Mercurial > libpst
diff timeconv.c @ 0:6b1b602514db libpst_0_5
Initial revision
author | carl |
---|---|
date | Fri, 09 Jul 2004 07:26:16 -0700 |
parents | |
children | 43e8802f08c5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/timeconv.c Fri Jul 09 07:26:16 2004 -0700 @@ -0,0 +1,126 @@ +/*********************************************************************** + * + * Borrowed from WINE sources!! (http://www.winehq.com) + * Converts a Win32 FILETIME structure to a UNIX time_t value + */ + +/*** WARNING **** + * This file is not to be incluided in a Visual C++ Project + * It will make the whole project fail to compile + * There are functions in libpst.c to handle the dates + * Do not use this one + */ + +#include <time.h> +#include "common.h" + +time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ); +char * fileTimeToAscii (const FILETIME *filetime); + +char * fileTimeToAscii (const FILETIME *filetime) { + time_t t1; + + t1 = fileTimeToUnixTime(filetime,0); + return ctime(&t1); +} + +struct tm * fileTimeToStructTM (const FILETIME *filetime) { + time_t t1; + t1 = fileTimeToUnixTime(filetime, 0); + return gmtime(&t1); +} + +/*********************************************************************** + * DOSFS_FileTimeToUnixTime + * + * Convert a FILETIME format to Unix time. + * If not NULL, 'remainder' contains the fractional part of the filetime, + * in the range of [0..9999999] (even if time_t is negative). + */ +time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ) +{ + /* Read the comment in the function DOSFS_UnixTimeToFileTime. */ +#if USE_LONG_LONG + + long long int t = filetime->dwHighDateTime; + t <<= 32; + t += (UINT32)filetime->dwLowDateTime; + t -= 116444736000000000LL; + if (t < 0) + { + if (remainder) *remainder = 9999999 - (-t - 1) % 10000000; + return -1 - ((-t - 1) / 10000000); + } + else + { + if (remainder) *remainder = t % 10000000; + return t / 10000000; + } + +#else /* ISO version */ + + UINT32 a0; /* 16 bit, low bits */ + UINT32 a1; /* 16 bit, medium bits */ + UINT32 a2; /* 32 bit, high bits */ + UINT32 r; /* remainder of division */ + unsigned int carry; /* carry bit for subtraction */ + int negative; /* whether a represents a negative value */ + + /* Copy the time values to a2/a1/a0 */ + a2 = (UINT32)filetime->dwHighDateTime; + a1 = ((UINT32)filetime->dwLowDateTime ) >> 16; + a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff; + + /* Subtract the time difference */ + if (a0 >= 32768 ) a0 -= 32768 , carry = 0; + else a0 += (1 << 16) - 32768 , carry = 1; + + if (a1 >= 54590 + carry) a1 -= 54590 + carry, carry = 0; + else a1 += (1 << 16) - 54590 - carry, carry = 1; + + a2 -= 27111902 + carry; + + /* If a is negative, replace a by (-1-a) */ + negative = (a2 >= ((UINT32)1) << 31); + if (negative) + { + /* Set a to -a - 1 (a is a2/a1/a0) */ + a0 = 0xffff - a0; + a1 = 0xffff - a1; + a2 = ~a2; + } + + /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r. + Split the divisor into 10000 * 1000 which are both less than 0xffff. */ + a1 += (a2 % 10000) << 16; + a2 /= 10000; + a0 += (a1 % 10000) << 16; + a1 /= 10000; + r = a0 % 10000; + a0 /= 10000; + + a1 += (a2 % 1000) << 16; + a2 /= 1000; + a0 += (a1 % 1000) << 16; + a1 /= 1000; + r += (a0 % 1000) * 10000; + a0 /= 1000; + + /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */ + if (negative) + { + /* Set a to -a - 1 (a is a2/a1/a0) */ + a0 = 0xffff - a0; + a1 = 0xffff - a1; + a2 = ~a2; + + r = 9999999 - r; + } + + if (remainder) *remainder = r; + + /* Do not replace this by << 32, it gives a compiler warning and it does + not work. */ + return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0; +#endif +}