Changeset 19943 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Mar 2, 2007, 9:42:20 AM (18 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/DateMath.cpp
r19268 r19943 45 45 #include <math.h> 46 46 #include <stdint.h> 47 #include <wtf/OwnPtr.h> 47 48 #if PLATFORM(DARWIN) 49 #include <notify.h> 50 #endif 48 51 49 52 namespace KJS { … … 57 60 static const double usecPerSec = 1000000.0; 58 61 59 static const double maxUnixTime = 2145859200.0; /*equivalent to 12/31/2037 */ 60 61 /* 62 * The following array contains the day of year for the first day of 63 * each month, where index 0 is January, and day 0 is January 1. 64 */ 65 static int firstDayOfMonth[2][12] = { 62 static const double maxUnixTime = 2145859200.0; // 12/31/2037 63 64 // Day of year for the first day of each month, where index 0 is January, and day 0 is January 1. 65 // First for non-leap years, then for leap years. 66 static const int firstDayOfMonth[2][12] = { 66 67 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, 67 68 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} 68 69 }; 69 70 static inline int daysInYear(int year)71 {72 if (year % 4 != 0)73 return 365;74 if (year % 400 == 0)75 return 366;76 if (year % 100 == 0)77 return 365;78 return 366;79 }80 81 static inline double daysFrom1970ToYear(int year)82 {83 return 365.0 * (year - 1970)84 + floor((year - 1969) / 4.0)85 - floor((year - 1901) / 100.0)86 + floor((year - 1601) / 400.0);87 }88 89 static inline double msFrom1970ToYear(int year)90 {91 return msPerDay * daysFrom1970ToYear(year);92 }93 94 static inline double msToDays(double ms)95 {96 return floor(ms / msPerDay);97 }98 99 static inline int msToYear(double ms)100 {101 int y = static_cast<int>(floor(ms /(msPerDay*365.2425)) + 1970);102 double t2 = msFrom1970ToYear(y);103 104 if (t2 > ms) {105 y--;106 } else {107 if (t2 + msPerDay * daysInYear(y) <= ms)108 y++;109 }110 return y;111 }112 70 113 71 static inline bool isLeapYear(int year) … … 122 80 } 123 81 82 static inline int daysInYear(int year) 83 { 84 return 365 + isLeapYear(year); 85 } 86 87 static inline double daysFrom1970ToYear(int year) 88 { 89 return 365.0 * (year - 1970) 90 + floor((year - 1969) / 4.0) 91 - floor((year - 1901) / 100.0) 92 + floor((year - 1601) / 400.0); 93 } 94 95 static inline double msFrom1970ToYear(int year) 96 { 97 return msPerDay * daysFrom1970ToYear(year); 98 } 99 100 static inline double msToDays(double ms) 101 { 102 return floor(ms / msPerDay); 103 } 104 105 static inline int msToYear(double ms) 106 { 107 int y = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970); 108 double t2 = msFrom1970ToYear(y); 109 if (t2 > ms) { 110 y--; 111 } else { 112 if (t2 + msPerDay * daysInYear(y) <= ms) 113 y++; 114 } 115 return y; 116 } 117 124 118 static inline bool isInLeapYear(double ms) 125 119 { … … 134 128 static inline double msToMilliseconds(double ms) 135 129 { 136 double result; 137 result = fmod(ms, msPerDay); 130 double result = fmod(ms, msPerDay); 138 131 if (result < 0) 139 132 result += msPerDay; … … 144 137 static inline int msToWeekDay(double ms) 145 138 { 146 int wd = ( (int)msToDays(ms) + 4) % 7;139 int wd = (static_cast<int>(msToDays(ms)) + 4) % 7; 147 140 if (wd < 0) 148 141 wd += 7; … … 152 145 static inline int msToSeconds(double ms) 153 146 { 154 int result = (int)fmod(floor(ms / msPerSecond), secondsPerMinute);147 double result = fmod(floor(ms / msPerSecond), secondsPerMinute); 155 148 if (result < 0) 156 result += (int)secondsPerMinute;157 return result;149 result += secondsPerMinute; 150 return static_cast<int>(result); 158 151 } 159 152 160 153 static inline int msToMinutes(double ms) 161 154 { 162 int result = (int)fmod(floor(ms / msPerMinute), minutesPerHour);155 double result = fmod(floor(ms / msPerMinute), minutesPerHour); 163 156 if (result < 0) 164 result += (int)minutesPerHour;165 return result;157 result += minutesPerHour; 158 return static_cast<int>(result); 166 159 } 167 160 168 161 static inline int msToHours(double ms) 169 162 { 170 int result = (int)fmod(floor(ms/msPerHour), hoursPerDay);163 double result = fmod(floor(ms/msPerHour), hoursPerDay); 171 164 if (result < 0) 172 result += (int)hoursPerDay;173 return result;165 result += hoursPerDay; 166 return static_cast<int>(result); 174 167 } 175 168 176 169 static inline int msToMonth(double ms) 177 170 { 178 int d,step;171 int step; 179 172 int year = msToYear(ms); 180 d = dayInYear(ms, year);173 int d = dayInYear(ms, year); 181 174 182 175 if (d < (step = 31)) … … 208 201 static inline int msToDayInMonth(double ms) 209 202 { 210 int d,step, next;203 int step, next; 211 204 int year = msToYear(ms); 212 d = dayInYear(ms, year);205 int d = dayInYear(ms, year); 213 206 214 207 if (d <= (next = 30)) … … 294 287 * NOT including DST. 295 288 */ 296 double getUTCOffset() { 289 double getUTCOffset() 290 { 291 #if PLATFORM(DARWIN) 292 // Register for a notification whenever the time zone changes. 293 static bool triedToRegister = false; 294 static bool haveNotificationToken = false; 295 static int notificationToken; 296 if (!triedToRegister) { 297 triedToRegister = true; 298 uint32_t status = notify_register_check("com.apple.system.timezone", ¬ificationToken); 299 if (status == NOTIFY_STATUS_OK) 300 haveNotificationToken = true; 301 } 302 303 // If we can verify that we have not received a time zone notification, 304 // then use the cached offset from the last time this function was called. 305 static bool haveCachedOffset = false; 306 static double cachedOffset; 307 if (haveNotificationToken && haveCachedOffset) { 308 int notified; 309 uint32_t status = notify_check(notificationToken, ¬ified); 310 if (status == NOTIFY_STATUS_OK && !notified) 311 return cachedOffset; 312 } 313 #endif 314 297 315 tm localt; 298 316 … … 305 323 306 324 utcOffset *= msPerSecond; 325 326 #if PLATFORM(DARWIN) 327 haveCachedOffset = true; 328 cachedOffset = utcOffset; 329 #endif 307 330 308 331 return utcOffset; … … 316 339 static double getDSTOffsetSimple(double localTimeSeconds) 317 340 { 318 if (localTimeSeconds > maxUnixTime)341 if (localTimeSeconds > maxUnixTime) 319 342 localTimeSeconds = maxUnixTime; 320 343 else if(localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0) … … 322 345 323 346 //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset() 324 double offsetTime = (localTimeSeconds * msPerSecond) + getUTCOffset() 347 double offsetTime = (localTimeSeconds * msPerSecond) + getUTCOffset(); 325 348 326 349 // Offset from UTC but doesn't include DST obviously … … 332 355 333 356 tm localTM; 334 357 #if PLATFORM(WIN_OS) 335 358 localtime_s(&localTM, &localTime); 336 359 #else 337 360 localtime_r(&localTime, &localTM); 338 339 361 #endif 362 340 363 double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM.tm_min - offsetMinute) * 60); 341 364 … … 346 369 } 347 370 348 // Get the DST offset the time passed in 349 // ms is in UTC 371 // Get the DST offset, given a time in UTC 350 372 static double getDSTOffset(double ms) 351 373 { 352 // On macthe call to localtime (see getDSTOffsetSimple) will return historically accurate374 // On Mac OS X, the call to localtime (see getDSTOffsetSimple) will return historically accurate 353 375 // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript 354 376 // standard explicitly dictates that historical information should not be considered when 355 // determining DST. For this reason we shiftyears that localtime can handle but would377 // determining DST. For this reason we shift away from years that localtime can handle but would 356 378 // return historically accurate information. 357 379 358 380 // if before Jan 01, 2000 12:00:00 AM UTC or after Jan 01, 2038 12:00:00 AM UTC 359 381 if (ms < 946684800000.0 || ms > 2145916800000.0) { 360 int year; 361 int day; 362 363 year = equivalentYearForDST(msToYear(ms)); 364 day = dateToDayInYear(year, msToMonth(ms), msToDayInMonth(ms)); 382 int year = equivalentYearForDST(msToYear(ms)); 383 int day = dateToDayInYear(year, msToMonth(ms), msToDayInMonth(ms)); 365 384 ms = (day * msPerDay) + msToMilliseconds(ms); 366 385 } … … 371 390 double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bool inputIsUTC) 372 391 { 373 374 392 int day = dateToDayInYear(t.year + 1900, t.month, t.monthDay); 375 393 double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds); 376 394 double result = (day * msPerDay) + ms; 377 395 378 if (!inputIsUTC) { // convert to UTC396 if (!inputIsUTC) { // convert to UTC 379 397 result -= getUTCOffset(); 380 398 result -= getDSTOffset(result); … … 389 407 double dstOff = 0.0; 390 408 391 if (!outputIsUTC) { // convert to local time409 if (!outputIsUTC) { // convert to local time 392 410 dstOff = getDSTOffset(ms); 393 411 ms += dstOff + getUTCOffset(); … … 402 420 tm.month = msToMonth(ms); 403 421 tm.year = msToYear(ms) - 1900; 404 tm.isDST = dstOff != 0.0;422 tm.isDST = dstOff != 0.0; 405 423 406 424 tm.utcOffset = static_cast<long>((dstOff + getUTCOffset()) / msPerSecond); … … 408 426 } 409 427 410 } 428 } // namespace KJS -
trunk/JavaScriptCore/kjs/DateMath.h
r17444 r19943 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten ([email protected]) 3 * Copyright (C) 2006 Apple Computer3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 4 4 * 5 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 … … 44 44 #include <time.h> 45 45 #include <string.h> 46 #include <wtf/Noncopyable.h> 46 47 47 48 namespace KJS { 48 49 49 // Constants //50 50 const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; 51 51 const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; … … 60 60 const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0; 61 61 62 63 // Forward //64 struct GregorianDateTime;65 66 // Exported Functions //67 void msToGregorianDateTime(double, bool outputIsUTC, struct GregorianDateTime&);68 double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC);69 double getUTCOffset();70 int equivalentYearForDST(int year);71 72 62 // Intentionally overridding the default tm of the system 73 63 // Not all OS' have the same members of their tm's 74 struct GregorianDateTime {64 struct GregorianDateTime : Noncopyable{ 75 65 GregorianDateTime() 66 : second(0) 67 , minute(0) 68 , hour(0) 69 , weekDay(0) 70 , monthDay(0) 71 , yearDay(0) 72 , month(0) 73 , year(0) 74 , isDST(0) 75 , utcOffset(0) 76 , timeZone(0) 76 77 { 77 second = 0;78 minute = 0;79 hour = 0;80 weekDay = 0;81 monthDay = 0;82 yearDay = 0;83 month = 0;84 year = 0;85 isDST = 0;86 utcOffset = 0;87 timeZone = NULL;88 78 } 89 79 90 80 ~GregorianDateTime() 91 81 { 92 if (timeZone) 93 delete timeZone; 82 delete [] timeZone; 94 83 } 95 84 … … 148 137 int month; 149 138 int year; 150 int 139 int isDST; 151 140 int utcOffset; 152 141 char* timeZone; 153 142 }; 154 143 144 void msToGregorianDateTime(double, bool outputIsUTC, struct GregorianDateTime&); 145 double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC); 146 double getUTCOffset(); 147 int equivalentYearForDST(int year); 148 155 149 } //namespace KJS 156 150
Note:
See TracChangeset
for help on using the changeset viewer.