Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(252)

Side by Side Diff: base/time.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/time.h ('k') | base/time_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2004-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // Time functions
17
18 #include "omaha/base/time.h"
19 #include "omaha/base/commontypes.h"
20 #include "omaha/base/debug.h"
21 #include "omaha/base/error.h"
22 #include "omaha/base/logging.h"
23 #include "omaha/base/string.h"
24 #include "omaha/base/utils.h"
25
26 namespace omaha {
27
28 // Date Constants
29
30 #define kNumOfDays 7
31 #define kNumOfMonth 12
32
33 static const TCHAR kRFC822_DateDelimiters[] = _T(" ,:");
34 static const TCHAR kRFC822_TimeDelimiter[] = _T(":");
35 SELECTANY const TCHAR* kRFC822_Day[kNumOfDays] = {
36 _T("Mon"),
37 _T("Tue"),
38 _T("Wed"),
39 _T("Thu"),
40 _T("Fri"),
41 _T("Sat"),
42 _T("Sun") };
43
44 SELECTANY const TCHAR* kRFC822_Month[kNumOfMonth] = {
45 _T("Jan"),
46 _T("Feb"),
47 _T("Mar"),
48 _T("Apr"),
49 _T("May"),
50 _T("Jun"),
51 _T("Jul"),
52 _T("Aug"),
53 _T("Sep"),
54 _T("Oct"),
55 _T("Nov"),
56 _T("Dec") };
57
58 struct TimeZoneInfo {
59 const TCHAR* zone_name;
60 int hour_dif;
61 };
62
63 SELECTANY TimeZoneInfo kRFC822_TimeZone[] = {
64 { _T("UT"), 0 },
65 { _T("GMT"), 0 },
66 { _T("EST"), -5 },
67 { _T("EDT"), -4 },
68 { _T("CST"), -6 },
69 { _T("CDT"), -5 },
70 { _T("MST"), -7 },
71 { _T("MDT"), -6 },
72 { _T("PST"), -8 },
73 { _T("PDT"), -7 },
74 { _T("A"), -1 }, // Military time zones
75 { _T("B"), -2 },
76 { _T("C"), -3 },
77 { _T("D"), -4 },
78 { _T("E"), -5 },
79 { _T("F"), -6 },
80 { _T("G"), -7 },
81 { _T("H"), -8 },
82 { _T("I"), -9 },
83 { _T("K"), -10 },
84 { _T("L"), -11 },
85 { _T("M"), -12 },
86 { _T("N"), 1 },
87 { _T("O"), 2 },
88 { _T("P"), 3 },
89 { _T("Q"), 4 },
90 { _T("R"), 5 },
91 { _T("S"), 6 },
92 { _T("T"), 7 },
93 { _T("U"), 8 },
94 { _T("V"), 9 },
95 { _T("W"), 10 },
96 { _T("X"), 11 },
97 { _T("Y"), 12 },
98 { _T("Z"), 0 },
99 };
100
101 SELECTANY const TCHAR *days[] =
102 { L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat" };
103
104 SELECTANY const TCHAR *months[] = {
105 L"Jan",
106 L"Feb",
107 L"Mar",
108 L"Apr",
109 L"May",
110 L"Jun",
111 L"Jul",
112 L"Aug",
113 L"Sep",
114 L"Oct",
115 L"Nov",
116 L"Dec"
117 };
118
119 // NOTE: so long as the output is used internally only, no localization is
120 // needed here.
121 CString ConvertTimeToGMTString(const FILETIME *ft) {
122 ASSERT(ft, (L""));
123
124 CString s;
125 SYSTEMTIME st;
126 if (!FileTimeToSystemTime(ft, &st)) {
127 return L"";
128 }
129
130 // same as FormatGmt(_T("%a, %d %b %Y %H:%M:%S GMT"));
131 s.Format(NOTRANSL(L"%s, %02d %s %d %02d:%02d:%02d GMT"), days[st.wDayOfWeek],
132 st.wDay, months[st.wMonth-1], st.wYear, st.wHour, st.wMinute, st.wSecond);
133 return s;
134 }
135
136 time64 ConvertTime16ToTime64(uint16 time16) {
137 return time16 * kTimeGranularity + kStart100NsTime;
138 }
139
140 uint16 ConvertTime64ToTime16(time64 time) {
141 ASSERT1(time >= kStart100NsTime);
142
143 time64 t64 = (time - kStart100NsTime) / kTimeGranularity;
144 ASSERT1(t64 <= kTime16Max);
145
146 return static_cast<uint16>(t64);
147 }
148
149 time64 TimeTToTime64(const time_t& old_value) {
150 FILETIME file_time;
151 TimeTToFileTime(old_value, &file_time);
152 return FileTimeToTime64(file_time);
153 }
154
155 #ifdef _DEBUG
156 void ComputeStartTime() {
157 SYSTEMTIME start_system_time = kStartSystemTime;
158 time64 start_100ns_time = SystemTimeToTime64(&start_system_time);
159 UTIL_LOG(L1, (_T("posting list starting time = %s\n"),
160 String_Int64ToString(start_100ns_time, 10)));
161 }
162 #endif
163
164 // Time management
165
166 // Allow the unittest to override.
167 static time64 time_override = 0;
168
169 // #ifdef UNITTEST
170 void SetTimeOverride(const time64 & time_new) {
171 time_override = time_new;
172 }
173
174 // #endif
175
176 time64 GetCurrent100NSTime() {
177 if (time_override != 0)
178 return time_override;
179
180 // In order gte the 100ns time we shouldn't use SystemTime
181 // as it's granularity is 1 ms. Below is the correct implementation.
182 // On the other hand the system clock granularity is 15 ms, so we
183 // are not gaining much by having the timestamp in nano-sec
184 // If we decide to go with ms, divide "time64 time" by 10000
185 // SYSTEMTIME sys_time;
186 // GetLocalTime(&sys_time);
187 // return SystemTimeToTime64(&sys_time);
188
189 // get the current time in 100-nanoseconds intervals
190 FILETIME file_time;
191 ::GetSystemTimeAsFileTime(&file_time);
192
193 time64 time = FileTimeToTime64(file_time);
194 return time;
195 }
196
197 time64 GetCurrentMsTime() {
198 return GetCurrent100NSTime() / kMillisecsTo100ns;
199 }
200
201 time64 SystemTimeToTime64(const SYSTEMTIME* sys_time) {
202 ASSERT1(sys_time);
203
204 FILETIME file_time;
205 SetZero(file_time);
206
207 if (!::SystemTimeToFileTime(sys_time, &file_time)) {
208 UTIL_LOG(LE,
209 (_T("[SystemTimeToTime64 - failed to SystemTimeToFileTime][0x%x]"),
210 HRESULTFromLastError()));
211 return 0;
212 }
213
214 return FileTimeToTime64(file_time);
215 }
216
217 // returns a value compatible with EXE/DLL timestamps
218 // and the C time() function
219 // NOTE: behavior is independent of wMilliseconds value
220 int32 SystemTimeToInt32(const SYSTEMTIME *sys_time) {
221 ASSERT(sys_time, (L""));
222
223 time64 t64 = SystemTimeToTime64(sys_time);
224 int32 t32 = 0;
225
226 if (t64 != 0) {
227 t32 = Time64ToInt32(t64);
228 }
229 return t32;
230 }
231
232 int32 Time64ToInt32(const time64 & time) {
233 // convert to 32-bit format
234 // time() (32-bit) measures seconds since 1970/01/01 00:00:00 (UTC)
235 // FILETIME (64-bit) measures 100-ns intervals since 1601/01/01 00:00:00 (UTC)
236
237 // seconds between 1601 and 1970
238 time64 t32 = (time / kSecsTo100ns) -
239 ((time64(60*60*24) * time64(365*369 + 89)));
240 ASSERT(t32 == (t32 & 0x7FFFFFFF), (L"")); // make sure it fits
241
242 // cast at the end (avoids overflow/underflow when computing 32-bit value)
243 return static_cast<int32>(t32);
244 }
245
246 time64 Int32ToTime64(const int32 & time) {
247 // convert to 64-bit format
248 // time() (32-bit) measures seconds since 1970/01/01 00:00:00 (UTC)
249 // FILETIME (64-bit) measures 100-ns intervals since 1601/01/01 00:00:00 (UTC)
250
251 // seconds between 1601 and 1970
252 time64 t64 = (static_cast<time64>(time) +
253 (time64(60*60*24) * time64(365*369 + 89))) * kSecsTo100ns;
254 return t64;
255 }
256
257 // TODO(omaha): The next 2 functions can fail if FileTimeToLocalFileTime or
258 // FileTimeToSystemTime fails.
259 // Consider having it return a HRESULT. Right now if FileTimeToSystemTime fails,
260 // it returns an undefined value.
261
262 // Convert a uint to a genuine systemtime
263 SYSTEMTIME Time64ToSystemTime(const time64& time) {
264 FILETIME file_time;
265 SetZero(file_time);
266 Time64ToFileTime(time, &file_time);
267
268 SYSTEMTIME sys_time;
269 SetZero(sys_time);
270 if (!FileTimeToSystemTime(&file_time, &sys_time)) {
271 UTIL_LOG(LE, (_T("[Time64ToSystemTime]")
272 _T("[failed to FileTimeToSystemTime][0x%x]"),
273 HRESULTFromLastError()));
274 }
275
276 return sys_time;
277 }
278
279
280 // Convert a uint to a genuine localtime
281 // Should ONLY be used for display, since internally we use only UTC
282 SYSTEMTIME Time64ToLocalTime(const time64& time) {
283 FILETIME file_time;
284 SetZero(file_time);
285 Time64ToFileTime(time, &file_time);
286
287 FILETIME local_file_time;
288 SetZero(local_file_time);
289 if (!FileTimeToLocalFileTime(&file_time, &local_file_time)) {
290 UTIL_LOG(LE, (_T("[Time64ToLocalTime]")
291 _T("[failed to FileTimeToLocalFileTime][0x%x]"),
292 HRESULTFromLastError()));
293 }
294
295 SYSTEMTIME local_time;
296 SetZero(local_time);
297 if (!FileTimeToSystemTime(&local_file_time, &local_time)) {
298 UTIL_LOG(LE, (_T("[Time64ToLocalTime]")
299 _T("[failed to FileTimeToSystemTime][0x%x]"),
300 HRESULTFromLastError()));
301 }
302
303 return local_time;
304 }
305
306 time64 FileTimeToTime64(const FILETIME & file_time) {
307 return static_cast<time64>(
308 file_time.dwHighDateTime) << 32 | file_time.dwLowDateTime;
309 }
310
311 void Time64ToFileTime(const time64 & time, FILETIME *ft) {
312 ASSERT(ft, (L""));
313
314 ft->dwHighDateTime = static_cast<DWORD>(time >> 32);
315 ft->dwLowDateTime = static_cast<DWORD>(time & 0xffffffff);
316 }
317
318 // Convert from FILETIME to time_t
319 time_t FileTimeToTimeT(const FILETIME& file_time) {
320 return static_cast<time_t>(
321 (FileTimeToTime64(file_time) - kTimeTConvValue) / kSecsTo100ns);
322 }
323
324 // Convert from time_t to FILETIME
325 void TimeTToFileTime(const time_t& time, FILETIME* file_time) {
326 ASSERT1(file_time);
327
328 LONGLONG ll = Int32x32To64(time, kSecsTo100ns) + kTimeTConvValue;
329 file_time->dwLowDateTime = static_cast<DWORD>(ll);
330 file_time->dwHighDateTime = static_cast<DWORD>(ll >> 32);
331 }
332
333 // Parses RFC 822 Date/Time format
334 // 5. DATE AND TIME SPECIFICATION
335 // 5.1. SYNTAX
336 //
337 // date-time = [ day "," ] date time ; dd mm yy
338 // ; hh:mm:ss zzz
339 // day = "Mon" / "Tue" / "Wed" / "Thu"
340 // / "Fri" / "Sat" / "Sun"
341 //
342 // date = 1*2DIGIT month 2DIGIT ; day month year
343 // ; e.g. 20 Jun 82
344 //
345 // month = "Jan" / "Feb" / "Mar" / "Apr"
346 // / "May" / "Jun" / "Jul" / "Aug"
347 // / "Sep" / "Oct" / "Nov" / "Dec"
348 //
349 // time = hour zone ; ANSI and Military
350 //
351 // hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT]
352 // ; 00:00:00 - 23:59:59
353 //
354 // zone = "UT" / "GMT" ; Universal Time
355 // ; North American : UT
356 // / "EST" / "EDT" ; Eastern: - 5/ - 4
357 // / "CST" / "CDT" ; Central: - 6/ - 5
358 // / "MST" / "MDT" ; Mountain: - 7/ - 6
359 // / "PST" / "PDT" ; Pacific: - 8/ - 7
360 // / 1ALPHA ; Military: Z = UT;
361 // ; A:-1; (J not used)
362 // ; M:-12; N:+1; Y:+12
363 // / ( ("+" / "-") 4DIGIT ) ; Local differential
364 // ; hours+min. (HHMM)
365 // return local time if ret_local_time == true,
366 // return time is GMT / UTC time otherwise
367 bool RFC822DateToSystemTime(const TCHAR* str_RFC822_date,
368 SYSTEMTIME* psys_time,
369 bool ret_local_time) {
370 ASSERT(str_RFC822_date != NULL, (L""));
371 ASSERT(psys_time != NULL, (L""));
372
373 CString str_date = str_RFC822_date;
374 CString str_token;
375 int cur_pos = 0;
376
377 str_token= str_date.Tokenize(kRFC822_DateDelimiters, cur_pos);
378 if (str_token == "")
379 return false;
380
381 int i = 0;
382 for (i = 0; i < kNumOfDays; i++) {
383 if (str_token == kRFC822_Day[i]) {
384 str_token = str_date.Tokenize(kRFC822_DateDelimiters, cur_pos);
385 if (str_token == "")
386 return false;
387 break;
388 }
389 }
390
391 int day = String_StringToInt(str_token);
392 if (day < 0 || day > 31)
393 return false;
394
395 str_token = str_date.Tokenize(kRFC822_DateDelimiters, cur_pos);
396 if (str_token == "")
397 return false;
398
399 int month = -1;
400 for (i = 0; i < kNumOfMonth; i++) {
401 if (str_token == kRFC822_Month[i]) {
402 month = i+1; // month is 1 based number
403 break;
404 }
405 }
406 if (month == -1) // month not found
407 return false;
408
409 str_token = str_date.Tokenize(kRFC822_DateDelimiters, cur_pos);
410 if (str_token == "")
411 return false;
412
413 int year = String_StringToInt(str_token);
414 if (year < 100) // two digit year format, convert to 1950 - 2050 range
415 if (year < 50)
416 year += 2000;
417 else
418 year += 1900;
419
420 str_token = str_date.Tokenize(kRFC822_DateDelimiters, cur_pos);
421 if (str_token == "")
422 return false;
423
424 int hour = String_StringToInt(str_token);
425 if (hour < 0 || hour > 23)
426 return false;
427
428 str_token = str_date.Tokenize(kRFC822_DateDelimiters, cur_pos);
429 if (str_token == "")
430 return false;
431
432 int minute = String_StringToInt(str_token);
433 if (minute < 0 || minute > 59)
434 return false;
435
436 str_token = str_date.Tokenize(kRFC822_DateDelimiters, cur_pos);
437 if (str_token == "")
438 return false;
439
440 int second = 0;
441 // distingushed between XX:XX and XX:XX:XX time formats
442 if (str_token.GetLength() == 2 &&
443 String_IsDigit(str_token[0]) &&
444 String_IsDigit(str_token[1])) {
445 second = String_StringToInt(str_token);
446 if (second < 0 || second > 59)
447 return false;
448
449 str_token = str_date.Tokenize(kRFC822_DateDelimiters, cur_pos);
450 if (str_token == "")
451 return false;
452 }
453
454 int bias = 0;
455 if (str_token[0] == '+' ||
456 str_token[0] == '-' ||
457 String_IsDigit(str_token[0])) { // numeric format
458 int zone = String_StringToInt(str_token);
459
460 // zone is in HHMM format, need to convert to the number of minutes
461 bias = (zone / 100) * 60 + (zone % 100);
462 } else { // text format
463 for (i = 0; i < sizeof(kRFC822_TimeZone) / sizeof(TimeZoneInfo); i++)
464 if (str_token == kRFC822_TimeZone[i].zone_name) {
465 bias = kRFC822_TimeZone[i].hour_dif * 60;
466 break;
467 }
468 }
469
470 SYSTEMTIME mail_time;
471 memset(&mail_time, 0, sizeof(mail_time));
472
473 mail_time.wYear = static_cast<WORD>(year);
474 mail_time.wMonth = static_cast<WORD>(month);
475 mail_time.wDay = static_cast<WORD>(day);
476 mail_time.wHour = static_cast<WORD>(hour);
477 mail_time.wMinute = static_cast<WORD>(minute);
478 mail_time.wSecond = static_cast<WORD>(second);
479
480 // TzSpecificLocalTimeToSystemTime() is incompatible with Win 2000,
481 // convert time manually here
482 time64 time_64 = SystemTimeToTime64(&mail_time);
483 time_64 = time_64 - (bias*kMinsTo100ns);
484
485 *psys_time = Time64ToSystemTime(time_64);
486
487 if (ret_local_time) {
488 TIME_ZONE_INFORMATION local_time_zone_info;
489 SYSTEMTIME universal_time = *psys_time;
490
491 if (GetTimeZoneInformation(&local_time_zone_info) == TIME_ZONE_ID_INVALID) {
492 return false;
493 }
494 if (!SystemTimeToTzSpecificLocalTime(&local_time_zone_info,
495 &universal_time,
496 psys_time)) {
497 return false;
498 }
499 }
500 return true;
501 }
502
503 } // namespace omaha
504
OLDNEW
« no previous file with comments | « base/time.h ('k') | base/time_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698