aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows/TimeUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/Windows/TimeUtils.cpp')
-rw-r--r--CPP/Windows/TimeUtils.cpp220
1 files changed, 195 insertions, 25 deletions
diff --git a/CPP/Windows/TimeUtils.cpp b/CPP/Windows/TimeUtils.cpp
index 1f1335f..77d2c51 100644
--- a/CPP/Windows/TimeUtils.cpp
+++ b/CPP/Windows/TimeUtils.cpp
@@ -22,7 +22,7 @@ static const UInt64 kUnixTimeOffset =
22 (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear)); 22 (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
23static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond; 23static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
24 24
25bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw() 25bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &ft) throw()
26{ 26{
27 #if defined(_WIN32) && !defined(UNDER_CE) 27 #if defined(_WIN32) && !defined(UNDER_CE)
28 return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft)); 28 return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));
@@ -43,7 +43,7 @@ bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
43static const UInt32 kHighDosTime = 0xFF9FBF7D; 43static const UInt32 kHighDosTime = 0xFF9FBF7D;
44static const UInt32 kLowDosTime = 0x210000; 44static const UInt32 kLowDosTime = 0x210000;
45 45
46bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw() 46bool FileTime_To_DosTime(const FILETIME &ft, UInt32 &dosTime) throw()
47{ 47{
48 #if defined(_WIN32) && !defined(UNDER_CE) 48 #if defined(_WIN32) && !defined(UNDER_CE)
49 49
@@ -121,49 +121,86 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
121 return true; 121 return true;
122} 122}
123 123
124UInt64 UnixTimeToFileTime64(UInt32 unixTime) throw() 124
125bool UtcFileTime_To_LocalDosTime(const FILETIME &utc, UInt32 &dosTime) throw()
126{
127 FILETIME loc = { 0, 0 };
128 const UInt64 u1 = FILETIME_To_UInt64(utc);
129 const UInt64 kDelta = ((UInt64)1 << 41); // it's larger than quantums in 1 sec.
130 if (u1 >= kDelta)
131 {
132 if (!FileTimeToLocalFileTime(&utc, &loc))
133 loc = utc;
134 else
135 {
136 const UInt64 u2 = FILETIME_To_UInt64(loc);
137 const UInt64 delta = u1 < u2 ? (u2 - u1) : (u1 - u2);
138 if (delta > kDelta) // if FileTimeToLocalFileTime() overflow, we use UTC time
139 loc = utc;
140 }
141 }
142 return FileTime_To_DosTime(loc, dosTime);
143}
144
145UInt64 UnixTime_To_FileTime64(UInt32 unixTime) throw()
125{ 146{
126 return (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond; 147 return (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
127} 148}
128 149
129void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw() 150void UnixTime_To_FileTime(UInt32 unixTime, FILETIME &ft) throw()
130{ 151{
131 UInt64 v = UnixTimeToFileTime64(unixTime); 152 const UInt64 v = UnixTime_To_FileTime64(unixTime);
132 ft.dwLowDateTime = (DWORD)v; 153 ft.dwLowDateTime = (DWORD)v;
133 ft.dwHighDateTime = (DWORD)(v >> 32); 154 ft.dwHighDateTime = (DWORD)(v >> 32);
134} 155}
135 156
136UInt64 UnixTime64ToFileTime64(Int64 unixTime) throw() 157UInt64 UnixTime64_To_FileTime64(Int64 unixTime) throw()
137{ 158{
138 return (UInt64)((Int64)kUnixTimeOffset + unixTime) * kNumTimeQuantumsInSecond; 159 return (UInt64)((Int64)kUnixTimeOffset + unixTime) * kNumTimeQuantumsInSecond;
139} 160}
140 161
141bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw() 162
163bool UnixTime64_To_FileTime64(Int64 unixTime, UInt64 &fileTime) throw()
142{ 164{
143 if (unixTime > (Int64)(kNumSecondsInFileTime - kUnixTimeOffset)) 165 if (unixTime > (Int64)(kNumSecondsInFileTime - kUnixTimeOffset))
144 { 166 {
145 ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1; 167 fileTime = (UInt64)(Int64)-1;
146 return false; 168 return false;
147 } 169 }
148 Int64 v = (Int64)kUnixTimeOffset + unixTime; 170 if (unixTime < -(Int64)kUnixTimeOffset)
149 if (v < 0)
150 { 171 {
151 ft.dwLowDateTime = ft.dwHighDateTime = 0; 172 fileTime = 0;
152 return false; 173 return false;
153 } 174 }
154 UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond; 175 fileTime = UnixTime64_To_FileTime64(unixTime);
155 ft.dwLowDateTime = (DWORD)v2;
156 ft.dwHighDateTime = (DWORD)(v2 >> 32);
157 return true; 176 return true;
158} 177}
159 178
160Int64 FileTimeToUnixTime64(const FILETIME &ft) throw() 179
180bool UnixTime64_To_FileTime(Int64 unixTime, FILETIME &ft) throw()
161{ 181{
162 UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; 182 UInt64 v;
183 const bool res = UnixTime64_To_FileTime64(unixTime, v);
184 ft.dwLowDateTime = (DWORD)v;
185 ft.dwHighDateTime = (DWORD)(v >> 32);
186 return res;
187}
188
189
190Int64 FileTime_To_UnixTime64(const FILETIME &ft) throw()
191{
192 const UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
193 return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset;
194}
195
196Int64 FileTime_To_UnixTime64_and_Quantums(const FILETIME &ft, UInt32 &quantums) throw()
197{
198 const UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
199 quantums = (UInt32)(winTime % kNumTimeQuantumsInSecond);
163 return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset; 200 return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset;
164} 201}
165 202
166bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw() 203bool FileTime_To_UnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
167{ 204{
168 UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; 205 UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
169 winTime /= kNumTimeQuantumsInSecond; 206 winTime /= kNumTimeQuantumsInSecond;
@@ -173,9 +210,9 @@ bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
173 return false; 210 return false;
174 } 211 }
175 winTime -= kUnixTimeOffset; 212 winTime -= kUnixTimeOffset;
176 if (winTime > 0xFFFFFFFF) 213 if (winTime > (UInt32)0xFFFFFFFF)
177 { 214 {
178 unixTime = 0xFFFFFFFF; 215 unixTime = (UInt32)0xFFFFFFFF;
179 return false; 216 return false;
180 } 217 }
181 unixTime = (UInt32)winTime; 218 unixTime = (UInt32)winTime;
@@ -202,12 +239,13 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
202 return true; 239 return true;
203} 240}
204 241
205void GetCurUtcFileTime(FILETIME &ft) throw() 242
243void GetCurUtc_FiTime(CFiTime &ft) throw()
206{ 244{
245 #ifdef _WIN32
246
207 // Both variants provide same low resolution on WinXP: about 15 ms. 247 // Both variants provide same low resolution on WinXP: about 15 ms.
208 // But GetSystemTimeAsFileTime is much faster. 248 // But GetSystemTimeAsFileTime is much faster.
209 #ifdef _WIN32
210
211 #ifdef UNDER_CE 249 #ifdef UNDER_CE
212 SYSTEMTIME st; 250 SYSTEMTIME st;
213 GetSystemTime(&st); 251 GetSystemTime(&st);
@@ -216,8 +254,22 @@ void GetCurUtcFileTime(FILETIME &ft) throw()
216 GetSystemTimeAsFileTime(&ft); 254 GetSystemTimeAsFileTime(&ft);
217 #endif 255 #endif
218 256
219 #else 257 #else
220 258
259 FiTime_Clear(ft);
260 struct timeval now;
261 if (gettimeofday(&now, 0 ) == 0)
262 {
263 ft.tv_sec = now.tv_sec;
264 ft.tv_nsec = now.tv_usec * 1000;
265 }
266
267 #endif
268}
269
270#ifndef _WIN32
271void GetCurUtcFileTime(FILETIME &ft) throw()
272{
221 UInt64 v = 0; 273 UInt64 v = 0;
222 struct timeval now; 274 struct timeval now;
223 if (gettimeofday(&now, 0 ) == 0) 275 if (gettimeofday(&now, 0 ) == 0)
@@ -227,8 +279,126 @@ void GetCurUtcFileTime(FILETIME &ft) throw()
227 } 279 }
228 ft.dwLowDateTime = (DWORD)v; 280 ft.dwLowDateTime = (DWORD)v;
229 ft.dwHighDateTime = (DWORD)(v >> 32); 281 ft.dwHighDateTime = (DWORD)(v >> 32);
230
231 #endif
232} 282}
283#endif
284
233 285
234}} 286}}
287
288
289#ifdef _WIN32
290
291/*
292void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec)
293{
294 if (prec == k_PropVar_TimePrec_0
295 || prec == k_PropVar_TimePrec_HighPrec
296 || prec >= k_PropVar_TimePrec_100ns)
297 return;
298 UInt64 v = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
299
300 int numDigits = (int)prec - (int)k_PropVar_TimePrec_Base;
301 UInt32 d;
302 if (prec == k_PropVar_TimePrec_DOS)
303 {
304 // we round up as windows DosDateTimeToFileTime()
305 v += NWindows::NTime::kNumTimeQuantumsInSecond * 2 - 1;
306 d = NWindows::NTime::kNumTimeQuantumsInSecond * 2;
307 }
308 else
309 {
310 if (prec == k_PropVar_TimePrec_Unix)
311 numDigits = 0;
312 else if (numDigits < 0)
313 return;
314 d = 1;
315 for (unsigned k = numDigits; k < 7; k++)
316 d *= 10;
317 }
318 v /= d;
319 v *= d;
320 ft.dwLowDateTime = (DWORD)v;
321 ft.dwHighDateTime = (DWORD)(v >> 32);
322}
323*/
324
325#else
326
327/*
328void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec)
329{
330 if (prec >= k_PropVar_TimePrec_1ns
331 || prec == k_PropVar_TimePrec_HighPrec)
332 return;
333
334 int numDigits = (int)prec - (int)k_PropVar_TimePrec_Base;
335 UInt32 d;
336 if (prec == k_PropVar_TimePrec_Unix ||
337 prec == (int)k_PropVar_TimePrec_Base)
338 {
339 ft.tv_nsec = 0;
340 return;
341 }
342 if (prec == k_PropVar_TimePrec_DOS)
343 {
344 // we round up as windows DosDateTimeToFileTime()
345 const unsigned sec1 = (ft.tv_sec & 1);
346 if (ft.tv_nsec == 0 && sec1 == 0)
347 return;
348 ft.tv_nsec = 0;
349 ft.tv_sec += 2 - sec1;
350 return;
351 }
352 {
353 if (prec == k_PropVar_TimePrec_0
354 || numDigits < 0)
355 numDigits = 7;
356 d = 1;
357 for (unsigned k = numDigits; k < 9; k++)
358 d *= 10;
359 ft.tv_nsec /= d;
360 ft.tv_nsec *= d;
361 }
362}
363*/
364
365int Compare_FiTime(const CFiTime *a1, const CFiTime *a2)
366{
367 if (a1->tv_sec < a2->tv_sec) return -1;
368 if (a1->tv_sec > a2->tv_sec) return 1;
369 if (a1->tv_nsec < a2->tv_nsec) return -1;
370 if (a1->tv_nsec > a2->tv_nsec) return 1;
371 return 0;
372}
373
374bool FILETIME_To_timespec(const FILETIME &ft, timespec &ts)
375{
376 UInt32 quantums;
377 const Int64 sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, quantums);
378 // time_t is long
379 const time_t sec2 = (time_t)sec;
380 if (sec2 == sec)
381 {
382 ts.tv_sec = sec2;
383 ts.tv_nsec = (long)(quantums * 100);
384 return true;
385 }
386 return false;
387}
388
389void FiTime_To_FILETIME_ns100(const CFiTime &ts, FILETIME &ft, unsigned &ns100)
390{
391 const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100);
392 ns100 = (unsigned)((UInt64)ts.tv_nsec % 100);
393 ft.dwLowDateTime = (DWORD)v;
394 ft.dwHighDateTime = (DWORD)(v >> 32);
395}
396
397void FiTime_To_FILETIME(const CFiTime &ts, FILETIME &ft)
398{
399 const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100);
400 ft.dwLowDateTime = (DWORD)v;
401 ft.dwHighDateTime = (DWORD)(v >> 32);
402}
403
404#endif