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

Side by Side Diff: Source/wtf/DateMath.cpp

Issue 394903004: document.lastModified should consider user's local time zone (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase and take review comments into consideration Created 6 years, 4 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 | « Source/wtf/DateMath.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Copyright (C) 2009 Google Inc. All rights reserved. 4 * Copyright (C) 2009 Google Inc. All rights reserved.
5 * Copyright (C) 2007-2009 Torch Mobile, Inc. 5 * Copyright (C) 2007-2009 Torch Mobile, Inc.
6 * Copyright (C) 2010 &yet, LLC. (nate@andyet.net) 6 * Copyright (C) 2010 &yet, LLC. (nate@andyet.net)
7 * 7 *
8 * The Original Code is Mozilla Communicator client code, released 8 * The Original Code is Mozilla Communicator client code, released
9 * March 31, 1998. 9 * March 31, 1998.
10 * 10 *
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 #endif 96 #endif
97 97
98 using namespace WTF; 98 using namespace WTF;
99 99
100 namespace WTF { 100 namespace WTF {
101 101
102 /* Constants */ 102 /* Constants */
103 103
104 static const double hoursPerDay = 24.0; 104 static const double hoursPerDay = 24.0;
105 static const double secondsPerDay = 24.0 * 60.0 * 60.0; 105 static const double secondsPerDay = 24.0 * 60.0 * 60.0;
106 static const double secondsPerHour = 60.0 * 60.0;
107 106
108 static const double maxUnixTime = 2145859200.0; // 12/31/2037 107 static const double maxUnixTime = 2145859200.0; // 12/31/2037
109 108
110 // Day of year for the first day of each month, where index 0 is January, and da y 0 is January 1. 109 // Day of year for the first day of each month, where index 0 is January, and da y 0 is January 1.
111 // First for non-leap years, then for leap years. 110 // First for non-leap years, then for leap years.
112 static const int firstDayOfMonth[2][12] = { 111 static const int firstDayOfMonth[2][12] = {
113 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, 112 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
114 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} 113 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
115 }; 114 };
116 115
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 187 }
189 188
190 static inline double msToMilliseconds(double ms) 189 static inline double msToMilliseconds(double ms)
191 { 190 {
192 double result = fmod(ms, msPerDay); 191 double result = fmod(ms, msPerDay);
193 if (result < 0) 192 if (result < 0)
194 result += msPerDay; 193 result += msPerDay;
195 return result; 194 return result;
196 } 195 }
197 196
198 static int msToMinutes(double ms)
199 {
200 double result = fmod(floor(ms / msPerMinute), minutesPerHour);
201 if (result < 0)
202 result += minutesPerHour;
203 return static_cast<int>(result);
204 }
205
206 static int msToHours(double ms)
207 {
208 double result = fmod(floor(ms/msPerHour), hoursPerDay);
209 if (result < 0)
210 result += hoursPerDay;
211 return static_cast<int>(result);
212 }
213
214 int monthFromDayInYear(int dayInYear, bool leapYear) 197 int monthFromDayInYear(int dayInYear, bool leapYear)
215 { 198 {
216 const int d = dayInYear; 199 const int d = dayInYear;
217 int step; 200 int step;
218 201
219 if (d < (step = 31)) 202 if (d < (step = 31))
220 return 0; 203 return 0;
221 step += (leapYear ? 29 : 28); 204 step += (leapYear ? 29 : 28);
222 if (d < step) 205 if (d < step)
223 return 1; 206 return 1;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 return year; 334 return year;
352 335
353 int quotient = difference / 28; 336 int quotient = difference / 28;
354 int product = (quotient) * 28; 337 int product = (quotient) * 28;
355 338
356 year += product; 339 year += product;
357 ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cas t<int>(std::numeric_limits<double>::quiet_NaN()))); 340 ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cas t<int>(std::numeric_limits<double>::quiet_NaN())));
358 return year; 341 return year;
359 } 342 }
360 343
361 int32_t calculateUTCOffset() 344 static double calculateUTCOffset()
362 { 345 {
363 #if OS(WIN) 346 #if OS(WIN)
364 TIME_ZONE_INFORMATION timeZoneInformation; 347 TIME_ZONE_INFORMATION timeZoneInformation;
365 GetTimeZoneInformation(&timeZoneInformation); 348 GetTimeZoneInformation(&timeZoneInformation);
366 int32_t bias = timeZoneInformation.Bias + timeZoneInformation.StandardBias; 349 int32_t bias = timeZoneInformation.Bias + timeZoneInformation.StandardBias;
367 return -bias * 60 * 1000; 350 return -bias * 60 * 1000;
368 #else 351 #else
369 time_t localTime = time(0); 352 time_t localTime = time(0);
370 tm localt; 353 tm localt;
371 getLocalTime(&localTime, &localt); 354 getLocalTime(&localTime, &localt);
372 355
373 // Get the difference between this time zone and UTC on the 1st of January o f this year. 356 // tm_gmtoff includes any daylight savings offset, so subtract it.
374 localt.tm_sec = 0; 357 return static_cast<double>(localt.tm_gmtoff * msPerSecond - (localt.tm_isdst > 0 ? msPerHour : 0));
375 localt.tm_min = 0;
376 localt.tm_hour = 0;
377 localt.tm_mday = 1;
378 localt.tm_mon = 0;
379 // Not setting localt.tm_year!
380 localt.tm_wday = 0;
381 localt.tm_yday = 0;
382 localt.tm_isdst = 0;
383 #if HAVE(TM_GMTOFF)
384 localt.tm_gmtoff = 0;
385 #endif
386 #if HAVE(TM_ZONE)
387 localt.tm_zone = 0;
388 #endif
389
390 #if HAVE(TIMEGM)
391 time_t utcOffset = timegm(&localt) - mktime(&localt);
392 #else
393 // Using a canned date of 01/01/2009 on platforms with weaker date-handling foo.
394 localt.tm_year = 109;
395 time_t utcOffset = 1230768000 - mktime(&localt);
396 #endif
397
398 return static_cast<int32_t>(utcOffset * 1000);
399 #endif 358 #endif
400 } 359 }
401 360
402 /* 361 /*
403 * Get the DST offset for the time passed in. 362 * Get the DST offset for the time passed in.
404 */ 363 */
405 static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset ) 364 static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset )
406 { 365 {
407 if (localTimeSeconds > maxUnixTime) 366 if (localTimeSeconds > maxUnixTime)
408 localTimeSeconds = maxUnixTime; 367 localTimeSeconds = maxUnixTime;
409 else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (doe s not work with 0) 368 else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (doe s not work with 0)
410 localTimeSeconds += secondsPerDay; 369 localTimeSeconds += secondsPerDay;
411 370
412 //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset()
413 double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset;
414
415 // Offset from UTC but doesn't include DST obviously
416 int offsetHour = msToHours(offsetTime);
417 int offsetMinute = msToMinutes(offsetTime);
418
419 // FIXME: time_t has a potential problem in 2038 371 // FIXME: time_t has a potential problem in 2038
420 time_t localTime = static_cast<time_t>(localTimeSeconds); 372 time_t localTime = static_cast<time_t>(localTimeSeconds);
421 373
422 tm localTM; 374 tm localTM;
423 getLocalTime(&localTime, &localTM); 375 getLocalTime(&localTime, &localTM);
424 376
425 double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM. tm_min - offsetMinute) * 60); 377 return localTM.tm_isdst > 0 ? msPerHour : 0;
426
427 if (diff < 0)
428 diff += secondsPerDay;
429
430 return (diff * msPerSecond);
431 } 378 }
432 379
433 // Get the DST offset, given a time in UTC 380 // Get the DST offset, given a time in UTC
434 double calculateDSTOffset(double ms, double utcOffset) 381 static double calculateDSTOffset(double ms, double utcOffset)
435 { 382 {
436 // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will re turn historically accurate 383 // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will re turn historically accurate
437 // DST information (e.g. New Zealand did not have DST from 1946 to 1974) how ever the JavaScript 384 // DST information (e.g. New Zealand did not have DST from 1946 to 1974) how ever the JavaScript
438 // standard explicitly dictates that historical information should not be co nsidered when 385 // standard explicitly dictates that historical information should not be co nsidered when
439 // determining DST. For this reason we shift away from years that localtime can handle but would 386 // determining DST. For this reason we shift away from years that localtime can handle but would
440 // return historically accurate information. 387 // return historically accurate information.
441 int year = msToYear(ms); 388 int year = msToYear(ms);
442 int equivalentYear = equivalentYearForDST(year); 389 int equivalentYear = equivalentYearForDST(year);
443 if (year != equivalentYear) { 390 if (year != equivalentYear) {
444 bool leapYear = isLeapYear(year); 391 bool leapYear = isLeapYear(year);
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 stringBuilder.append(' '); 821 stringBuilder.append(' ');
875 822
876 stringBuilder.append(utcOffset > 0 ? '+' : '-'); 823 stringBuilder.append(utcOffset > 0 ? '+' : '-');
877 int absoluteUTCOffset = abs(utcOffset); 824 int absoluteUTCOffset = abs(utcOffset);
878 stringBuilder.append(twoDigitStringFromNumber(absoluteUTCOffset / 60)); 825 stringBuilder.append(twoDigitStringFromNumber(absoluteUTCOffset / 60));
879 stringBuilder.append(twoDigitStringFromNumber(absoluteUTCOffset % 60)); 826 stringBuilder.append(twoDigitStringFromNumber(absoluteUTCOffset % 60));
880 827
881 return stringBuilder.toString(); 828 return stringBuilder.toString();
882 } 829 }
883 830
831 double convertToLocalTime(double ms)
832 {
833 double utcOffset = calculateUTCOffset();
834 double dstOffset = calculateDSTOffset(ms, utcOffset);
835 return (ms + utcOffset + dstOffset);
836 }
837
884 } // namespace WTF 838 } // namespace WTF
OLDNEW
« no previous file with comments | « Source/wtf/DateMath.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698