1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 // -------------------------------------------------------------------
9 (function(global, utils) {
13 %CheckIsBootstrapping();
15 // -------------------------------------------------------------------
18 var GlobalDate = global.Date;
19 var InternalArray = utils.InternalArray;
24 var toPrimitiveSymbol = utils.ImportNow("to_primitive_symbol");
27 utils.Import(function(from) {
28 IsFinite = from.IsFinite;
29 MathAbs = from.MathAbs;
30 MathFloor = from.MathFloor;
31 ToNumber = from.ToNumber;
32 ToString = from.ToString;
35 // -------------------------------------------------------------------
37 // This file contains date support implemented in JavaScript.
39 var timezone_cache_time = NAN;
40 var timezone_cache_timezone;
42 function LocalTimezone(t) {
43 if (NUMBER_IS_NAN(t)) return "";
44 CheckDateCacheCurrent();
45 if (t == timezone_cache_time) {
46 return timezone_cache_timezone;
48 var timezone = %DateLocalTimezone(t);
49 timezone_cache_time = t;
50 timezone_cache_timezone = timezone;
56 if (NUMBER_IS_NAN(time)) return time;
57 // local_time_offset is needed before the call to DaylightSavingsOffset,
58 // so it may be uninitialized.
59 return %DateToUTC(time);
63 // ECMA 262 - 15.9.1.11
64 function MakeTime(hour, min, sec, ms) {
65 if (!IsFinite(hour)) return NAN;
66 if (!IsFinite(min)) return NAN;
67 if (!IsFinite(sec)) return NAN;
68 if (!IsFinite(ms)) return NAN;
69 return TO_INTEGER(hour) * msPerHour
70 + TO_INTEGER(min) * msPerMinute
71 + TO_INTEGER(sec) * msPerSecond
76 // ECMA 262 - 15.9.1.12
77 function TimeInYear(year) {
78 return DaysInYear(year) * msPerDay;
82 // Compute number of days given a year, month, date.
83 // Note that month and date can lie outside the normal range.
85 // MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
86 // MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
87 // MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
88 function MakeDay(year, month, date) {
89 if (!IsFinite(year) || !IsFinite(month) || !IsFinite(date)) return NAN;
91 // Convert to integer and map -0 to 0.
92 year = TO_INTEGER_MAP_MINUS_ZERO(year);
93 month = TO_INTEGER_MAP_MINUS_ZERO(month);
94 date = TO_INTEGER_MAP_MINUS_ZERO(date);
96 if (year < kMinYear || year > kMaxYear ||
97 month < kMinMonth || month > kMaxMonth) {
101 // Now we rely on year and month being SMIs.
102 return %DateMakeDay(year | 0, month | 0) + date - 1;
106 // ECMA 262 - 15.9.1.13
107 function MakeDate(day, time) {
108 var time = day * msPerDay + time;
109 // Some of our runtime funtions for computing UTC(time) rely on
110 // times not being significantly larger than MAX_TIME_MS. If there
111 // is no way that the time can be within range even after UTC
112 // conversion we return NaN immediately instead of relying on
113 // TimeClip to do it.
114 if (MathAbs(time) > MAX_TIME_BEFORE_UTC) return NAN;
119 // ECMA 262 - 15.9.1.14
120 function TimeClip(time) {
121 if (!IsFinite(time)) return NAN;
122 if (MathAbs(time) > MAX_TIME_MS) return NAN;
123 return TO_INTEGER(time);
127 // The Date cache is used to limit the cost of parsing the same Date
128 // strings over and over again.
130 // Cached time value.
132 // String input for which the cached time is valid.
137 function DateConstructor(year, month, date, hours, minutes, seconds, ms) {
138 if (!%_IsConstructCall()) {
140 return %_CallFunction(new GlobalDate(), DateToString);
144 var argc = %_ArgumentsLength();
147 value = %DateCurrentTime();
148 SET_UTC_DATE_VALUE(this, value);
149 } else if (argc == 1) {
150 if (IS_NUMBER(year)) {
152 } else if (IS_STRING(year)) {
153 // Probe the Date cache. If we already have a time value for the
154 // given time, we re-use that instead of parsing the string again.
155 CheckDateCacheCurrent();
156 var cache = Date_cache;
157 if (cache.string === year) {
160 value = DateParse(year);
161 if (!NUMBER_IS_NAN(value)) {
168 // According to ECMA 262, no hint should be given for this
169 // conversion. However, ToPrimitive defaults to STRING_HINT for
170 // Date objects which will lose precision when the Date
171 // constructor is called with another Date object as its
172 // argument. We therefore use NUMBER_HINT for the conversion,
173 // which is the default for everything else than Date objects.
174 // This makes us behave like KJS and SpiderMonkey.
175 var time = $toPrimitive(year, NUMBER_HINT);
176 value = IS_STRING(time) ? DateParse(time) : ToNumber(time);
178 SET_UTC_DATE_VALUE(this, value);
180 year = ToNumber(year);
181 month = ToNumber(month);
182 date = argc > 2 ? ToNumber(date) : 1;
183 hours = argc > 3 ? ToNumber(hours) : 0;
184 minutes = argc > 4 ? ToNumber(minutes) : 0;
185 seconds = argc > 5 ? ToNumber(seconds) : 0;
186 ms = argc > 6 ? ToNumber(ms) : 0;
187 year = (!NUMBER_IS_NAN(year) &&
188 0 <= TO_INTEGER(year) &&
189 TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
190 var day = MakeDay(year, month, date);
191 var time = MakeTime(hours, minutes, seconds, ms);
192 value = MakeDate(day, time);
193 SET_LOCAL_DATE_VALUE(this, value);
198 var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
199 var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
200 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
203 function TwoDigitString(value) {
204 return value < 10 ? "0" + value : "" + value;
208 function DateString(date) {
210 return WeekDays[LOCAL_WEEKDAY(date)] + ' '
211 + Months[LOCAL_MONTH(date)] + ' '
212 + TwoDigitString(LOCAL_DAY(date)) + ' '
217 var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
218 'Thursday', 'Friday', 'Saturday'];
219 var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June',
220 'July', 'August', 'September', 'October', 'November', 'December'];
223 function LongDateString(date) {
225 return LongWeekDays[LOCAL_WEEKDAY(date)] + ', '
226 + LongMonths[LOCAL_MONTH(date)] + ' '
227 + TwoDigitString(LOCAL_DAY(date)) + ', '
232 function TimeString(date) {
234 return TwoDigitString(LOCAL_HOUR(date)) + ':'
235 + TwoDigitString(LOCAL_MIN(date)) + ':'
236 + TwoDigitString(LOCAL_SEC(date));
240 function TimeStringUTC(date) {
242 return TwoDigitString(UTC_HOUR(date)) + ':'
243 + TwoDigitString(UTC_MIN(date)) + ':'
244 + TwoDigitString(UTC_SEC(date));
248 function LocalTimezoneString(date) {
250 var timezone = LocalTimezone(UTC_DATE_VALUE(date));
252 var timezoneOffset = -TIMEZONE_OFFSET(date);
253 var sign = (timezoneOffset >= 0) ? 1 : -1;
254 var hours = MathFloor((sign * timezoneOffset)/60);
255 var min = MathFloor((sign * timezoneOffset)%60);
256 var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
257 TwoDigitString(hours) + TwoDigitString(min);
258 return gmt + ' (' + timezone + ')';
262 function DatePrintString(date) {
264 return DateString(date) + ' ' + TimeString(date);
267 // -------------------------------------------------------------------
269 // Reused output buffer. Used when parsing date strings.
270 var parse_buffer = new InternalArray(8);
272 // ECMA 262 - 15.9.4.2
273 function DateParse(string) {
274 var arr = %DateParseString(ToString(string), parse_buffer);
275 if (IS_NULL(arr)) return NAN;
277 var day = MakeDay(arr[0], arr[1], arr[2]);
278 var time = MakeTime(arr[3], arr[4], arr[5], arr[6]);
279 var date = MakeDate(day, time);
281 if (IS_NULL(arr[7])) {
282 return TimeClip(UTC(date));
284 return TimeClip(date - arr[7] * 1000);
289 // ECMA 262 - 15.9.4.3
290 function DateUTC(year, month, date, hours, minutes, seconds, ms) {
291 year = ToNumber(year);
292 month = ToNumber(month);
293 var argc = %_ArgumentsLength();
294 date = argc > 2 ? ToNumber(date) : 1;
295 hours = argc > 3 ? ToNumber(hours) : 0;
296 minutes = argc > 4 ? ToNumber(minutes) : 0;
297 seconds = argc > 5 ? ToNumber(seconds) : 0;
298 ms = argc > 6 ? ToNumber(ms) : 0;
299 year = (!NUMBER_IS_NAN(year) &&
300 0 <= TO_INTEGER(year) &&
301 TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
302 var day = MakeDay(year, month, date);
303 var time = MakeTime(hours, minutes, seconds, ms);
304 return TimeClip(MakeDate(day, time));
308 // ECMA 262 - 15.9.4.4
310 return %DateCurrentTime();
314 // ECMA 262 - 15.9.5.2
315 function DateToString() {
317 var t = UTC_DATE_VALUE(this)
318 if (NUMBER_IS_NAN(t)) return kInvalidDate;
319 var time_zone_string = LocalTimezoneString(this)
320 return DatePrintString(this) + time_zone_string;
324 // ECMA 262 - 15.9.5.3
325 function DateToDateString() {
327 var t = UTC_DATE_VALUE(this);
328 if (NUMBER_IS_NAN(t)) return kInvalidDate;
329 return DateString(this);
333 // ECMA 262 - 15.9.5.4
334 function DateToTimeString() {
336 var t = UTC_DATE_VALUE(this);
337 if (NUMBER_IS_NAN(t)) return kInvalidDate;
338 var time_zone_string = LocalTimezoneString(this);
339 return TimeString(this) + time_zone_string;
343 // ECMA 262 - 15.9.5.5
344 function DateToLocaleString() {
346 return %_CallFunction(this, DateToString);
350 // ECMA 262 - 15.9.5.6
351 function DateToLocaleDateString() {
353 var t = UTC_DATE_VALUE(this);
354 if (NUMBER_IS_NAN(t)) return kInvalidDate;
355 return LongDateString(this);
359 // ECMA 262 - 15.9.5.7
360 function DateToLocaleTimeString() {
362 var t = UTC_DATE_VALUE(this);
363 if (NUMBER_IS_NAN(t)) return kInvalidDate;
364 return TimeString(this);
368 // 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint )
369 function DateToPrimitive(hint) {
370 if (!IS_SPEC_OBJECT(this)) {
371 throw MakeTypeError(kIncompatibleMethodReceiver,
372 "Date.prototype [ @@toPrimitive ]", this);
374 if (hint === "default") {
376 } else if (hint !== "number" && hint !== "string") {
377 throw MakeTypeError(kInvalidHint, hint);
379 return %OrdinaryToPrimitive(this, hint);
383 // ECMA 262 - 15.9.5.8
384 function DateValueOf() {
386 return UTC_DATE_VALUE(this);
390 // ECMA 262 - 15.9.5.9
391 function DateGetTime() {
393 return UTC_DATE_VALUE(this);
397 // ECMA 262 - 15.9.5.10
398 function DateGetFullYear() {
400 return LOCAL_YEAR(this);
404 // ECMA 262 - 15.9.5.11
405 function DateGetUTCFullYear() {
407 return UTC_YEAR(this);
411 // ECMA 262 - 15.9.5.12
412 function DateGetMonth() {
414 return LOCAL_MONTH(this);
418 // ECMA 262 - 15.9.5.13
419 function DateGetUTCMonth() {
421 return UTC_MONTH(this);
425 // ECMA 262 - 15.9.5.14
426 function DateGetDate() {
428 return LOCAL_DAY(this);
432 // ECMA 262 - 15.9.5.15
433 function DateGetUTCDate() {
435 return UTC_DAY(this);
439 // ECMA 262 - 15.9.5.16
440 function DateGetDay() {
442 return LOCAL_WEEKDAY(this);
446 // ECMA 262 - 15.9.5.17
447 function DateGetUTCDay() {
449 return UTC_WEEKDAY(this);
453 // ECMA 262 - 15.9.5.18
454 function DateGetHours() {
456 return LOCAL_HOUR(this);
460 // ECMA 262 - 15.9.5.19
461 function DateGetUTCHours() {
463 return UTC_HOUR(this);
467 // ECMA 262 - 15.9.5.20
468 function DateGetMinutes() {
470 return LOCAL_MIN(this);
474 // ECMA 262 - 15.9.5.21
475 function DateGetUTCMinutes() {
477 return UTC_MIN(this);
481 // ECMA 262 - 15.9.5.22
482 function DateGetSeconds() {
484 return LOCAL_SEC(this);
488 // ECMA 262 - 15.9.5.23
489 function DateGetUTCSeconds() {
495 // ECMA 262 - 15.9.5.24
496 function DateGetMilliseconds() {
498 return LOCAL_MS(this);
502 // ECMA 262 - 15.9.5.25
503 function DateGetUTCMilliseconds() {
509 // ECMA 262 - 15.9.5.26
510 function DateGetTimezoneOffset() {
512 return TIMEZONE_OFFSET(this);
516 // ECMA 262 - 15.9.5.27
517 function DateSetTime(ms) {
519 SET_UTC_DATE_VALUE(this, ToNumber(ms));
520 return UTC_DATE_VALUE(this);
524 // ECMA 262 - 15.9.5.28
525 function DateSetMilliseconds(ms) {
527 var t = LOCAL_DATE_VALUE(this);
529 var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), LOCAL_SEC(this), ms);
530 return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
534 // ECMA 262 - 15.9.5.29
535 function DateSetUTCMilliseconds(ms) {
537 var t = UTC_DATE_VALUE(this);
539 var time = MakeTime(UTC_HOUR(this),
543 return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
547 // ECMA 262 - 15.9.5.30
548 function DateSetSeconds(sec, ms) {
550 var t = LOCAL_DATE_VALUE(this);
552 ms = %_ArgumentsLength() < 2 ? LOCAL_MS(this) : ToNumber(ms);
553 var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), sec, ms);
554 return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
558 // ECMA 262 - 15.9.5.31
559 function DateSetUTCSeconds(sec, ms) {
561 var t = UTC_DATE_VALUE(this);
563 ms = %_ArgumentsLength() < 2 ? UTC_MS(this) : ToNumber(ms);
564 var time = MakeTime(UTC_HOUR(this), UTC_MIN(this), sec, ms);
565 return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
569 // ECMA 262 - 15.9.5.33
570 function DateSetMinutes(min, sec, ms) {
572 var t = LOCAL_DATE_VALUE(this);
574 var argc = %_ArgumentsLength();
575 sec = argc < 2 ? LOCAL_SEC(this) : ToNumber(sec);
576 ms = argc < 3 ? LOCAL_MS(this) : ToNumber(ms);
577 var time = MakeTime(LOCAL_HOUR(this), min, sec, ms);
578 return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
582 // ECMA 262 - 15.9.5.34
583 function DateSetUTCMinutes(min, sec, ms) {
585 var t = UTC_DATE_VALUE(this);
587 var argc = %_ArgumentsLength();
588 sec = argc < 2 ? UTC_SEC(this) : ToNumber(sec);
589 ms = argc < 3 ? UTC_MS(this) : ToNumber(ms);
590 var time = MakeTime(UTC_HOUR(this), min, sec, ms);
591 return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
595 // ECMA 262 - 15.9.5.35
596 function DateSetHours(hour, min, sec, ms) {
598 var t = LOCAL_DATE_VALUE(this);
599 hour = ToNumber(hour);
600 var argc = %_ArgumentsLength();
601 min = argc < 2 ? LOCAL_MIN(this) : ToNumber(min);
602 sec = argc < 3 ? LOCAL_SEC(this) : ToNumber(sec);
603 ms = argc < 4 ? LOCAL_MS(this) : ToNumber(ms);
604 var time = MakeTime(hour, min, sec, ms);
605 return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
609 // ECMA 262 - 15.9.5.34
610 function DateSetUTCHours(hour, min, sec, ms) {
612 var t = UTC_DATE_VALUE(this);
613 hour = ToNumber(hour);
614 var argc = %_ArgumentsLength();
615 min = argc < 2 ? UTC_MIN(this) : ToNumber(min);
616 sec = argc < 3 ? UTC_SEC(this) : ToNumber(sec);
617 ms = argc < 4 ? UTC_MS(this) : ToNumber(ms);
618 var time = MakeTime(hour, min, sec, ms);
619 return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
623 // ECMA 262 - 15.9.5.36
624 function DateSetDate(date) {
626 var t = LOCAL_DATE_VALUE(this);
627 date = ToNumber(date);
628 var day = MakeDay(LOCAL_YEAR(this), LOCAL_MONTH(this), date);
629 return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
633 // ECMA 262 - 15.9.5.37
634 function DateSetUTCDate(date) {
636 var t = UTC_DATE_VALUE(this);
637 date = ToNumber(date);
638 var day = MakeDay(UTC_YEAR(this), UTC_MONTH(this), date);
639 return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
643 // ECMA 262 - 15.9.5.38
644 function DateSetMonth(month, date) {
646 var t = LOCAL_DATE_VALUE(this);
647 month = ToNumber(month);
648 date = %_ArgumentsLength() < 2 ? LOCAL_DAY(this) : ToNumber(date);
649 var day = MakeDay(LOCAL_YEAR(this), month, date);
650 return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
654 // ECMA 262 - 15.9.5.39
655 function DateSetUTCMonth(month, date) {
657 var t = UTC_DATE_VALUE(this);
658 month = ToNumber(month);
659 date = %_ArgumentsLength() < 2 ? UTC_DAY(this) : ToNumber(date);
660 var day = MakeDay(UTC_YEAR(this), month, date);
661 return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
665 // ECMA 262 - 15.9.5.40
666 function DateSetFullYear(year, month, date) {
668 var t = LOCAL_DATE_VALUE(this);
669 year = ToNumber(year);
670 var argc = %_ArgumentsLength();
672 if (NUMBER_IS_NAN(t)) {
673 month = argc < 2 ? 0 : ToNumber(month);
674 date = argc < 3 ? 1 : ToNumber(date);
677 month = argc < 2 ? LOCAL_MONTH(this) : ToNumber(month);
678 date = argc < 3 ? LOCAL_DAY(this) : ToNumber(date);
679 time = LOCAL_TIME_IN_DAY(this);
681 var day = MakeDay(year, month, date);
682 return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
686 // ECMA 262 - 15.9.5.41
687 function DateSetUTCFullYear(year, month, date) {
689 var t = UTC_DATE_VALUE(this);
690 year = ToNumber(year);
691 var argc = %_ArgumentsLength();
693 if (NUMBER_IS_NAN(t)) {
694 month = argc < 2 ? 0 : ToNumber(month);
695 date = argc < 3 ? 1 : ToNumber(date);
698 month = argc < 2 ? UTC_MONTH(this) : ToNumber(month);
699 date = argc < 3 ? UTC_DAY(this) : ToNumber(date);
700 time = UTC_TIME_IN_DAY(this);
702 var day = MakeDay(year, month, date);
703 return SET_UTC_DATE_VALUE(this, MakeDate(day, time));
707 // ECMA 262 - 15.9.5.42
708 function DateToUTCString() {
710 var t = UTC_DATE_VALUE(this);
711 if (NUMBER_IS_NAN(t)) return kInvalidDate;
712 // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
713 return WeekDays[UTC_WEEKDAY(this)] + ', '
714 + TwoDigitString(UTC_DAY(this)) + ' '
715 + Months[UTC_MONTH(this)] + ' '
716 + UTC_YEAR(this) + ' '
717 + TimeStringUTC(this) + ' GMT';
722 function DateGetYear() {
724 return LOCAL_YEAR(this) - 1900;
729 function DateSetYear(year) {
731 year = ToNumber(year);
732 if (NUMBER_IS_NAN(year)) return SET_UTC_DATE_VALUE(this, NAN);
733 year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
734 ? 1900 + TO_INTEGER(year) : year;
735 var t = LOCAL_DATE_VALUE(this);
736 var month, date, time;
737 if (NUMBER_IS_NAN(t)) {
742 month = LOCAL_MONTH(this);
743 date = LOCAL_DAY(this);
744 time = LOCAL_TIME_IN_DAY(this);
746 var day = MakeDay(year, month, date);
747 return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
753 // Notice that this does not follow ECMA 262 completely. ECMA 262
754 // says that toGMTString should be the same Function object as
755 // toUTCString. JSC does not do this, so for compatibility we do not
756 // do that either. Instead, we create a new function whose name
757 // property will return toGMTString.
758 function DateToGMTString() {
759 return %_CallFunction(this, DateToUTCString);
763 function PadInt(n, digits) {
764 if (digits == 1) return n;
765 return n < %_MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
769 // ECMA 262 - 20.3.4.36
770 function DateToISOString() {
772 var t = UTC_DATE_VALUE(this);
773 if (NUMBER_IS_NAN(t)) throw MakeRangeError(kInvalidTimeValue);
774 var year = UTC_YEAR(this);
776 if (year >= 0 && year <= 9999) {
777 year_string = PadInt(year, 4);
780 year_string = "-" + PadInt(-year, 6);
782 year_string = "+" + PadInt(year, 6);
786 '-' + PadInt(UTC_MONTH(this) + 1, 2) +
787 '-' + PadInt(UTC_DAY(this), 2) +
788 'T' + PadInt(UTC_HOUR(this), 2) +
789 ':' + PadInt(UTC_MIN(this), 2) +
790 ':' + PadInt(UTC_SEC(this), 2) +
791 '.' + PadInt(UTC_MS(this), 3) +
796 // 20.3.4.37 Date.prototype.toJSON ( key )
797 function DateToJSON(key) {
798 var o = TO_OBJECT(this);
799 var tv = TO_PRIMITIVE_NUMBER(o);
800 if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
803 return o.toISOString();
807 var date_cache_version_holder;
808 var date_cache_version = NAN;
811 function CheckDateCacheCurrent() {
812 if (!date_cache_version_holder) {
813 date_cache_version_holder = %DateCacheVersion();
814 if (!date_cache_version_holder) return;
816 if (date_cache_version_holder[0] == date_cache_version) {
819 date_cache_version = date_cache_version_holder[0];
821 // Reset the timezone cache:
822 timezone_cache_time = NAN;
823 timezone_cache_timezone = UNDEFINED;
825 // Reset the date cache:
826 Date_cache.time = NAN;
827 Date_cache.string = null;
831 function CreateDate(time) {
832 var date = new GlobalDate();
837 // -------------------------------------------------------------------
839 %SetCode(GlobalDate, DateConstructor);
840 %FunctionSetPrototype(GlobalDate, new GlobalDate(NAN));
842 // Set up non-enumerable properties of the Date object itself.
843 utils.InstallFunctions(GlobalDate, DONT_ENUM, [
849 // Set up non-enumerable constructor property of the Date prototype object.
850 %AddNamedProperty(GlobalDate.prototype, "constructor", GlobalDate, DONT_ENUM);
851 utils.SetFunctionName(DateToPrimitive, toPrimitiveSymbol);
852 %AddNamedProperty(GlobalDate.prototype, toPrimitiveSymbol, DateToPrimitive,
853 DONT_ENUM | READ_ONLY);
855 // Set up non-enumerable functions of the Date prototype object and
857 utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [
858 "toString", DateToString,
859 "toDateString", DateToDateString,
860 "toTimeString", DateToTimeString,
861 "toLocaleString", DateToLocaleString,
862 "toLocaleDateString", DateToLocaleDateString,
863 "toLocaleTimeString", DateToLocaleTimeString,
864 "valueOf", DateValueOf,
865 "getTime", DateGetTime,
866 "getFullYear", DateGetFullYear,
867 "getUTCFullYear", DateGetUTCFullYear,
868 "getMonth", DateGetMonth,
869 "getUTCMonth", DateGetUTCMonth,
870 "getDate", DateGetDate,
871 "getUTCDate", DateGetUTCDate,
872 "getDay", DateGetDay,
873 "getUTCDay", DateGetUTCDay,
874 "getHours", DateGetHours,
875 "getUTCHours", DateGetUTCHours,
876 "getMinutes", DateGetMinutes,
877 "getUTCMinutes", DateGetUTCMinutes,
878 "getSeconds", DateGetSeconds,
879 "getUTCSeconds", DateGetUTCSeconds,
880 "getMilliseconds", DateGetMilliseconds,
881 "getUTCMilliseconds", DateGetUTCMilliseconds,
882 "getTimezoneOffset", DateGetTimezoneOffset,
883 "setTime", DateSetTime,
884 "setMilliseconds", DateSetMilliseconds,
885 "setUTCMilliseconds", DateSetUTCMilliseconds,
886 "setSeconds", DateSetSeconds,
887 "setUTCSeconds", DateSetUTCSeconds,
888 "setMinutes", DateSetMinutes,
889 "setUTCMinutes", DateSetUTCMinutes,
890 "setHours", DateSetHours,
891 "setUTCHours", DateSetUTCHours,
892 "setDate", DateSetDate,
893 "setUTCDate", DateSetUTCDate,
894 "setMonth", DateSetMonth,
895 "setUTCMonth", DateSetUTCMonth,
896 "setFullYear", DateSetFullYear,
897 "setUTCFullYear", DateSetUTCFullYear,
898 "toGMTString", DateToGMTString,
899 "toUTCString", DateToUTCString,
900 "getYear", DateGetYear,
901 "setYear", DateSetYear,
902 "toISOString", DateToISOString,
906 %InstallToContext(["create_date_fun", CreateDate]);