Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

timeconv.c

Go to the documentation of this file.
00001 /***********************************************************************
00002  *
00003  * Borrowed from WINE sources!! (http://www.winehq.com)
00004  * Converts a Win32 FILETIME structure to a UNIX time_t value
00005  */
00006 
00007 /*** WARNING ****
00008  * This file is not to be included in a Visual C++ Project
00009  * It will make the whole project fail to compile
00010  * There are functions in libpst.c to handle the dates
00011  * Do not use this one
00012  */
00013 
00014 #include <time.h>
00015 #include "timeconv.h"
00016 
00017 char * fileTimeToAscii (const FILETIME *filetime) {
00018   time_t t1;
00019 
00020   t1 = fileTimeToUnixTime(filetime, NULL);
00021   return ctime(&t1);
00022 }
00023 
00024 struct tm * fileTimeToStructTM (const FILETIME *filetime) {
00025   time_t t1;
00026   t1 = fileTimeToUnixTime(filetime, NULL);
00027   return gmtime(&t1);
00028 }
00029 
00030 /***********************************************************************
00031  *           DOSFS_FileTimeToUnixTime
00032  *
00033  * Convert a FILETIME format to Unix time.
00034  * If not NULL, 'remainder' contains the fractional part of the filetime,
00035  * in the range of [0..9999999] (even if time_t is negative).
00036  */
00037 time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder )
00038 {
00039     /* Read the comment in the function DOSFS_UnixTimeToFileTime. */
00040 #if USE_LONG_LONG
00041 
00042     long long int t = filetime->dwHighDateTime;
00043     t <<= 32;
00044     t += (UINT32)filetime->dwLowDateTime;
00045     t -= 116444736000000000LL;
00046     if (t < 0)
00047     {
00048     if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
00049     return -1 - ((-t - 1) / 10000000);
00050     }
00051     else
00052     {
00053     if (remainder) *remainder = t % 10000000;
00054     return t / 10000000;
00055     }
00056 
00057 #else  /* ISO version */
00058 
00059     UINT32 a0;          /* 16 bit, low    bits */
00060     UINT32 a1;          /* 16 bit, medium bits */
00061     UINT32 a2;          /* 32 bit, high   bits */
00062     UINT32 r;           /* remainder of division */
00063     unsigned int carry;     /* carry bit for subtraction */
00064     int negative;       /* whether a represents a negative value */
00065 
00066     /* Copy the time values to a2/a1/a0 */
00067     a2 =  (UINT32)filetime->dwHighDateTime;
00068     a1 = ((UINT32)filetime->dwLowDateTime ) >> 16;
00069     a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff;
00070 
00071     /* Subtract the time difference */
00072     if (a0 >= 32768           ) a0 -=             32768        , carry = 0;
00073     else                        a0 += (1 << 16) - 32768        , carry = 1;
00074 
00075     if (a1 >= 54590    + carry) a1 -=             54590 + carry, carry = 0;
00076     else                        a1 += (1 << 16) - 54590 - carry, carry = 1;
00077 
00078     a2 -= 27111902 + carry;
00079 
00080     /* If a is negative, replace a by (-1-a) */
00081     negative = (a2 >= ((UINT32)1) << 31);
00082     if (negative)
00083     {
00084     /* Set a to -a - 1 (a is a2/a1/a0) */
00085     a0 = 0xffff - a0;
00086     a1 = 0xffff - a1;
00087     a2 = ~a2;
00088     }
00089 
00090     /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r.
00091        Split the divisor into 10000 * 1000 which are both less than 0xffff. */
00092     a1 += (a2 % 10000) << 16;
00093     a2 /=       10000;
00094     a0 += (a1 % 10000) << 16;
00095     a1 /=       10000;
00096     r   =  a0 % 10000;
00097     a0 /=       10000;
00098 
00099     a1 += (a2 % 1000) << 16;
00100     a2 /=       1000;
00101     a0 += (a1 % 1000) << 16;
00102     a1 /=       1000;
00103     r  += (a0 % 1000) * 10000;
00104     a0 /=       1000;
00105 
00106     /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
00107     if (negative)
00108     {
00109     /* Set a to -a - 1 (a is a2/a1/a0) */
00110     a0 = 0xffff - a0;
00111     a1 = 0xffff - a1;
00112     a2 = ~a2;
00113 
00114         r  = 9999999 - r;
00115     }
00116 
00117     if (remainder) *remainder = r;
00118 
00119     /* Do not replace this by << 32, it gives a compiler warning and it does
00120        not work. */
00121     return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0;
00122 #endif
00123 }

Generated on Thu Dec 11 11:58:49 2008 for 'LibPst' by  doxygen 1.3.9.1