Mercurial > libpst
comparison src/timeconv.c @ 182:b65e8d0a088a
more cleanup on external names in the shared object file
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Mon, 13 Apr 2009 11:39:33 -0700 |
parents | 6954d315aaa8 |
children | 7c60d6d1c681 |
comparison
equal
deleted
inserted
replaced
181:3b04745ff76d | 182:b65e8d0a088a |
---|---|
1 /*********************************************************************** | |
2 * | |
3 * Borrowed from WINE sources!! (http://www.winehq.com) | |
4 * Converts a Win32 FILETIME structure to a UNIX time_t value | |
5 */ | |
6 | |
7 /*** WARNING **** | |
8 * This file is not to be included in a Visual C++ Project | |
9 * It will make the whole project fail to compile | |
10 * There are functions in libpst.c to handle the dates | |
11 * Do not use this one | |
12 */ | |
13 | |
14 #ifndef _WIN32 | |
15 | |
16 #include "define.h" | 1 #include "define.h" |
17 | 2 |
18 char * pst_fileTimeToAscii (const FILETIME *filetime) { | |
19 time_t t1; | |
20 | 3 |
21 t1 = pst_fileTimeToUnixTime(filetime, NULL); | 4 |
22 return ctime(&t1); | 5 char * pst_fileTimeToAscii(const FILETIME* filetime) { |
6 time_t t; | |
7 t = pst_fileTimeToUnixTime(filetime); | |
8 return ctime(&t); | |
23 } | 9 } |
10 | |
24 | 11 |
25 struct tm * pst_fileTimeToStructTM (const FILETIME *filetime) { | 12 struct tm * pst_fileTimeToStructTM (const FILETIME *filetime) { |
26 time_t t1; | 13 time_t t1; |
27 t1 = pst_fileTimeToUnixTime(filetime, NULL); | 14 t1 = pst_fileTimeToUnixTime(filetime); |
28 return gmtime(&t1); | 15 return gmtime(&t1); |
29 } | 16 } |
30 | 17 |
31 /*********************************************************************** | 18 |
32 * DOSFS_FileTimeToUnixTime | 19 time_t pst_fileTimeToUnixTime(const FILETIME *filetime) |
33 * | |
34 * Convert a FILETIME format to Unix time. | |
35 * If not NULL, 'remainder' contains the fractional part of the filetime, | |
36 * in the range of [0..9999999] (even if time_t is negative). | |
37 */ | |
38 time_t pst_fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ) | |
39 { | 20 { |
40 /* Read the comment in the function DOSFS_UnixTimeToFileTime. */ | 21 int64_t t = filetime->dwHighDateTime; |
41 #if USE_LONG_LONG | |
42 | |
43 long long int t = filetime->dwHighDateTime; | |
44 t <<= 32; | 22 t <<= 32; |
45 t += (UINT32)filetime->dwLowDateTime; | 23 t += filetime->dwLowDateTime; |
46 t -= 116444736000000000LL; | 24 t -= 116444736000000000LL; |
47 if (t < 0) | 25 if (t < 0) { |
48 { | 26 return -1 - ((-t - 1) / 10000000); |
49 if (remainder) *remainder = 9999999 - (-t - 1) % 10000000; | |
50 return -1 - ((-t - 1) / 10000000); | |
51 } | 27 } |
52 else | 28 else { |
53 { | 29 return t / 10000000; |
54 if (remainder) *remainder = t % 10000000; | |
55 return t / 10000000; | |
56 } | 30 } |
57 | |
58 #else /* ISO version */ | |
59 | |
60 UINT32 a0; /* 16 bit, low bits */ | |
61 UINT32 a1; /* 16 bit, medium bits */ | |
62 UINT32 a2; /* 32 bit, high bits */ | |
63 UINT32 r; /* remainder of division */ | |
64 unsigned int carry; /* carry bit for subtraction */ | |
65 int negative; /* whether a represents a negative value */ | |
66 | |
67 /* Copy the time values to a2/a1/a0 */ | |
68 a2 = (UINT32)filetime->dwHighDateTime; | |
69 a1 = ((UINT32)filetime->dwLowDateTime ) >> 16; | |
70 a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff; | |
71 | |
72 /* Subtract the time difference */ | |
73 if (a0 >= 32768 ) a0 -= 32768 , carry = 0; | |
74 else a0 += (1 << 16) - 32768 , carry = 1; | |
75 | |
76 if (a1 >= 54590 + carry) a1 -= 54590 + carry, carry = 0; | |
77 else a1 += (1 << 16) - 54590 - carry, carry = 1; | |
78 | |
79 a2 -= 27111902 + carry; | |
80 | |
81 /* If a is negative, replace a by (-1-a) */ | |
82 negative = (a2 >= ((UINT32)1) << 31); | |
83 if (negative) | |
84 { | |
85 /* Set a to -a - 1 (a is a2/a1/a0) */ | |
86 a0 = 0xffff - a0; | |
87 a1 = 0xffff - a1; | |
88 a2 = ~a2; | |
89 } | |
90 | |
91 /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r. | |
92 Split the divisor into 10000 * 1000 which are both less than 0xffff. */ | |
93 a1 += (a2 % 10000) << 16; | |
94 a2 /= 10000; | |
95 a0 += (a1 % 10000) << 16; | |
96 a1 /= 10000; | |
97 r = a0 % 10000; | |
98 a0 /= 10000; | |
99 | |
100 a1 += (a2 % 1000) << 16; | |
101 a2 /= 1000; | |
102 a0 += (a1 % 1000) << 16; | |
103 a1 /= 1000; | |
104 r += (a0 % 1000) * 10000; | |
105 a0 /= 1000; | |
106 | |
107 /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */ | |
108 if (negative) | |
109 { | |
110 /* Set a to -a - 1 (a is a2/a1/a0) */ | |
111 a0 = 0xffff - a0; | |
112 a1 = 0xffff - a1; | |
113 a2 = ~a2; | |
114 | |
115 r = 9999999 - r; | |
116 } | |
117 | |
118 if (remainder) *remainder = r; | |
119 | |
120 /* Do not replace this by << 32, it gives a compiler warning and it does | |
121 not work. */ | |
122 return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0; | |
123 #endif | |
124 } | 31 } |
125 | 32 |
126 #endif /* !_WIN32 */ |