2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 
   3  *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 
   5  *  This library is free software; you can redistribute it and/or 
   6  *  modify it under the terms of the GNU Lesser General Public 
   7  *  License as published by the Free Software Foundation; either 
   8  *  version 2 of the License, or (at your option) any later version. 
  10  *  This library is distributed in the hope that it will be useful, 
  11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
  12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  13  *  Lesser General Public License for more details. 
  15  *  You should have received a copy of the GNU Lesser General Public 
  16  *  License along with this library; if not, write to the Free Software 
  17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 
  23 #include "date_object.h" 
  24 #include "date_object.lut.h" 
  32 #include <sys/param.h> 
  40 #include <sys/timeb.h> 
  52 #include "error_object.h" 
  53 #include "operations.h" 
  56 #include <wtf/ASCIICType.h> 
  57 #include <wtf/Assertions.h> 
  58 #include <wtf/MathExtras.h> 
  59 #include <wtf/StringExtras.h> 
  60 #include <wtf/UnusedParam.h> 
  62     #include <CoreFoundation/CoreFoundation.h> 
  68 static double parseDate(const UString
&); 
  69 static double timeClip(double); 
  71 inline int gmtoffset(const GregorianDateTime
& t
) 
  80  * Class to implement all methods that are properties of the 
  83 class DateObjectFuncImp 
: public InternalFunctionImp 
{ 
  85     DateObjectFuncImp(ExecState 
*, FunctionPrototype 
*, int i
, int len
, const Identifier
& ); 
  87     virtual JSValue 
*callAsFunction(ExecState 
*, JSObject 
*thisObj
, const List 
&args
); 
  96 static CFDateFormatterStyle 
styleFromArgString(const UString
& string
, CFDateFormatterStyle defaultStyle
) 
  98     if (string 
== "short") 
  99         return kCFDateFormatterShortStyle
; 
 100     if (string 
== "medium") 
 101         return kCFDateFormatterMediumStyle
; 
 102     if (string 
== "long") 
 103         return kCFDateFormatterLongStyle
; 
 104     if (string 
== "full") 
 105         return kCFDateFormatterFullStyle
; 
 109 static UString 
formatLocaleDate(ExecState 
*exec
, double time
, bool includeDate
, bool includeTime
, const List 
&args
) 
 111     CFDateFormatterStyle dateStyle 
= (includeDate 
? kCFDateFormatterLongStyle 
: kCFDateFormatterNoStyle
); 
 112     CFDateFormatterStyle timeStyle 
= (includeTime 
? kCFDateFormatterLongStyle 
: kCFDateFormatterNoStyle
); 
 114     bool useCustomFormat 
= false; 
 115     UString customFormatString
; 
 117     UString arg0String 
= args
[0]->toString(exec
); 
 118     if (arg0String 
== "custom" && !args
[1]->isUndefined()) { 
 119         useCustomFormat 
= true; 
 120         customFormatString 
= args
[1]->toString(exec
); 
 121     } else if (includeDate 
&& includeTime 
&& !args
[1]->isUndefined()) { 
 122         dateStyle 
= styleFromArgString(arg0String
, dateStyle
); 
 123         timeStyle 
= styleFromArgString(args
[1]->toString(exec
), timeStyle
); 
 124     } else if (includeDate 
&& !args
[0]->isUndefined()) { 
 125         dateStyle 
= styleFromArgString(arg0String
, dateStyle
); 
 126     } else if (includeTime 
&& !args
[0]->isUndefined()) { 
 127         timeStyle 
= styleFromArgString(arg0String
, timeStyle
); 
 130     CFLocaleRef locale 
= CFLocaleCopyCurrent(); 
 131     CFDateFormatterRef formatter 
= CFDateFormatterCreate(0, locale
, dateStyle
, timeStyle
); 
 134     if (useCustomFormat
) { 
 135         CFStringRef customFormatCFString 
= CFStringCreateWithCharacters(0, (UniChar 
*)customFormatString
.data(), customFormatString
.size()); 
 136         CFDateFormatterSetFormat(formatter
, customFormatCFString
); 
 137         CFRelease(customFormatCFString
); 
 140     CFStringRef string 
= CFDateFormatterCreateStringWithAbsoluteTime(0, formatter
, time 
- kCFAbsoluteTimeIntervalSince1970
); 
 142     CFRelease(formatter
); 
 144     // We truncate the string returned from CFDateFormatter if it's absurdly long (> 200 characters). 
 145     // That's not great error handling, but it just won't happen so it doesn't matter. 
 147     const size_t bufferLength 
= sizeof(buffer
) / sizeof(buffer
[0]); 
 148     size_t length 
= CFStringGetLength(string
); 
 149     ASSERT(length 
<= bufferLength
); 
 150     if (length 
> bufferLength
) 
 151         length 
= bufferLength
; 
 152     CFStringGetCharacters(string
, CFRangeMake(0, length
), reinterpret_cast<UniChar 
*>(buffer
)); 
 156     return UString(buffer
, length
); 
 160 static UString 
formatDate(const GregorianDateTime 
&t
) 
 163     snprintf(buffer
, sizeof(buffer
), "%s %s %02d %04d", 
 164         weekdayName
[(t
.weekDay 
+ 6) % 7], 
 165         monthName
[t
.month
], t
.monthDay
, t
.year 
+ 1900); 
 169 static UString 
formatDateUTCVariant(const GregorianDateTime 
&t
) 
 172     snprintf(buffer
, sizeof(buffer
), "%s, %02d %s %04d", 
 173         weekdayName
[(t
.weekDay 
+ 6) % 7], 
 174         t
.monthDay
, monthName
[t
.month
], t
.year 
+ 1900); 
 178 static UString 
formatTime(const GregorianDateTime 
&t
, bool utc
) 
 182         snprintf(buffer
, sizeof(buffer
), "%02d:%02d:%02d GMT", t
.hour
, t
.minute
, t
.second
); 
 184         int offset 
= abs(gmtoffset(t
)); 
 187         strftime(tzname
, sizeof(tzname
), "%Z", >m
); 
 190             snprintf(buffer
, sizeof(buffer
), "%02d:%02d:%02d GMT%c%02d%02d (%s)", 
 191                 t
.hour
, t
.minute
, t
.second
, 
 192                 gmtoffset(t
) < 0 ? '-' : '+', offset 
/ (60*60), (offset 
/ 60) % 60, tzname
); 
 194             snprintf(buffer
, sizeof(buffer
), "%02d:%02d:%02d GMT%c%02d%02d", 
 195                 t
.hour
, t
.minute
, t
.second
, 
 196                 gmtoffset(t
) < 0 ? '-' : '+', offset 
/ (60*60), (offset 
/ 60) % 60); 
 199     return UString(buffer
); 
 202 // Converts a list of arguments sent to a Date member function into milliseconds, updating 
 203 // ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. 
 205 // Format of member function: f([hour,] [min,] [sec,] [ms]) 
 206 static void fillStructuresUsingTimeArgs(ExecState
* exec
, const List
& args
, int maxArgs
, double* ms
, GregorianDateTime
* t
) 
 208     double milliseconds 
= 0; 
 210     int numArgs 
= args
.size(); 
 212     // JS allows extra trailing arguments -- ignore them 
 213     if (numArgs 
> maxArgs
) 
 217     if (maxArgs 
>= 4 && idx 
< numArgs
) { 
 219         milliseconds 
+= args
[idx
++]->toInt32(exec
) * msPerHour
; 
 223     if (maxArgs 
>= 3 && idx 
< numArgs
) { 
 225         milliseconds 
+= args
[idx
++]->toInt32(exec
) * msPerMinute
; 
 229     if (maxArgs 
>= 2 && idx 
< numArgs
) { 
 231         milliseconds 
+= args
[idx
++]->toInt32(exec
) * msPerSecond
; 
 236         milliseconds 
+= args
[idx
]->toNumber(exec
); 
 243 // Converts a list of arguments sent to a Date member function into years, months, and milliseconds, updating 
 244 // ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. 
 246 // Format of member function: f([years,] [months,] [days]) 
 247 static void fillStructuresUsingDateArgs(ExecState 
*exec
, const List 
&args
, int maxArgs
, double *ms
, GregorianDateTime 
*t
) 
 250     int numArgs 
= args
.size(); 
 252     // JS allows extra trailing arguments -- ignore them 
 253     if (numArgs 
> maxArgs
) 
 257     if (maxArgs 
>= 3 && idx 
< numArgs
) 
 258         t
->year 
= args
[idx
++]->toInt32(exec
) - 1900; 
 261     if (maxArgs 
>= 2 && idx 
< numArgs
) 
 262         t
->month 
= args
[idx
++]->toInt32(exec
); 
 267         *ms 
+= args
[idx
]->toInt32(exec
) * msPerDay
; 
 271 // ------------------------------ DateInstance ------------------------------ 
 273 const ClassInfo 
DateInstance::info 
= {"Date", 0, 0}; 
 275 DateInstance::DateInstance(JSObject 
*proto
) 
 276   : JSWrapperObject(proto
) 
 280 bool DateInstance::getTime(GregorianDateTime 
&t
, int &offset
) const 
 282     double milli 
= internalValue()->getNumber(); 
 286     msToGregorianDateTime(milli
, false, t
); 
 287     offset 
= gmtoffset(t
); 
 291 bool DateInstance::getUTCTime(GregorianDateTime 
&t
) const 
 293     double milli 
= internalValue()->getNumber(); 
 297     msToGregorianDateTime(milli
, true, t
); 
 301 bool DateInstance::getTime(double &milli
, int &offset
) const 
 303     milli 
= internalValue()->getNumber(); 
 308     msToGregorianDateTime(milli
, false, t
); 
 309     offset 
= gmtoffset(t
); 
 313 bool DateInstance::getUTCTime(double &milli
) const 
 315     milli 
= internalValue()->getNumber(); 
 322 static inline bool isTime_tSigned() 
 324     time_t minusOne 
= (time_t)(-1); 
 328 // ------------------------------ DatePrototype ----------------------------- 
 330 const ClassInfo 
DatePrototype::info 
= {"Date", &DateInstance::info
, &dateTable
}; 
 332 /* Source for date_object.lut.h 
 333    FIXMEL We could use templates to simplify the UTC variants. 
 335   toString              dateProtoFuncToString                DontEnum|Function       0 
 336   toUTCString           dateProtoFuncToUTCString             DontEnum|Function       0 
 337   toDateString          dateProtoFuncToDateString            DontEnum|Function       0 
 338   toTimeString          dateProtoFuncToTimeString            DontEnum|Function       0 
 339   toLocaleString        dateProtoFuncToLocaleString          DontEnum|Function       0 
 340   toLocaleDateString    dateProtoFuncToLocaleDateString      DontEnum|Function       0 
 341   toLocaleTimeString    dateProtoFuncToLocaleTimeString      DontEnum|Function       0 
 342   valueOf               dateProtoFuncValueOf                 DontEnum|Function       0 
 343   getTime               dateProtoFuncGetTime                 DontEnum|Function       0 
 344   getFullYear           dateProtoFuncGetFullYear             DontEnum|Function       0 
 345   getUTCFullYear        dateProtoFuncGetUTCFullYear          DontEnum|Function       0 
 346   toGMTString           dateProtoFuncToGMTString             DontEnum|Function       0 
 347   getMonth              dateProtoFuncGetMonth                DontEnum|Function       0 
 348   getUTCMonth           dateProtoFuncGetUTCMonth             DontEnum|Function       0 
 349   getDate               dateProtoFuncGetDate                 DontEnum|Function       0 
 350   getUTCDate            dateProtoFuncGetUTCDate              DontEnum|Function       0 
 351   getDay                dateProtoFuncGetDay                  DontEnum|Function       0 
 352   getUTCDay             dateProtoFuncGetUTCDay               DontEnum|Function       0 
 353   getHours              dateProtoFuncGetHours                DontEnum|Function       0 
 354   getUTCHours           dateProtoFuncGetUTCHours             DontEnum|Function       0 
 355   getMinutes            dateProtoFuncGetMinutes              DontEnum|Function       0 
 356   getUTCMinutes         dateProtoFuncGetUTCMinutes           DontEnum|Function       0 
 357   getSeconds            dateProtoFuncGetSeconds              DontEnum|Function       0 
 358   getUTCSeconds         dateProtoFuncGetUTCSeconds           DontEnum|Function       0 
 359   getMilliseconds       dateProtoFuncGetMilliSeconds         DontEnum|Function       0 
 360   getUTCMilliseconds    dateProtoFuncGetUTCMilliseconds      DontEnum|Function       0 
 361   getTimezoneOffset     dateProtoFuncGetTimezoneOffset       DontEnum|Function       0 
 362   setTime               dateProtoFuncSetTime                 DontEnum|Function       1 
 363   setMilliseconds       dateProtoFuncSetMilliSeconds         DontEnum|Function       1 
 364   setUTCMilliseconds    dateProtoFuncSetUTCMilliseconds      DontEnum|Function       1 
 365   setSeconds            dateProtoFuncSetSeconds              DontEnum|Function       2 
 366   setUTCSeconds         dateProtoFuncSetUTCSeconds           DontEnum|Function       2 
 367   setMinutes            dateProtoFuncSetMinutes              DontEnum|Function       3 
 368   setUTCMinutes         dateProtoFuncSetUTCMinutes           DontEnum|Function       3 
 369   setHours              dateProtoFuncSetHours                DontEnum|Function       4 
 370   setUTCHours           dateProtoFuncSetUTCHours             DontEnum|Function       4 
 371   setDate               dateProtoFuncSetDate                 DontEnum|Function       1 
 372   setUTCDate            dateProtoFuncSetUTCDate              DontEnum|Function       1 
 373   setMonth              dateProtoFuncSetMonth                DontEnum|Function       2 
 374   setUTCMonth           dateProtoFuncSetUTCMonth             DontEnum|Function       2 
 375   setFullYear           dateProtoFuncSetFullYear             DontEnum|Function       3 
 376   setUTCFullYear        dateProtoFuncSetUTCFullYear          DontEnum|Function       3 
 377   setYear               dateProtoFuncSetYear                 DontEnum|Function       1 
 378   getYear               dateProtoFuncGetYear                 DontEnum|Function       0 
 383 DatePrototype::DatePrototype(ExecState 
*, ObjectPrototype 
*objectProto
) 
 384   : DateInstance(objectProto
) 
 386     setInternalValue(jsNaN()); 
 387     // The constructor will be added later, after DateObjectImp has been built. 
 390 bool DatePrototype::getOwnPropertySlot(ExecState
* exec
, const Identifier
& propertyName
, PropertySlot
& slot
) 
 392     return getStaticFunctionSlot
<JSObject
>(exec
, &dateTable
, this, propertyName
, slot
); 
 395 // ------------------------------ DateObjectImp -------------------------------- 
 397 // TODO: MakeTime (15.9.11.1) etc. ? 
 399 DateObjectImp::DateObjectImp(ExecState
* exec
, FunctionPrototype
* funcProto
, DatePrototype
* dateProto
) 
 400   : InternalFunctionImp(funcProto
, dateProto
->classInfo()->className
) 
 402   static const Identifier
* parsePropertyName 
= new Identifier("parse"); 
 403   static const Identifier
* UTCPropertyName 
= new Identifier("UTC"); 
 405   putDirect(exec
->propertyNames().prototype
, dateProto
, DontEnum
|DontDelete
|ReadOnly
); 
 406   putDirectFunction(new DateObjectFuncImp(exec
, funcProto
, DateObjectFuncImp::Parse
, 1, *parsePropertyName
), DontEnum
); 
 407   putDirectFunction(new DateObjectFuncImp(exec
, funcProto
, DateObjectFuncImp::UTC
, 7, *UTCPropertyName
), DontEnum
); 
 408   putDirect(exec
->propertyNames().length
, 7, ReadOnly
|DontDelete
|DontEnum
); 
 411 bool DateObjectImp::implementsConstruct() const 
 417 JSObject 
*DateObjectImp::construct(ExecState 
*exec
, const List 
&args
) 
 419   int numArgs 
= args
.size(); 
 423   if (numArgs 
== 0) { // new Date() ECMA 15.9.3.3 
 424     value 
= getCurrentUTCTime(); 
 425   } else if (numArgs 
== 1) { 
 426     if (args
[0]->isObject(&DateInstance::info
)) 
 427       value 
= static_cast<DateInstance
*>(args
[0])->internalValue()->toNumber(exec
); 
 429       JSValue
* primitive 
= args
[0]->toPrimitive(exec
); 
 430       if (primitive
->isString()) 
 431         value 
= parseDate(primitive
->getString()); 
 433         value 
= primitive
->toNumber(exec
); 
 436     if (isnan(args
[0]->toNumber(exec
)) 
 437         || isnan(args
[1]->toNumber(exec
)) 
 438         || (numArgs 
>= 3 && isnan(args
[2]->toNumber(exec
))) 
 439         || (numArgs 
>= 4 && isnan(args
[3]->toNumber(exec
))) 
 440         || (numArgs 
>= 5 && isnan(args
[4]->toNumber(exec
))) 
 441         || (numArgs 
>= 6 && isnan(args
[5]->toNumber(exec
))) 
 442         || (numArgs 
>= 7 && isnan(args
[6]->toNumber(exec
)))) { 
 446       int year 
= args
[0]->toInt32(exec
); 
 447       t
.year 
= (year 
>= 0 && year 
<= 99) ? year 
: year 
- 1900; 
 448       t
.month 
= args
[1]->toInt32(exec
); 
 449       t
.monthDay 
= (numArgs 
>= 3) ? args
[2]->toInt32(exec
) : 1; 
 450       t
.hour 
= args
[3]->toInt32(exec
); 
 451       t
.minute 
= args
[4]->toInt32(exec
); 
 452       t
.second 
= args
[5]->toInt32(exec
); 
 454       double ms 
= (numArgs 
>= 7) ? args
[6]->toNumber(exec
) : 0; 
 455       value 
= gregorianDateTimeToMS(t
, ms
, false); 
 459   DateInstance 
*ret 
= new DateInstance(exec
->lexicalGlobalObject()->datePrototype()); 
 460   ret
->setInternalValue(jsNumber(timeClip(value
))); 
 465 JSValue 
*DateObjectImp::callAsFunction(ExecState 
* /*exec*/, JSObject 
* /*thisObj*/, const List 
&/*args*/) 
 468     GregorianDateTime 
ts(*localtime(&t
)); 
 469     return jsString(formatDate(ts
) + " " + formatTime(ts
, false)); 
 472 // ------------------------------ DateObjectFuncImp ---------------------------- 
 474 DateObjectFuncImp::DateObjectFuncImp(ExecState
* exec
, FunctionPrototype
* funcProto
, int i
, int len
, const Identifier
& name
) 
 475     : InternalFunctionImp(funcProto
, name
), id(i
) 
 477     putDirect(exec
->propertyNames().length
, len
, DontDelete
|ReadOnly
|DontEnum
); 
 481 JSValue 
*DateObjectFuncImp::callAsFunction(ExecState
* exec
, JSObject
*, const List
& args
) 
 484     return jsNumber(parseDate(args
[0]->toString(exec
))); 
 488     if (isnan(args
[0]->toNumber(exec
)) 
 489         || isnan(args
[1]->toNumber(exec
)) 
 490         || (n 
>= 3 && isnan(args
[2]->toNumber(exec
))) 
 491         || (n 
>= 4 && isnan(args
[3]->toNumber(exec
))) 
 492         || (n 
>= 5 && isnan(args
[4]->toNumber(exec
))) 
 493         || (n 
>= 6 && isnan(args
[5]->toNumber(exec
))) 
 494         || (n 
>= 7 && isnan(args
[6]->toNumber(exec
)))) { 
 499     memset(&t
, 0, sizeof(t
)); 
 500     int year 
= args
[0]->toInt32(exec
); 
 501     t
.year 
= (year 
>= 0 && year 
<= 99) ? year 
: year 
- 1900; 
 502     t
.month 
= args
[1]->toInt32(exec
); 
 503     t
.monthDay 
= (n 
>= 3) ? args
[2]->toInt32(exec
) : 1; 
 504     t
.hour 
= args
[3]->toInt32(exec
); 
 505     t
.minute 
= args
[4]->toInt32(exec
); 
 506     t
.second 
= args
[5]->toInt32(exec
); 
 507     double ms 
= (n 
>= 7) ? args
[6]->toNumber(exec
) : 0; 
 508     return jsNumber(gregorianDateTimeToMS(t
, ms
, true)); 
 512 // ----------------------------------------------------------------------------- 
 514 // Code originally from krfcdate.cpp, but we don't want to use kdecore, and we want double range. 
 516 static inline double ymdhmsToSeconds(long year
, int mon
, int day
, int hour
, int minute
, int second
) 
 518     double days 
= (day 
- 32075) 
 519         + floor(1461 * (year 
+ 4800.0 + (mon 
- 14) / 12) / 4) 
 520         + 367 * (mon 
- 2 - (mon 
- 14) / 12 * 12) / 12 
 521         - floor(3 * ((year 
+ 4900.0 + (mon 
- 14) / 12) / 100) / 4) 
 523     return ((days 
* hoursPerDay 
+ hour
) * minutesPerHour 
+ minute
) * secondsPerMinute 
+ second
; 
 526 // We follow the recommendation of RFC 2822 to consider all 
 527 // obsolete time zones not listed here equivalent to "-0000". 
 528 static const struct KnownZone 
{ 
 529 #if !PLATFORM(WIN_OS) 
 547 inline static void skipSpacesAndComments(const char*& s
) 
 552         if (!isASCIISpace(ch
)) { 
 555             else if (ch 
== ')' && nesting 
> 0) 
 557             else if (nesting 
== 0) 
 564 // returns 0-11 (Jan-Dec); -1 on failure 
 565 static int findMonth(const char* monthStr
) 
 569     for (int i 
= 0; i 
< 3; ++i
) { 
 572         needle
[i
] = static_cast<char>(toASCIILower(*monthStr
++)); 
 575     const char *haystack 
= "janfebmaraprmayjunjulaugsepoctnovdec"; 
 576     const char *str 
= strstr(haystack
, needle
); 
 578         int position 
= static_cast<int>(str 
- haystack
); 
 579         if (position 
% 3 == 0) 
 585 static double parseDate(const UString 
&date
) 
 587     // This parses a date in the form: 
 588     //     Tuesday, 09-Nov-99 23:12:40 GMT 
 590     //     Sat, 01-Jan-2000 08:00:00 GMT 
 592     //     Sat, 01 Jan 2000 08:00:00 GMT 
 594     //     01 Jan 99 22:00 +0100    (exceptions in rfc822/rfc2822) 
 595     // ### non RFC formats, added for Javascript: 
 596     //     [Wednesday] January 09 1999 23:12:40 GMT 
 597     //     [Wednesday] January 09 23:12:40 GMT 1999 
 599     // We ignore the weekday. 
 601     CString dateCString 
= date
.UTF8String(); 
 602     const char *dateString 
= dateCString
.c_str(); 
 604     // Skip leading space 
 605     skipSpacesAndComments(dateString
); 
 608     const char *wordStart 
= dateString
; 
 609     // Check contents of first words if not number 
 610     while (*dateString 
&& !isASCIIDigit(*dateString
)) { 
 611         if (isASCIISpace(*dateString
) || *dateString 
== '(') { 
 612             if (dateString 
- wordStart 
>= 3) 
 613                 month 
= findMonth(wordStart
); 
 614             skipSpacesAndComments(dateString
); 
 615             wordStart 
= dateString
; 
 620     // Missing delimiter between month and day (like "January29")? 
 621     if (month 
== -1 && wordStart 
!= dateString
) 
 622         month 
= findMonth(wordStart
); 
 624     skipSpacesAndComments(dateString
); 
 629     // ' 09-Nov-99 23:12:40 GMT' 
 632     long day 
= strtol(dateString
, &newPosStr
, 10); 
 635     dateString 
= newPosStr
; 
 645         // ### where is the boundary and what happens below? 
 646         if (*dateString 
!= '/') 
 648         // looks like a YYYY/MM/DD date 
 652         month 
= strtol(dateString
, &newPosStr
, 10) - 1; 
 655         dateString 
= newPosStr
; 
 656         if (*dateString
++ != '/' || !*dateString
) 
 658         day 
= strtol(dateString
, &newPosStr
, 10); 
 661         dateString 
= newPosStr
; 
 662     } else if (*dateString 
== '/' && month 
== -1) { 
 664         // This looks like a MM/DD/YYYY date, not an RFC date. 
 665         month 
= day 
- 1; // 0-based 
 666         day 
= strtol(dateString
, &newPosStr
, 10); 
 669         if (day 
< 1 || day 
> 31) 
 671         dateString 
= newPosStr
; 
 672         if (*dateString 
== '/') 
 677         if (*dateString 
== '-') 
 680         skipSpacesAndComments(dateString
); 
 682         if (*dateString 
== ',') 
 685         if (month 
== -1) { // not found yet 
 686             month 
= findMonth(dateString
); 
 690             while (*dateString 
&& *dateString 
!= '-' && *dateString 
!= ',' && !isASCIISpace(*dateString
)) 
 696             // '-99 23:12:40 GMT' 
 697             if (*dateString 
!= '-' && *dateString 
!= '/' && *dateString 
!= ',' && !isASCIISpace(*dateString
)) 
 703     if (month 
< 0 || month 
> 11) 
 707     if (year 
<= 0 && *dateString
) { 
 708         year 
= strtol(dateString
, &newPosStr
, 10); 
 713     // Don't fail if the time is missing. 
 718         dateString 
= newPosStr
; 
 721         if (!(isASCIISpace(*newPosStr
) || *newPosStr 
== ',')) { 
 722             if (*newPosStr 
!= ':') 
 724             // There was no year; the number was the hour. 
 727             // in the normal case (we parsed the year), advance to the next number 
 728             dateString 
= ++newPosStr
; 
 729             skipSpacesAndComments(dateString
); 
 732         hour 
= strtol(dateString
, &newPosStr
, 10); 
 733         // Do not check for errno here since we want to continue 
 734         // even if errno was set becasue we are still looking 
 737         // Read a number? If not, this might be a timezone name. 
 738         if (newPosStr 
!= dateString
) { 
 739             dateString 
= newPosStr
; 
 741             if (hour 
< 0 || hour 
> 23) 
 748             if (*dateString
++ != ':') 
 751             minute 
= strtol(dateString
, &newPosStr
, 10); 
 754             dateString 
= newPosStr
; 
 756             if (minute 
< 0 || minute 
> 59) 
 760             if (*dateString 
&& *dateString 
!= ':' && !isASCIISpace(*dateString
)) 
 763             // seconds are optional in rfc822 + rfc2822 
 764             if (*dateString 
==':') { 
 767                 second 
= strtol(dateString
, &newPosStr
, 10); 
 770                 dateString 
= newPosStr
; 
 772                 if (second 
< 0 || second 
> 59) 
 776             skipSpacesAndComments(dateString
); 
 778             if (strncasecmp(dateString
, "AM", 2) == 0) { 
 784                 skipSpacesAndComments(dateString
); 
 785             } else if (strncasecmp(dateString
, "PM", 2) == 0) { 
 791                 skipSpacesAndComments(dateString
); 
 799     // Don't fail if the time zone is missing.  
 800     // Some websites omit the time zone (4275206). 
 802         if (strncasecmp(dateString
, "GMT", 3) == 0 || strncasecmp(dateString
, "UTC", 3) == 0) { 
 807         if (*dateString 
== '+' || *dateString 
== '-') { 
 808             long o 
= strtol(dateString
, &newPosStr
, 10); 
 811             dateString 
= newPosStr
; 
 813             if (o 
< -9959 || o 
> 9959) 
 816             int sgn 
= (o 
< 0) ? -1 : 1; 
 818             if (*dateString 
!= ':') { 
 819                 offset 
= ((o 
/ 100) * 60 + (o 
% 100)) * sgn
; 
 820             } else { // GMT+05:00 
 821                 long o2 
= strtol(dateString
, &newPosStr
, 10); 
 824                 dateString 
= newPosStr
; 
 825                 offset 
= (o 
* 60 + o2
) * sgn
; 
 829             for (int i 
= 0; i 
< int(sizeof(known_zones
) / sizeof(KnownZone
)); i
++) { 
 830                 if (0 == strncasecmp(dateString
, known_zones
[i
].tzName
, strlen(known_zones
[i
].tzName
))) { 
 831                     offset 
= known_zones
[i
].tzOffset
; 
 832                     dateString 
+= strlen(known_zones
[i
].tzName
); 
 840     skipSpacesAndComments(dateString
); 
 842     if (*dateString 
&& year 
== -1) { 
 843         year 
= strtol(dateString
, &newPosStr
, 10); 
 846         dateString 
= newPosStr
; 
 849     skipSpacesAndComments(dateString
); 
 855     // Y2K: Handle 2 digit years. 
 856     if (year 
>= 0 && year 
< 100) { 
 863     // fall back to local timezone 
 866         memset(&t
, 0, sizeof(tm
)); 
 869         t
.year 
= year 
- 1900; 
 875         // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range. 
 876         return gregorianDateTimeToMS(t
, 0, false); 
 879     return (ymdhmsToSeconds(year
, month 
+ 1, day
, hour
, minute
, second
) - (offset 
* 60.0)) * msPerSecond
; 
 882 double timeClip(double t
) 
 886     if (fabs(t
) > 8.64E15
) 
 893 JSValue
* dateProtoFuncToString(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
 895     if (!thisObj
->inherits(&DateInstance::info
)) 
 896         return throwError(exec
, TypeError
); 
 898     const bool utc 
= false; 
 900     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
 901     JSValue
* v 
= thisDateObj
->internalValue(); 
 902     double milli 
= v
->toNumber(exec
); 
 904         return jsString("Invalid Date"); 
 907     msToGregorianDateTime(milli
, utc
, t
); 
 908     return jsString(formatDate(t
) + " " + formatTime(t
, utc
)); 
 911 JSValue
* dateProtoFuncToUTCString(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
 913     if (!thisObj
->inherits(&DateInstance::info
)) 
 914         return throwError(exec
, TypeError
); 
 916     const bool utc 
= true; 
 918     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
 919     JSValue
* v 
= thisDateObj
->internalValue(); 
 920     double milli 
= v
->toNumber(exec
); 
 922         return jsString("Invalid Date"); 
 925     msToGregorianDateTime(milli
, utc
, t
); 
 926     return jsString(formatDateUTCVariant(t
) + " " + formatTime(t
, utc
)); 
 929 JSValue
* dateProtoFuncToDateString(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
 931     if (!thisObj
->inherits(&DateInstance::info
)) 
 932         return throwError(exec
, TypeError
); 
 934     const bool utc 
= false; 
 936     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
 937     JSValue
* v 
= thisDateObj
->internalValue(); 
 938     double milli 
= v
->toNumber(exec
); 
 940         return jsString("Invalid Date"); 
 943     msToGregorianDateTime(milli
, utc
, t
); 
 944     return jsString(formatDate(t
)); 
 947 JSValue
* dateProtoFuncToTimeString(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
 949     if (!thisObj
->inherits(&DateInstance::info
)) 
 950         return throwError(exec
, TypeError
); 
 952     const bool utc 
= false; 
 954     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
 955     JSValue
* v 
= thisDateObj
->internalValue(); 
 956     double milli 
= v
->toNumber(exec
); 
 958         return jsString("Invalid Date"); 
 961     msToGregorianDateTime(milli
, utc
, t
); 
 962     return jsString(formatTime(t
, utc
)); 
 965 JSValue
* dateProtoFuncToLocaleString(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
 967     if (!thisObj
->inherits(&DateInstance::info
)) 
 968         return throwError(exec
, TypeError
); 
 970     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
 971     JSValue
* v 
= thisDateObj
->internalValue(); 
 972     double milli 
= v
->toNumber(exec
); 
 974         return jsString("Invalid Date"); 
 976     double secs 
= floor(milli 
/ msPerSecond
); 
 977     return jsString(formatLocaleDate(exec
, secs
, true, true, args
)); 
 980 JSValue
* dateProtoFuncToLocaleDateString(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
 982     if (!thisObj
->inherits(&DateInstance::info
)) 
 983         return throwError(exec
, TypeError
); 
 985     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
 986     JSValue
* v 
= thisDateObj
->internalValue(); 
 987     double milli 
= v
->toNumber(exec
); 
 989         return jsString("Invalid Date"); 
 991     double secs 
= floor(milli 
/ msPerSecond
); 
 992     return jsString(formatLocaleDate(exec
, secs
, true, false, args
)); 
 995 JSValue
* dateProtoFuncToLocaleTimeString(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
 997     if (!thisObj
->inherits(&DateInstance::info
)) 
 998         return throwError(exec
, TypeError
); 
1000     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1001     JSValue
* v 
= thisDateObj
->internalValue(); 
1002     double milli 
= v
->toNumber(exec
); 
1004         return jsString("Invalid Date"); 
1006     double secs 
= floor(milli 
/ msPerSecond
); 
1007     return jsString(formatLocaleDate(exec
, secs
, false, true, args
)); 
1010 JSValue
* dateProtoFuncValueOf(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1012     if (!thisObj
->inherits(&DateInstance::info
)) 
1013         return throwError(exec
, TypeError
); 
1015     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1016     JSValue
* v 
= thisDateObj
->internalValue(); 
1017     double milli 
= v
->toNumber(exec
); 
1021     return jsNumber(milli
); 
1024 JSValue
* dateProtoFuncGetTime(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1026     if (!thisObj
->inherits(&DateInstance::info
)) 
1027         return throwError(exec
, TypeError
); 
1029     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1030     JSValue
* v 
= thisDateObj
->internalValue(); 
1031     double milli 
= v
->toNumber(exec
); 
1035     return jsNumber(milli
); 
1038 JSValue
* dateProtoFuncGetFullYear(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1040     if (!thisObj
->inherits(&DateInstance::info
)) 
1041         return throwError(exec
, TypeError
); 
1043     const bool utc 
= false; 
1045     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1046     JSValue
* v 
= thisDateObj
->internalValue(); 
1047     double milli 
= v
->toNumber(exec
); 
1051     GregorianDateTime t
; 
1052     msToGregorianDateTime(milli
, utc
, t
); 
1053     return jsNumber(1900 + t
.year
); 
1056 JSValue
* dateProtoFuncGetUTCFullYear(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1058     if (!thisObj
->inherits(&DateInstance::info
)) 
1059         return throwError(exec
, TypeError
); 
1061     const bool utc 
= true; 
1063     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1064     JSValue
* v 
= thisDateObj
->internalValue(); 
1065     double milli 
= v
->toNumber(exec
); 
1069     GregorianDateTime t
; 
1070     msToGregorianDateTime(milli
, utc
, t
); 
1071     return jsNumber(1900 + t
.year
); 
1074 JSValue
* dateProtoFuncToGMTString(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1076     if (!thisObj
->inherits(&DateInstance::info
)) 
1077         return throwError(exec
, TypeError
); 
1079     const bool utc 
= true; 
1081     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1082     JSValue
* v 
= thisDateObj
->internalValue(); 
1083     double milli 
= v
->toNumber(exec
); 
1085         return jsString("Invalid Date"); 
1087     GregorianDateTime t
; 
1088     msToGregorianDateTime(milli
, utc
, t
); 
1089     return jsString(formatDateUTCVariant(t
) + " " + formatTime(t
, utc
)); 
1092 JSValue
* dateProtoFuncGetMonth(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1094     if (!thisObj
->inherits(&DateInstance::info
)) 
1095         return throwError(exec
, TypeError
); 
1097     const bool utc 
= false; 
1099     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1100     JSValue
* v 
= thisDateObj
->internalValue(); 
1101     double milli 
= v
->toNumber(exec
); 
1105     GregorianDateTime t
; 
1106     msToGregorianDateTime(milli
, utc
, t
); 
1107     return jsNumber(t
.month
); 
1110 JSValue
* dateProtoFuncGetUTCMonth(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1112     if (!thisObj
->inherits(&DateInstance::info
)) 
1113         return throwError(exec
, TypeError
); 
1115     const bool utc 
= true; 
1117     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1118     JSValue
* v 
= thisDateObj
->internalValue(); 
1119     double milli 
= v
->toNumber(exec
); 
1123     GregorianDateTime t
; 
1124     msToGregorianDateTime(milli
, utc
, t
); 
1125     return jsNumber(t
.month
); 
1128 JSValue
* dateProtoFuncGetDate(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1130     if (!thisObj
->inherits(&DateInstance::info
)) 
1131         return throwError(exec
, TypeError
); 
1133     const bool utc 
= false; 
1135     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1136     JSValue
* v 
= thisDateObj
->internalValue(); 
1137     double milli 
= v
->toNumber(exec
); 
1141     GregorianDateTime t
; 
1142     msToGregorianDateTime(milli
, utc
, t
); 
1143     return jsNumber(t
.monthDay
); 
1146 JSValue
* dateProtoFuncGetUTCDate(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1148     if (!thisObj
->inherits(&DateInstance::info
)) 
1149         return throwError(exec
, TypeError
); 
1151     const bool utc 
= true; 
1153     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1154     JSValue
* v 
= thisDateObj
->internalValue(); 
1155     double milli 
= v
->toNumber(exec
); 
1159     GregorianDateTime t
; 
1160     msToGregorianDateTime(milli
, utc
, t
); 
1161     return jsNumber(t
.monthDay
); 
1164 JSValue
* dateProtoFuncGetDay(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1166     if (!thisObj
->inherits(&DateInstance::info
)) 
1167         return throwError(exec
, TypeError
); 
1169     const bool utc 
= false; 
1171     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1172     JSValue
* v 
= thisDateObj
->internalValue(); 
1173     double milli 
= v
->toNumber(exec
); 
1177     GregorianDateTime t
; 
1178     msToGregorianDateTime(milli
, utc
, t
); 
1179     return jsNumber(t
.weekDay
); 
1182 JSValue
* dateProtoFuncGetUTCDay(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1184     if (!thisObj
->inherits(&DateInstance::info
)) 
1185         return throwError(exec
, TypeError
); 
1187     const bool utc 
= true; 
1189     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1190     JSValue
* v 
= thisDateObj
->internalValue(); 
1191     double milli 
= v
->toNumber(exec
); 
1195     GregorianDateTime t
; 
1196     msToGregorianDateTime(milli
, utc
, t
); 
1197     return jsNumber(t
.weekDay
); 
1200 JSValue
* dateProtoFuncGetHours(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1202     if (!thisObj
->inherits(&DateInstance::info
)) 
1203         return throwError(exec
, TypeError
); 
1205     const bool utc 
= false; 
1207     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1208     JSValue
* v 
= thisDateObj
->internalValue(); 
1209     double milli 
= v
->toNumber(exec
); 
1213     GregorianDateTime t
; 
1214     msToGregorianDateTime(milli
, utc
, t
); 
1215     return jsNumber(t
.hour
); 
1218 JSValue
* dateProtoFuncGetUTCHours(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1220     if (!thisObj
->inherits(&DateInstance::info
)) 
1221         return throwError(exec
, TypeError
); 
1223     const bool utc 
= true; 
1225     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1226     JSValue
* v 
= thisDateObj
->internalValue(); 
1227     double milli 
= v
->toNumber(exec
); 
1231     GregorianDateTime t
; 
1232     msToGregorianDateTime(milli
, utc
, t
); 
1233     return jsNumber(t
.hour
); 
1236 JSValue
* dateProtoFuncGetMinutes(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1238     if (!thisObj
->inherits(&DateInstance::info
)) 
1239         return throwError(exec
, TypeError
); 
1241     const bool utc 
= false; 
1243     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1244     JSValue
* v 
= thisDateObj
->internalValue(); 
1245     double milli 
= v
->toNumber(exec
); 
1249     GregorianDateTime t
; 
1250     msToGregorianDateTime(milli
, utc
, t
); 
1251     return jsNumber(t
.minute
); 
1254 JSValue
* dateProtoFuncGetUTCMinutes(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1256     if (!thisObj
->inherits(&DateInstance::info
)) 
1257         return throwError(exec
, TypeError
); 
1259     const bool utc 
= true; 
1261     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1262     JSValue
* v 
= thisDateObj
->internalValue(); 
1263     double milli 
= v
->toNumber(exec
); 
1267     GregorianDateTime t
; 
1268     msToGregorianDateTime(milli
, utc
, t
); 
1269     return jsNumber(t
.minute
); 
1272 JSValue
* dateProtoFuncGetSeconds(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1274     if (!thisObj
->inherits(&DateInstance::info
)) 
1275         return throwError(exec
, TypeError
); 
1277     const bool utc 
= false; 
1279     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1280     JSValue
* v 
= thisDateObj
->internalValue(); 
1281     double milli 
= v
->toNumber(exec
); 
1285     GregorianDateTime t
; 
1286     msToGregorianDateTime(milli
, utc
, t
); 
1287     return jsNumber(t
.second
); 
1290 JSValue
* dateProtoFuncGetUTCSeconds(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1292     if (!thisObj
->inherits(&DateInstance::info
)) 
1293         return throwError(exec
, TypeError
); 
1295     const bool utc 
= true; 
1297     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1298     JSValue
* v 
= thisDateObj
->internalValue(); 
1299     double milli 
= v
->toNumber(exec
); 
1303     GregorianDateTime t
; 
1304     msToGregorianDateTime(milli
, utc
, t
); 
1305     return jsNumber(t
.second
); 
1308 JSValue
* dateProtoFuncGetMilliSeconds(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1310     if (!thisObj
->inherits(&DateInstance::info
)) 
1311         return throwError(exec
, TypeError
); 
1313     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1314     JSValue
* v 
= thisDateObj
->internalValue(); 
1315     double milli 
= v
->toNumber(exec
); 
1319     double secs 
= floor(milli 
/ msPerSecond
); 
1320     double ms 
= milli 
- secs 
* msPerSecond
; 
1321     return jsNumber(ms
); 
1324 JSValue
* dateProtoFuncGetUTCMilliseconds(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1326     if (!thisObj
->inherits(&DateInstance::info
)) 
1327         return throwError(exec
, TypeError
); 
1329     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1330     JSValue
* v 
= thisDateObj
->internalValue(); 
1331     double milli 
= v
->toNumber(exec
); 
1335     double secs 
= floor(milli 
/ msPerSecond
); 
1336     double ms 
= milli 
- secs 
* msPerSecond
; 
1337     return jsNumber(ms
); 
1340 JSValue
* dateProtoFuncGetTimezoneOffset(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1342     if (!thisObj
->inherits(&DateInstance::info
)) 
1343         return throwError(exec
, TypeError
); 
1345     const bool utc 
= false; 
1347     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1348     JSValue
* v 
= thisDateObj
->internalValue(); 
1349     double milli 
= v
->toNumber(exec
); 
1353     GregorianDateTime t
; 
1354     msToGregorianDateTime(milli
, utc
, t
); 
1355     return jsNumber(-gmtoffset(t
) / minutesPerHour
); 
1358 JSValue
* dateProtoFuncSetTime(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1360     if (!thisObj
->inherits(&DateInstance::info
)) 
1361         return throwError(exec
, TypeError
); 
1363     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1365     double milli 
= timeClip(args
[0]->toNumber(exec
)); 
1366     JSValue
* result 
= jsNumber(milli
); 
1367     thisDateObj
->setInternalValue(result
); 
1371 static JSValue
* setNewValueFromTimeArgs(ExecState
* exec
, JSObject
* thisObj
, const List
& args
, int numArgsToUse
, bool inputIsUTC
) 
1373     if (!thisObj
->inherits(&DateInstance::info
)) 
1374         return throwError(exec
, TypeError
); 
1376     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
); 
1377     JSValue
* v 
= thisDateObj
->internalValue(); 
1378     double milli 
= v
->toNumber(exec
); 
1379     double secs 
= floor(milli 
/ msPerSecond
); 
1380     double ms 
= milli 
- secs 
* msPerSecond
; 
1382     GregorianDateTime t
; 
1383     msToGregorianDateTime(milli
, inputIsUTC
, t
); 
1385     fillStructuresUsingTimeArgs(exec
, args
, numArgsToUse
, &ms
, &t
); 
1387     JSValue
* result 
= jsNumber(gregorianDateTimeToMS(t
, ms
, inputIsUTC
)); 
1388     thisDateObj
->setInternalValue(result
); 
1392 static JSValue
* setNewValueFromDateArgs(ExecState
* exec
, JSObject
* thisObj
, const List
& args
, int numArgsToUse
, bool inputIsUTC
) 
1394     if (!thisObj
->inherits(&DateInstance::info
)) 
1395         return throwError(exec
, TypeError
); 
1397     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
); 
1398     JSValue
* v 
= thisDateObj
->internalValue(); 
1399     double milli 
= v
->toNumber(exec
); 
1400     double secs 
= floor(milli 
/ msPerSecond
); 
1401     double ms 
= milli 
- secs 
* msPerSecond
; 
1403     GregorianDateTime t
; 
1404     msToGregorianDateTime(milli
, inputIsUTC
, t
); 
1406     fillStructuresUsingDateArgs(exec
, args
, numArgsToUse
, &ms
, &t
); 
1408     JSValue
* result 
= jsNumber(gregorianDateTimeToMS(t
, ms
, inputIsUTC
)); 
1409     thisDateObj
->setInternalValue(result
); 
1413 JSValue
* dateProtoFuncSetMilliSeconds(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1415     const bool inputIsUTC 
= false; 
1416     return setNewValueFromTimeArgs(exec
, thisObj
, args
, 1, inputIsUTC
); 
1419 JSValue
* dateProtoFuncSetUTCMilliseconds(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1421     const bool inputIsUTC 
= true; 
1422     return setNewValueFromTimeArgs(exec
, thisObj
, args
, 1, inputIsUTC
); 
1425 JSValue
* dateProtoFuncSetSeconds(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1427     const bool inputIsUTC 
= false; 
1428     return setNewValueFromTimeArgs(exec
, thisObj
, args
, 2, inputIsUTC
); 
1431 JSValue
* dateProtoFuncSetUTCSeconds(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1433     const bool inputIsUTC 
= true; 
1434     return setNewValueFromTimeArgs(exec
, thisObj
, args
, 2, inputIsUTC
); 
1437 JSValue
* dateProtoFuncSetMinutes(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1439     const bool inputIsUTC 
= false; 
1440     return setNewValueFromTimeArgs(exec
, thisObj
, args
, 3, inputIsUTC
); 
1443 JSValue
* dateProtoFuncSetUTCMinutes(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1445     const bool inputIsUTC 
= true; 
1446     return setNewValueFromTimeArgs(exec
, thisObj
, args
, 3, inputIsUTC
); 
1449 JSValue
* dateProtoFuncSetHours(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1451     const bool inputIsUTC 
= false; 
1452     return setNewValueFromTimeArgs(exec
, thisObj
, args
, 4, inputIsUTC
); 
1455 JSValue
* dateProtoFuncSetUTCHours(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1457     const bool inputIsUTC 
= true; 
1458     return setNewValueFromTimeArgs(exec
, thisObj
, args
, 4, inputIsUTC
); 
1461 JSValue
* dateProtoFuncSetDate(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1463     const bool inputIsUTC 
= false; 
1464     return setNewValueFromDateArgs(exec
, thisObj
, args
, 1, inputIsUTC
); 
1467 JSValue
* dateProtoFuncSetUTCDate(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1469     const bool inputIsUTC 
= true; 
1470     return setNewValueFromDateArgs(exec
, thisObj
, args
, 1, inputIsUTC
); 
1473 JSValue
* dateProtoFuncSetMonth(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1475     const bool inputIsUTC 
= false; 
1476     return setNewValueFromDateArgs(exec
, thisObj
, args
, 2, inputIsUTC
); 
1479 JSValue
* dateProtoFuncSetUTCMonth(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1481     const bool inputIsUTC 
= true; 
1482     return setNewValueFromDateArgs(exec
, thisObj
, args
, 2, inputIsUTC
); 
1485 JSValue
* dateProtoFuncSetFullYear(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1487     const bool inputIsUTC 
= false; 
1488     return setNewValueFromDateArgs(exec
, thisObj
, args
, 3, inputIsUTC
); 
1491 JSValue
* dateProtoFuncSetUTCFullYear(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1493     const bool inputIsUTC 
= true; 
1494     return setNewValueFromDateArgs(exec
, thisObj
, args
, 3, inputIsUTC
); 
1497 JSValue
* dateProtoFuncSetYear(ExecState
* exec
, JSObject
* thisObj
, const List
& args
) 
1499     if (!thisObj
->inherits(&DateInstance::info
)) 
1500         return throwError(exec
, TypeError
); 
1502     const bool utc 
= false; 
1504     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1505     JSValue
* v 
= thisDateObj
->internalValue(); 
1506     double milli 
= v
->toNumber(exec
); 
1507     double secs 
= floor(milli 
/ msPerSecond
); 
1508     double ms 
= milli 
- secs 
* msPerSecond
; 
1510     GregorianDateTime t
; 
1511     msToGregorianDateTime(milli
, utc
, t
); 
1513     t
.year 
= (args
[0]->toInt32(exec
) > 99 || args
[0]->toInt32(exec
) < 0) ? args
[0]->toInt32(exec
) - 1900 : args
[0]->toInt32(exec
); 
1515     JSValue
* result 
= jsNumber(gregorianDateTimeToMS(t
, ms
, utc
)); 
1516     thisDateObj
->setInternalValue(result
); 
1520 JSValue
* dateProtoFuncGetYear(ExecState
* exec
, JSObject
* thisObj
, const List
&) 
1522     if (!thisObj
->inherits(&DateInstance::info
)) 
1523         return throwError(exec
, TypeError
); 
1525     const bool utc 
= false; 
1527     DateInstance
* thisDateObj 
= static_cast<DateInstance
*>(thisObj
);  
1528     JSValue
* v 
= thisDateObj
->internalValue(); 
1529     double milli 
= v
->toNumber(exec
); 
1533     GregorianDateTime t
; 
1534     msToGregorianDateTime(milli
, utc
, t
); 
1536     // IE returns the full year even in getYear. 
1537     if (exec
->dynamicGlobalObject()->compatMode() == IECompat
) 
1538         return jsNumber(1900 + t
.year
); 
1539     return jsNumber(t
.year
);