comparison src/timeconv.c @ 16:c508ee15dfca

switch to automake/autoconf
author carl
date Sun, 19 Feb 2006 18:47:46 -0800
parents
children b2a7f2e0926a
comparison
equal deleted inserted replaced
15:ac98f448b6ab 16:c508ee15dfca
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 incluided 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 #include <time.h>
15 #include "common.h"
16 #include "timeconv.h"
17
18 time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder );
19 char * fileTimeToAscii (const FILETIME *filetime);
20
21 char * fileTimeToAscii (const FILETIME *filetime) {
22 time_t t1;
23
24 t1 = fileTimeToUnixTime(filetime,0);
25 return ctime(&t1);
26 }
27
28 struct tm * fileTimeToStructTM (const FILETIME *filetime) {
29 time_t t1;
30 t1 = fileTimeToUnixTime(filetime, 0);
31 return gmtime(&t1);
32 }
33
34 /***********************************************************************
35 * DOSFS_FileTimeToUnixTime
36 *
37 * Convert a FILETIME format to Unix time.
38 * If not NULL, 'remainder' contains the fractional part of the filetime,
39 * in the range of [0..9999999] (even if time_t is negative).
40 */
41 time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder )
42 {
43 /* Read the comment in the function DOSFS_UnixTimeToFileTime. */
44 #if USE_LONG_LONG
45
46 long long int t = filetime->dwHighDateTime;
47 t <<= 32;
48 t += (UINT32)filetime->dwLowDateTime;
49 t -= 116444736000000000LL;
50 if (t < 0)
51 {
52 if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
53 return -1 - ((-t - 1) / 10000000);
54 }
55 else
56 {
57 if (remainder) *remainder = t % 10000000;
58 return t / 10000000;
59 }
60
61 #else /* ISO version */
62
63 UINT32 a0; /* 16 bit, low bits */
64 UINT32 a1; /* 16 bit, medium bits */
65 UINT32 a2; /* 32 bit, high bits */
66 UINT32 r; /* remainder of division */
67 unsigned int carry; /* carry bit for subtraction */
68 int negative; /* whether a represents a negative value */
69
70 /* Copy the time values to a2/a1/a0 */
71 a2 = (UINT32)filetime->dwHighDateTime;
72 a1 = ((UINT32)filetime->dwLowDateTime ) >> 16;
73 a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff;
74
75 /* Subtract the time difference */
76 if (a0 >= 32768 ) a0 -= 32768 , carry = 0;
77 else a0 += (1 << 16) - 32768 , carry = 1;
78
79 if (a1 >= 54590 + carry) a1 -= 54590 + carry, carry = 0;
80 else a1 += (1 << 16) - 54590 - carry, carry = 1;
81
82 a2 -= 27111902 + carry;
83
84 /* If a is negative, replace a by (-1-a) */
85 negative = (a2 >= ((UINT32)1) << 31);
86 if (negative)
87 {
88 /* Set a to -a - 1 (a is a2/a1/a0) */
89 a0 = 0xffff - a0;
90 a1 = 0xffff - a1;
91 a2 = ~a2;
92 }
93
94 /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r.
95 Split the divisor into 10000 * 1000 which are both less than 0xffff. */
96 a1 += (a2 % 10000) << 16;
97 a2 /= 10000;
98 a0 += (a1 % 10000) << 16;
99 a1 /= 10000;
100 r = a0 % 10000;
101 a0 /= 10000;
102
103 a1 += (a2 % 1000) << 16;
104 a2 /= 1000;
105 a0 += (a1 % 1000) << 16;
106 a1 /= 1000;
107 r += (a0 % 1000) * 10000;
108 a0 /= 1000;
109
110 /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
111 if (negative)
112 {
113 /* Set a to -a - 1 (a is a2/a1/a0) */
114 a0 = 0xffff - a0;
115 a1 = 0xffff - a1;
116 a2 = ~a2;
117
118 r = 9999999 - r;
119 }
120
121 if (remainder) *remainder = r;
122
123 /* Do not replace this by << 32, it gives a compiler warning and it does
124 not work. */
125 return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0;
126 #endif
127 }