Changeset 16780 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Oct 4, 2006, 11:36:29 AM (19 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 2 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/date_object.cpp
r16164 r16780 52 52 #include "error_object.h" 53 53 #include "operations.h" 54 #include <DateMath.h> 54 55 55 56 #include <wtf/MathExtras.h> … … 57 58 58 59 #if PLATFORM(MAC) 59 #include <CoreFoundation/CoreFoundation.h> 60 #endif 60 #include <CoreFoundation/CoreFoundation.h> 61 #endif 62 63 namespace KJS { 64 65 static double parseDate(const UString&); 66 static double timeClip(double); 61 67 62 68 inline int gmtoffset(const tm& t) … … 64 70 #if PLATFORM(WIN_OS) 65 71 // Time is supposed to be in the current timezone. 66 // FIXME: Use undocumented _dstbias? 67 return -(_timezone / 60 - (t.tm_isdst > 0 ? 60 : 0 )) * 60; 72 return static_cast<int>(getUTCOffset()/1000.0); 68 73 #else 69 74 return t.tm_gmtoff; … … 71 76 } 72 77 73 namespace KJS {74 78 75 79 /** … … 90 94 int id; 91 95 }; 92 93 // some constants94 const double hoursPerDay = 24;95 const double minutesPerHour = 60;96 const double secondsPerMinute = 60;97 const double msPerSecond = 1000;98 const double msPerMinute = 60 * 1000;99 const double msPerHour = 60 * 60 * 1000;100 const double msPerDay = 24 * 60 * 60 * 1000;101 102 static const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };103 static const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };104 105 static double makeTime(tm *, double ms, bool utc);106 static double parseDate(const UString &);107 static double timeClip(double);108 static void millisecondsToTM(double milli, bool utc, tm *t);109 96 110 97 #if PLATFORM(MAC) … … 197 184 char buffer[100]; 198 185 if (utc) { 199 // FIXME: why not on windows? 200 #if !PLATFORM(WIN_OS) 186 #if !PLATFORM(WIN_OS) //win doesn't have the tm_gtoff member 201 187 ASSERT(t.tm_gmtoff == 0); 202 188 #endif … … 221 207 } 222 208 return UString(buffer); 223 }224 225 static int day(double t)226 {227 return int(floor(t / msPerDay));228 }229 230 static double dayFromYear(int year)231 {232 return 365.0 * (year - 1970)233 + floor((year - 1969) / 4.0)234 - floor((year - 1901) / 100.0)235 + floor((year - 1601) / 400.0);236 }237 238 // based on the rule for whether it's a leap year or not239 static int daysInYear(int year)240 {241 if (year % 4 != 0)242 return 365;243 if (year % 400 == 0)244 return 366;245 if (year % 100 == 0)246 return 365;247 return 366;248 }249 250 // time value of the start of a year251 static double timeFromYear(int year)252 {253 return msPerDay * dayFromYear(year);254 }255 256 // year determined by time value257 static int yearFromTime(double t)258 {259 // ### there must be an easier way260 261 // initial guess262 int y = 1970 + int(t / (365.25 * msPerDay));263 264 // adjustment265 if (timeFromYear(y) > t) {266 do267 --y;268 while (timeFromYear(y) > t);269 } else {270 while (timeFromYear(y + 1) < t)271 ++y;272 }273 274 return y;275 }276 277 // 0: Sunday, 1: Monday, etc.278 static int weekDay(double t)279 {280 int wd = (day(t) + 4) % 7;281 if (wd < 0)282 wd += 7;283 return wd;284 209 } 285 210 … … 369 294 return false; 370 295 371 m illisecondsToTM(milli, false, &t);296 msToTM(milli, false, t); 372 297 offset = gmtoffset(t); 373 298 return true; … … 380 305 return false; 381 306 382 m illisecondsToTM(milli, true, &t);307 msToTM(milli, true, t); 383 308 return true; 384 309 } … … 391 316 392 317 tm t; 393 m illisecondsToTM(milli, false, &t);318 msToTM(milli, false, t); 394 319 offset = gmtoffset(t); 395 320 return true; … … 410 335 return minusOne < 0; 411 336 } 412 413 static void millisecondsToTM(double milli, bool utc, tm *t)414 {415 // check whether time value is outside time_t's usual range416 // make the necessary transformations if necessary417 static bool time_tIsSigned = isTime_tSigned();418 static double time_tMin = (time_tIsSigned ? - (double)(1ULL << (8 * sizeof(time_t) - 1)) : 0);419 static double time_tMax = (time_tIsSigned ? (1ULL << 8 * sizeof(time_t) - 1) - 1 : 2 * (double)(1ULL << 8 * sizeof(time_t) - 1) - 1);420 int realYearOffset = 0;421 double milliOffset = 0.0;422 double secs = floor(milli / msPerSecond);423 424 if (secs < time_tMin || secs > time_tMax) {425 // ### ugly and probably not very precise426 int realYear = yearFromTime(milli);427 int base = daysInYear(realYear) == 365 ? 2001 : 2000;428 milliOffset = timeFromYear(base) - timeFromYear(realYear);429 milli += milliOffset;430 realYearOffset = realYear - base;431 }432 433 time_t tv = (time_t) floor(milli / msPerSecond);434 435 *t = *(utc ? gmtime(&tv) : localtime(&tv));436 // We had an out of range year. Restore the year (plus/minus offset437 // found by calculating tm_year) and fix the week day calculation.438 if (realYearOffset != 0) {439 t->tm_year += realYearOffset;440 milli -= milliOffset;441 // Do our own weekday calculation. Use time zone offset to handle local time.442 double m = milli;443 if (!utc)444 m += gmtoffset(*t) * msPerSecond;445 t->tm_wday = weekDay(m);446 }447 }448 449 337 450 338 // ------------------------------ DatePrototype ----------------------------- … … 576 464 577 465 tm t; 578 m illisecondsToTM(milli, utc, &t);466 msToTM(milli, utc, t); 579 467 580 468 switch (id) { … … 675 563 id == SetMinutes || id == SetHours || id == SetDate || 676 564 id == SetMonth || id == SetFullYear ) { 677 result = jsNumber( makeTime(&t, ms, utc));565 result = jsNumber(dateToMseconds(&t, ms, utc)); 678 566 thisDateObj->setInternalValue(result); 679 567 } … … 762 650 t.tm_isdst = -1; 763 651 double ms = (numArgs >= 7) ? roundValue(exec, args[6]) : 0; 764 value = makeTime(&t, ms, false);652 value = dateToMseconds(&t, ms, false); 765 653 } 766 654 } … … 815 703 t.tm_sec = (n >= 6) ? args[5]->toInt32(exec) : 0; 816 704 double ms = (n >= 7) ? roundValue(exec, args[6]) : 0; 817 return jsNumber( makeTime(&t, ms, true));705 return jsNumber(dateToMseconds(&t, ms, true)); 818 706 } 819 707 } … … 853 741 { "PDT", -420 } 854 742 }; 855 856 static double makeTime(tm *t, double ms, bool utc)857 {858 int utcOffset;859 if (utc) {860 time_t zero = 0;861 #if PLATFORM(WIN_OS)862 // FIXME: not thread safe863 (void)localtime(&zero);864 #if COMPILER(BORLAND) || COMPILER(CYGWIN)865 utcOffset = - _timezone;866 #else867 utcOffset = - timezone;868 #endif869 t->tm_isdst = 0;870 #else871 tm t3;872 localtime_r(&zero, &t3);873 utcOffset = t3.tm_gmtoff;874 t->tm_isdst = t3.tm_isdst;875 #endif876 } else {877 utcOffset = 0;878 t->tm_isdst = -1;879 }880 881 double yearOffset = 0.0;882 if (t->tm_year < (1970 - 1900) || t->tm_year > (2038 - 1900)) {883 // we'll fool mktime() into believing that this year is within884 // its normal, portable range (1970-2038) by setting tm_year to885 // 2000 or 2001 and adding the difference in milliseconds later.886 // choice between offset will depend on whether the year is a887 // leap year or not.888 int y = t->tm_year + 1900;889 int baseYear = daysInYear(y) == 365 ? 2001 : 2000;890 double baseTime = timeFromYear(baseYear);891 yearOffset = timeFromYear(y) - baseTime;892 t->tm_year = baseYear - 1900;893 }894 895 // Determine whether DST is in effect. mktime() can't do this for us because896 // it doesn't know about ms and yearOffset.897 // NOTE: Casting values of large magnitude to time_t (long) will898 // produce incorrect results, but there's no other option when calling localtime_r().899 if (!utc) {900 time_t tval = mktime(t) + (time_t)((ms + yearOffset) / 1000);901 tm t3 = *localtime(&tval);902 t->tm_isdst = t3.tm_isdst;903 }904 905 return (mktime(t) + utcOffset) * msPerSecond + ms + yearOffset;906 }907 743 908 744 inline static void skipSpacesAndComments(const char *&s) … … 1234 1070 t.tm_hour = hour; 1235 1071 1236 // Use our makeTime() rather than mktime() as the latter can't handle the full year range.1237 return makeTime(&t, 0, false);1072 // Use our dateToMseconds() rather than mktime() as the latter can't handle the full year range. 1073 return dateToMseconds(&t, 0, false); 1238 1074 } 1239 1075 -
trunk/JavaScriptCore/kjs/testkjs.cpp
r15437 r16780 32 32 #include <math.h> 33 33 #include <stdio.h> 34 34 35 #include <string.h> 35 36 #if HAVE(SYS_TIME_H)
Note:
See TracChangeset
for help on using the changeset viewer.