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 #ifndef _WIN32
00015 
00016 #include "define.h"
00017 
00018 char * fileTimeToAscii (const FILETIME *filetime) {
00019   time_t t1;
00020 
00021   t1 = fileTimeToUnixTime(filetime, NULL);
00022   return ctime(&t1);
00023 }
00024 
00025 struct tm * fileTimeToStructTM (const FILETIME *filetime) {
00026   time_t t1;
00027   t1 = fileTimeToUnixTime(filetime, NULL);
00028   return gmtime(&t1);
00029 }
00030 
00031 /***********************************************************************
00032  *           DOSFS_FileTimeToUnixTime
00033  *
00034  * Convert a FILETIME format to Unix time.
00035  * If not NULL, 'remainder' contains the fractional part of the filetime,
00036  * in the range of [0..9999999] (even if time_t is negative).
00037  */
00038 time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder )
00039 {
00040     /* Read the comment in the function DOSFS_UnixTimeToFileTime. */
00041 #if USE_LONG_LONG
00042 
00043     long long int t = filetime->dwHighDateTime;
00044     t <<= 32;
00045     t += (UINT32)filetime->dwLowDateTime;
00046     t -= 116444736000000000LL;
00047     if (t < 0)
00048     {
00049     if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
00050     return -1 - ((-t - 1) / 10000000);
00051     }
00052     else
00053     {
00054     if (remainder) *remainder = t % 10000000;
00055     return t / 10000000;
00056     }
00057 
00058 #else  /* ISO version */
00059 
00060     UINT32 a0;          /* 16 bit, low    bits */
00061     UINT32 a1;          /* 16 bit, medium bits */
00062     UINT32 a2;          /* 32 bit, high   bits */
00063     UINT32 r;           /* remainder of division */
00064     unsigned int carry;     /* carry bit for subtraction */
00065     int negative;       /* whether a represents a negative value */
00066 
00067     /* Copy the time values to a2/a1/a0 */
00068     a2 =  (UINT32)filetime->dwHighDateTime;
00069     a1 = ((UINT32)filetime->dwLowDateTime ) >> 16;
00070     a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff;
00071 
00072     /* Subtract the time difference */
00073     if (a0 >= 32768           ) a0 -=             32768        , carry = 0;
00074     else                        a0 += (1 << 16) - 32768        , carry = 1;
00075 
00076     if (a1 >= 54590    + carry) a1 -=             54590 + carry, carry = 0;
00077     else                        a1 += (1 << 16) - 54590 - carry, carry = 1;
00078 
00079     a2 -= 27111902 + carry;
00080 
00081     /* If a is negative, replace a by (-1-a) */
00082     negative = (a2 >= ((UINT32)1) << 31);
00083     if (negative)
00084     {
00085     /* Set a to -a - 1 (a is a2/a1/a0) */
00086     a0 = 0xffff - a0;
00087     a1 = 0xffff - a1;
00088     a2 = ~a2;
00089     }
00090 
00091     /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r.
00092        Split the divisor into 10000 * 1000 which are both less than 0xffff. */
00093     a1 += (a2 % 10000) << 16;
00094     a2 /=       10000;
00095     a0 += (a1 % 10000) << 16;
00096     a1 /=       10000;
00097     r   =  a0 % 10000;
00098     a0 /=       10000;
00099 
00100     a1 += (a2 % 1000) << 16;
00101     a2 /=       1000;
00102     a0 += (a1 % 1000) << 16;
00103     a1 /=       1000;
00104     r  += (a0 % 1000) * 10000;
00105     a0 /=       1000;
00106 
00107     /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
00108     if (negative)
00109     {
00110     /* Set a to -a - 1 (a is a2/a1/a0) */
00111     a0 = 0xffff - a0;
00112     a1 = 0xffff - a1;
00113     a2 = ~a2;
00114 
00115         r  = 9999999 - r;
00116     }
00117 
00118     if (remainder) *remainder = r;
00119 
00120     /* Do not replace this by << 32, it gives a compiler warning and it does
00121        not work. */
00122     return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0;
00123 #endif
00124 }
00125 
00126 #endif  /* !_WIN32 */

Generated on Thu Mar 19 16:39:26 2009 for 'LibPst' by  doxygen 1.3.9.1