deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / date.js
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.
4
5 // This file relies on the fact that the following declarations have been made
6 // in v8natives.js:
7 // var $isFinite = GlobalIsFinite;
8
9 var $createDate;
10
11 // -------------------------------------------------------------------
12
13 (function() {
14
15 "use strict";
16
17 %CheckIsBootstrapping();
18
19 var GlobalDate = global.Date;
20
21 // This file contains date support implemented in JavaScript.
22
23 // Helper function to throw error.
24 function ThrowDateTypeError() {
25   throw new $TypeError('this is not a Date object.');
26 }
27
28 var timezone_cache_time = NAN;
29 var timezone_cache_timezone;
30
31 function LocalTimezone(t) {
32   if (NUMBER_IS_NAN(t)) return "";
33   CheckDateCacheCurrent();
34   if (t == timezone_cache_time) {
35     return timezone_cache_timezone;
36   }
37   var timezone = %DateLocalTimezone(t);
38   timezone_cache_time = t;
39   timezone_cache_timezone = timezone;
40   return timezone;
41 }
42
43
44 function UTC(time) {
45   if (NUMBER_IS_NAN(time)) return time;
46   // local_time_offset is needed before the call to DaylightSavingsOffset,
47   // so it may be uninitialized.
48   return %DateToUTC(time);
49 }
50
51
52 // ECMA 262 - 15.9.1.11
53 function MakeTime(hour, min, sec, ms) {
54   if (!$isFinite(hour)) return NAN;
55   if (!$isFinite(min)) return NAN;
56   if (!$isFinite(sec)) return NAN;
57   if (!$isFinite(ms)) return NAN;
58   return TO_INTEGER(hour) * msPerHour
59       + TO_INTEGER(min) * msPerMinute
60       + TO_INTEGER(sec) * msPerSecond
61       + TO_INTEGER(ms);
62 }
63
64
65 // ECMA 262 - 15.9.1.12
66 function TimeInYear(year) {
67   return DaysInYear(year) * msPerDay;
68 }
69
70
71 // Compute number of days given a year, month, date.
72 // Note that month and date can lie outside the normal range.
73 //   For example:
74 //     MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
75 //     MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
76 //     MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
77 function MakeDay(year, month, date) {
78   if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return NAN;
79
80   // Convert to integer and map -0 to 0.
81   year = TO_INTEGER_MAP_MINUS_ZERO(year);
82   month = TO_INTEGER_MAP_MINUS_ZERO(month);
83   date = TO_INTEGER_MAP_MINUS_ZERO(date);
84
85   if (year < kMinYear || year > kMaxYear ||
86       month < kMinMonth || month > kMaxMonth) {
87     return NAN;
88   }
89
90   // Now we rely on year and month being SMIs.
91   return %DateMakeDay(year | 0, month | 0) + date - 1;
92 }
93
94
95 // ECMA 262 - 15.9.1.13
96 function MakeDate(day, time) {
97   var time = day * msPerDay + time;
98   // Some of our runtime funtions for computing UTC(time) rely on
99   // times not being significantly larger than MAX_TIME_MS. If there
100   // is no way that the time can be within range even after UTC
101   // conversion we return NaN immediately instead of relying on
102   // TimeClip to do it.
103   if ($abs(time) > MAX_TIME_BEFORE_UTC) return NAN;
104   return time;
105 }
106
107
108 // ECMA 262 - 15.9.1.14
109 function TimeClip(time) {
110   if (!$isFinite(time)) return NAN;
111   if ($abs(time) > MAX_TIME_MS) return NAN;
112   return TO_INTEGER(time);
113 }
114
115
116 // The Date cache is used to limit the cost of parsing the same Date
117 // strings over and over again.
118 var Date_cache = {
119   // Cached time value.
120   time: 0,
121   // String input for which the cached time is valid.
122   string: null
123 };
124
125
126 function DateConstructor(year, month, date, hours, minutes, seconds, ms) {
127   if (!%_IsConstructCall()) {
128     // ECMA 262 - 15.9.2
129     return (new GlobalDate()).toString();
130   }
131
132   // ECMA 262 - 15.9.3
133   var argc = %_ArgumentsLength();
134   var value;
135   if (argc == 0) {
136     value = %DateCurrentTime();
137     SET_UTC_DATE_VALUE(this, value);
138   } else if (argc == 1) {
139     if (IS_NUMBER(year)) {
140       value = year;
141     } else if (IS_STRING(year)) {
142       // Probe the Date cache. If we already have a time value for the
143       // given time, we re-use that instead of parsing the string again.
144       CheckDateCacheCurrent();
145       var cache = Date_cache;
146       if (cache.string === year) {
147         value = cache.time;
148       } else {
149         value = DateParse(year);
150         if (!NUMBER_IS_NAN(value)) {
151           cache.time = value;
152           cache.string = year;
153         }
154       }
155
156     } else {
157       // According to ECMA 262, no hint should be given for this
158       // conversion. However, ToPrimitive defaults to STRING_HINT for
159       // Date objects which will lose precision when the Date
160       // constructor is called with another Date object as its
161       // argument. We therefore use NUMBER_HINT for the conversion,
162       // which is the default for everything else than Date objects.
163       // This makes us behave like KJS and SpiderMonkey.
164       var time = ToPrimitive(year, NUMBER_HINT);
165       value = IS_STRING(time) ? DateParse(time) : ToNumber(time);
166     }
167     SET_UTC_DATE_VALUE(this, value);
168   } else {
169     year = ToNumber(year);
170     month = ToNumber(month);
171     date = argc > 2 ? ToNumber(date) : 1;
172     hours = argc > 3 ? ToNumber(hours) : 0;
173     minutes = argc > 4 ? ToNumber(minutes) : 0;
174     seconds = argc > 5 ? ToNumber(seconds) : 0;
175     ms = argc > 6 ? ToNumber(ms) : 0;
176     year = (!NUMBER_IS_NAN(year) &&
177             0 <= TO_INTEGER(year) &&
178             TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
179     var day = MakeDay(year, month, date);
180     var time = MakeTime(hours, minutes, seconds, ms);
181     value = MakeDate(day, time);
182     SET_LOCAL_DATE_VALUE(this, value);
183   }
184 }
185
186
187 var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
188 var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
189               'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
190
191
192 function TwoDigitString(value) {
193   return value < 10 ? "0" + value : "" + value;
194 }
195
196
197 function DateString(date) {
198   return WeekDays[LOCAL_WEEKDAY(date)] + ' '
199       + Months[LOCAL_MONTH(date)] + ' '
200       + TwoDigitString(LOCAL_DAY(date)) + ' '
201       + LOCAL_YEAR(date);
202 }
203
204
205 var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
206     'Thursday', 'Friday', 'Saturday'];
207 var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June',
208     'July', 'August', 'September', 'October', 'November', 'December'];
209
210
211 function LongDateString(date) {
212   return LongWeekDays[LOCAL_WEEKDAY(date)] + ', '
213       + LongMonths[LOCAL_MONTH(date)] + ' '
214       + TwoDigitString(LOCAL_DAY(date)) + ', '
215       + LOCAL_YEAR(date);
216 }
217
218
219 function TimeString(date) {
220   return TwoDigitString(LOCAL_HOUR(date)) + ':'
221       + TwoDigitString(LOCAL_MIN(date)) + ':'
222       + TwoDigitString(LOCAL_SEC(date));
223 }
224
225
226 function TimeStringUTC(date) {
227   return TwoDigitString(UTC_HOUR(date)) + ':'
228       + TwoDigitString(UTC_MIN(date)) + ':'
229       + TwoDigitString(UTC_SEC(date));
230 }
231
232
233 function LocalTimezoneString(date) {
234   var timezone = LocalTimezone(UTC_DATE_VALUE(date));
235
236   var timezoneOffset = -TIMEZONE_OFFSET(date);
237   var sign = (timezoneOffset >= 0) ? 1 : -1;
238   var hours = $floor((sign * timezoneOffset)/60);
239   var min   = $floor((sign * timezoneOffset)%60);
240   var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
241       TwoDigitString(hours) + TwoDigitString(min);
242   return gmt + ' (' +  timezone + ')';
243 }
244
245
246 function DatePrintString(date) {
247   return DateString(date) + ' ' + TimeString(date);
248 }
249
250 // -------------------------------------------------------------------
251
252 // Reused output buffer. Used when parsing date strings.
253 var parse_buffer = $Array(8);
254
255 // ECMA 262 - 15.9.4.2
256 function DateParse(string) {
257   var arr = %DateParseString(ToString(string), parse_buffer);
258   if (IS_NULL(arr)) return NAN;
259
260   var day = MakeDay(arr[0], arr[1], arr[2]);
261   var time = MakeTime(arr[3], arr[4], arr[5], arr[6]);
262   var date = MakeDate(day, time);
263
264   if (IS_NULL(arr[7])) {
265     return TimeClip(UTC(date));
266   } else {
267     return TimeClip(date - arr[7] * 1000);
268   }
269 }
270
271
272 // ECMA 262 - 15.9.4.3
273 function DateUTC(year, month, date, hours, minutes, seconds, ms) {
274   year = ToNumber(year);
275   month = ToNumber(month);
276   var argc = %_ArgumentsLength();
277   date = argc > 2 ? ToNumber(date) : 1;
278   hours = argc > 3 ? ToNumber(hours) : 0;
279   minutes = argc > 4 ? ToNumber(minutes) : 0;
280   seconds = argc > 5 ? ToNumber(seconds) : 0;
281   ms = argc > 6 ? ToNumber(ms) : 0;
282   year = (!NUMBER_IS_NAN(year) &&
283           0 <= TO_INTEGER(year) &&
284           TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
285   var day = MakeDay(year, month, date);
286   var time = MakeTime(hours, minutes, seconds, ms);
287   return TimeClip(MakeDate(day, time));
288 }
289
290
291 // ECMA 262 - 15.9.4.4
292 function DateNow() {
293   return %DateCurrentTime();
294 }
295
296
297 // ECMA 262 - 15.9.5.2
298 function DateToString() {
299   var t = UTC_DATE_VALUE(this)
300   if (NUMBER_IS_NAN(t)) return kInvalidDate;
301   var time_zone_string = LocalTimezoneString(this)
302   return DatePrintString(this) + time_zone_string;
303 }
304
305
306 // ECMA 262 - 15.9.5.3
307 function DateToDateString() {
308   var t = UTC_DATE_VALUE(this);
309   if (NUMBER_IS_NAN(t)) return kInvalidDate;
310   return DateString(this);
311 }
312
313
314 // ECMA 262 - 15.9.5.4
315 function DateToTimeString() {
316   var t = UTC_DATE_VALUE(this);
317   if (NUMBER_IS_NAN(t)) return kInvalidDate;
318   var time_zone_string = LocalTimezoneString(this);
319   return TimeString(this) + time_zone_string;
320 }
321
322
323 // ECMA 262 - 15.9.5.5
324 function DateToLocaleString() {
325   return %_CallFunction(this, DateToString);
326 }
327
328
329 // ECMA 262 - 15.9.5.6
330 function DateToLocaleDateString() {
331   var t = UTC_DATE_VALUE(this);
332   if (NUMBER_IS_NAN(t)) return kInvalidDate;
333   return LongDateString(this);
334 }
335
336
337 // ECMA 262 - 15.9.5.7
338 function DateToLocaleTimeString() {
339   var t = UTC_DATE_VALUE(this);
340   if (NUMBER_IS_NAN(t)) return kInvalidDate;
341   return TimeString(this);
342 }
343
344
345 // ECMA 262 - 15.9.5.8
346 function DateValueOf() {
347   return UTC_DATE_VALUE(this);
348 }
349
350
351 // ECMA 262 - 15.9.5.9
352 function DateGetTime() {
353   return UTC_DATE_VALUE(this);
354 }
355
356
357 // ECMA 262 - 15.9.5.10
358 function DateGetFullYear() {
359   return LOCAL_YEAR(this);
360 }
361
362
363 // ECMA 262 - 15.9.5.11
364 function DateGetUTCFullYear() {
365   return UTC_YEAR(this);
366 }
367
368
369 // ECMA 262 - 15.9.5.12
370 function DateGetMonth() {
371   return LOCAL_MONTH(this);
372 }
373
374
375 // ECMA 262 - 15.9.5.13
376 function DateGetUTCMonth() {
377   return UTC_MONTH(this);
378 }
379
380
381 // ECMA 262 - 15.9.5.14
382 function DateGetDate() {
383   return LOCAL_DAY(this);
384 }
385
386
387 // ECMA 262 - 15.9.5.15
388 function DateGetUTCDate() {
389   return UTC_DAY(this);
390 }
391
392
393 // ECMA 262 - 15.9.5.16
394 function DateGetDay() {
395   return LOCAL_WEEKDAY(this);
396 }
397
398
399 // ECMA 262 - 15.9.5.17
400 function DateGetUTCDay() {
401   return UTC_WEEKDAY(this);
402 }
403
404
405 // ECMA 262 - 15.9.5.18
406 function DateGetHours() {
407   return LOCAL_HOUR(this);
408 }
409
410
411 // ECMA 262 - 15.9.5.19
412 function DateGetUTCHours() {
413   return UTC_HOUR(this);
414 }
415
416
417 // ECMA 262 - 15.9.5.20
418 function DateGetMinutes() {
419   return LOCAL_MIN(this);
420 }
421
422
423 // ECMA 262 - 15.9.5.21
424 function DateGetUTCMinutes() {
425   return UTC_MIN(this);
426 }
427
428
429 // ECMA 262 - 15.9.5.22
430 function DateGetSeconds() {
431   return LOCAL_SEC(this);
432 }
433
434
435 // ECMA 262 - 15.9.5.23
436 function DateGetUTCSeconds() {
437   return UTC_SEC(this)
438 }
439
440
441 // ECMA 262 - 15.9.5.24
442 function DateGetMilliseconds() {
443   return LOCAL_MS(this);
444 }
445
446
447 // ECMA 262 - 15.9.5.25
448 function DateGetUTCMilliseconds() {
449   return UTC_MS(this);
450 }
451
452
453 // ECMA 262 - 15.9.5.26
454 function DateGetTimezoneOffset() {
455   return TIMEZONE_OFFSET(this);
456 }
457
458
459 // ECMA 262 - 15.9.5.27
460 function DateSetTime(ms) {
461   CHECK_DATE(this);
462   SET_UTC_DATE_VALUE(this, ToNumber(ms));
463   return UTC_DATE_VALUE(this);
464 }
465
466
467 // ECMA 262 - 15.9.5.28
468 function DateSetMilliseconds(ms) {
469   var t = LOCAL_DATE_VALUE(this);
470   ms = ToNumber(ms);
471   var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), LOCAL_SEC(this), ms);
472   return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
473 }
474
475
476 // ECMA 262 - 15.9.5.29
477 function DateSetUTCMilliseconds(ms) {
478   var t = UTC_DATE_VALUE(this);
479   ms = ToNumber(ms);
480   var time = MakeTime(UTC_HOUR(this),
481                       UTC_MIN(this),
482                       UTC_SEC(this),
483                       ms);
484   return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
485 }
486
487
488 // ECMA 262 - 15.9.5.30
489 function DateSetSeconds(sec, ms) {
490   var t = LOCAL_DATE_VALUE(this);
491   sec = ToNumber(sec);
492   ms = %_ArgumentsLength() < 2 ? LOCAL_MS(this) : ToNumber(ms);
493   var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), sec, ms);
494   return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
495 }
496
497
498 // ECMA 262 - 15.9.5.31
499 function DateSetUTCSeconds(sec, ms) {
500   var t = UTC_DATE_VALUE(this);
501   sec = ToNumber(sec);
502   ms = %_ArgumentsLength() < 2 ? UTC_MS(this) : ToNumber(ms);
503   var time = MakeTime(UTC_HOUR(this), UTC_MIN(this), sec, ms);
504   return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
505 }
506
507
508 // ECMA 262 - 15.9.5.33
509 function DateSetMinutes(min, sec, ms) {
510   var t = LOCAL_DATE_VALUE(this);
511   min = ToNumber(min);
512   var argc = %_ArgumentsLength();
513   sec = argc < 2 ? LOCAL_SEC(this) : ToNumber(sec);
514   ms = argc < 3 ? LOCAL_MS(this) : ToNumber(ms);
515   var time = MakeTime(LOCAL_HOUR(this), min, sec, ms);
516   return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
517 }
518
519
520 // ECMA 262 - 15.9.5.34
521 function DateSetUTCMinutes(min, sec, ms) {
522   var t = UTC_DATE_VALUE(this);
523   min = ToNumber(min);
524   var argc = %_ArgumentsLength();
525   sec = argc < 2 ? UTC_SEC(this) : ToNumber(sec);
526   ms = argc < 3 ? UTC_MS(this) : ToNumber(ms);
527   var time = MakeTime(UTC_HOUR(this), min, sec, ms);
528   return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
529 }
530
531
532 // ECMA 262 - 15.9.5.35
533 function DateSetHours(hour, min, sec, ms) {
534   var t = LOCAL_DATE_VALUE(this);
535   hour = ToNumber(hour);
536   var argc = %_ArgumentsLength();
537   min = argc < 2 ? LOCAL_MIN(this) : ToNumber(min);
538   sec = argc < 3 ? LOCAL_SEC(this) : ToNumber(sec);
539   ms = argc < 4 ? LOCAL_MS(this) : ToNumber(ms);
540   var time = MakeTime(hour, min, sec, ms);
541   return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
542 }
543
544
545 // ECMA 262 - 15.9.5.34
546 function DateSetUTCHours(hour, min, sec, ms) {
547   var t = UTC_DATE_VALUE(this);
548   hour = ToNumber(hour);
549   var argc = %_ArgumentsLength();
550   min = argc < 2 ? UTC_MIN(this) : ToNumber(min);
551   sec = argc < 3 ? UTC_SEC(this) : ToNumber(sec);
552   ms = argc < 4 ? UTC_MS(this) : ToNumber(ms);
553   var time = MakeTime(hour, min, sec, ms);
554   return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
555 }
556
557
558 // ECMA 262 - 15.9.5.36
559 function DateSetDate(date) {
560   var t = LOCAL_DATE_VALUE(this);
561   date = ToNumber(date);
562   var day = MakeDay(LOCAL_YEAR(this), LOCAL_MONTH(this), date);
563   return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
564 }
565
566
567 // ECMA 262 - 15.9.5.37
568 function DateSetUTCDate(date) {
569   var t = UTC_DATE_VALUE(this);
570   date = ToNumber(date);
571   var day = MakeDay(UTC_YEAR(this), UTC_MONTH(this), date);
572   return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
573 }
574
575
576 // ECMA 262 - 15.9.5.38
577 function DateSetMonth(month, date) {
578   var t = LOCAL_DATE_VALUE(this);
579   month = ToNumber(month);
580   date = %_ArgumentsLength() < 2 ? LOCAL_DAY(this) : ToNumber(date);
581   var day = MakeDay(LOCAL_YEAR(this), month, date);
582   return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
583 }
584
585
586 // ECMA 262 - 15.9.5.39
587 function DateSetUTCMonth(month, date) {
588   var t = UTC_DATE_VALUE(this);
589   month = ToNumber(month);
590   date = %_ArgumentsLength() < 2 ? UTC_DAY(this) : ToNumber(date);
591   var day = MakeDay(UTC_YEAR(this), month, date);
592   return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
593 }
594
595
596 // ECMA 262 - 15.9.5.40
597 function DateSetFullYear(year, month, date) {
598   var t = LOCAL_DATE_VALUE(this);
599   year = ToNumber(year);
600   var argc = %_ArgumentsLength();
601   var time ;
602   if (NUMBER_IS_NAN(t)) {
603     month = argc < 2 ? 0 : ToNumber(month);
604     date = argc < 3 ? 1 : ToNumber(date);
605     time = 0;
606   } else {
607     month = argc < 2 ? LOCAL_MONTH(this) : ToNumber(month);
608     date = argc < 3 ? LOCAL_DAY(this) : ToNumber(date);
609     time = LOCAL_TIME_IN_DAY(this);
610   }
611   var day = MakeDay(year, month, date);
612   return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
613 }
614
615
616 // ECMA 262 - 15.9.5.41
617 function DateSetUTCFullYear(year, month, date) {
618   var t = UTC_DATE_VALUE(this);
619   year = ToNumber(year);
620   var argc = %_ArgumentsLength();
621   var time ;
622   if (NUMBER_IS_NAN(t)) {
623     month = argc < 2 ? 0 : ToNumber(month);
624     date = argc < 3 ? 1 : ToNumber(date);
625     time = 0;
626   } else {
627     month = argc < 2 ? UTC_MONTH(this) : ToNumber(month);
628     date = argc < 3 ? UTC_DAY(this) : ToNumber(date);
629     time = UTC_TIME_IN_DAY(this);
630   }
631   var day = MakeDay(year, month, date);
632   return SET_UTC_DATE_VALUE(this, MakeDate(day, time));
633 }
634
635
636 // ECMA 262 - 15.9.5.42
637 function DateToUTCString() {
638   var t = UTC_DATE_VALUE(this);
639   if (NUMBER_IS_NAN(t)) return kInvalidDate;
640   // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
641   return WeekDays[UTC_WEEKDAY(this)] + ', '
642       + TwoDigitString(UTC_DAY(this)) + ' '
643       + Months[UTC_MONTH(this)] + ' '
644       + UTC_YEAR(this) + ' '
645       + TimeStringUTC(this) + ' GMT';
646 }
647
648
649 // ECMA 262 - B.2.4
650 function DateGetYear() {
651   return LOCAL_YEAR(this) - 1900;
652 }
653
654
655 // ECMA 262 - B.2.5
656 function DateSetYear(year) {
657   CHECK_DATE(this);
658   year = ToNumber(year);
659   if (NUMBER_IS_NAN(year)) return SET_UTC_DATE_VALUE(this, NAN);
660   year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
661       ? 1900 + TO_INTEGER(year) : year;
662   var t = LOCAL_DATE_VALUE(this);
663   var month, date, time;
664   if (NUMBER_IS_NAN(t))  {
665     month = 0;
666     date = 1;
667     time = 0;
668   } else {
669     month = LOCAL_MONTH(this);
670     date = LOCAL_DAY(this);
671     time = LOCAL_TIME_IN_DAY(this);
672   }
673   var day = MakeDay(year, month, date);
674   return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
675 }
676
677
678 // ECMA 262 - B.2.6
679 //
680 // Notice that this does not follow ECMA 262 completely.  ECMA 262
681 // says that toGMTString should be the same Function object as
682 // toUTCString.  JSC does not do this, so for compatibility we do not
683 // do that either.  Instead, we create a new function whose name
684 // property will return toGMTString.
685 function DateToGMTString() {
686   return %_CallFunction(this, DateToUTCString);
687 }
688
689
690 function PadInt(n, digits) {
691   if (digits == 1) return n;
692   return n < %_MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
693 }
694
695
696 // ECMA 262 - 15.9.5.43
697 function DateToISOString() {
698   var t = UTC_DATE_VALUE(this);
699   if (NUMBER_IS_NAN(t)) throw MakeRangeError("invalid_time_value", []);
700   var year = this.getUTCFullYear();
701   var year_string;
702   if (year >= 0 && year <= 9999) {
703     year_string = PadInt(year, 4);
704   } else {
705     if (year < 0) {
706       year_string = "-" + PadInt(-year, 6);
707     } else {
708       year_string = "+" + PadInt(year, 6);
709     }
710   }
711   return year_string +
712       '-' + PadInt(this.getUTCMonth() + 1, 2) +
713       '-' + PadInt(this.getUTCDate(), 2) +
714       'T' + PadInt(this.getUTCHours(), 2) +
715       ':' + PadInt(this.getUTCMinutes(), 2) +
716       ':' + PadInt(this.getUTCSeconds(), 2) +
717       '.' + PadInt(this.getUTCMilliseconds(), 3) +
718       'Z';
719 }
720
721
722 function DateToJSON(key) {
723   var o = ToObject(this);
724   var tv = DefaultNumber(o);
725   if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
726     return null;
727   }
728   return o.toISOString();
729 }
730
731
732 var date_cache_version_holder;
733 var date_cache_version = NAN;
734
735
736 function CheckDateCacheCurrent() {
737   if (!date_cache_version_holder) {
738     date_cache_version_holder = %DateCacheVersion();
739     if (!date_cache_version_holder) return;
740   }
741   if (date_cache_version_holder[0] == date_cache_version) {
742     return;
743   }
744   date_cache_version = date_cache_version_holder[0];
745
746   // Reset the timezone cache:
747   timezone_cache_time = NAN;
748   timezone_cache_timezone = UNDEFINED;
749
750   // Reset the date cache:
751   Date_cache.time = NAN;
752   Date_cache.string = null;
753 }
754
755
756 function CreateDate(time) {
757   var date = new GlobalDate();
758   date.setTime(time);
759   return date;
760 }
761
762 // -------------------------------------------------------------------
763
764 %SetCode(GlobalDate, DateConstructor);
765 %FunctionSetPrototype(GlobalDate, new GlobalDate(NAN));
766
767 // Set up non-enumerable properties of the Date object itself.
768 InstallFunctions(GlobalDate, DONT_ENUM, $Array(
769   "UTC", DateUTC,
770   "parse", DateParse,
771   "now", DateNow
772 ));
773
774 // Set up non-enumerable constructor property of the Date prototype object.
775 %AddNamedProperty(GlobalDate.prototype, "constructor", GlobalDate, DONT_ENUM);
776
777 // Set up non-enumerable functions of the Date prototype object and
778 // set their names.
779 InstallFunctions(GlobalDate.prototype, DONT_ENUM, $Array(
780   "toString", DateToString,
781   "toDateString", DateToDateString,
782   "toTimeString", DateToTimeString,
783   "toLocaleString", DateToLocaleString,
784   "toLocaleDateString", DateToLocaleDateString,
785   "toLocaleTimeString", DateToLocaleTimeString,
786   "valueOf", DateValueOf,
787   "getTime", DateGetTime,
788   "getFullYear", DateGetFullYear,
789   "getUTCFullYear", DateGetUTCFullYear,
790   "getMonth", DateGetMonth,
791   "getUTCMonth", DateGetUTCMonth,
792   "getDate", DateGetDate,
793   "getUTCDate", DateGetUTCDate,
794   "getDay", DateGetDay,
795   "getUTCDay", DateGetUTCDay,
796   "getHours", DateGetHours,
797   "getUTCHours", DateGetUTCHours,
798   "getMinutes", DateGetMinutes,
799   "getUTCMinutes", DateGetUTCMinutes,
800   "getSeconds", DateGetSeconds,
801   "getUTCSeconds", DateGetUTCSeconds,
802   "getMilliseconds", DateGetMilliseconds,
803   "getUTCMilliseconds", DateGetUTCMilliseconds,
804   "getTimezoneOffset", DateGetTimezoneOffset,
805   "setTime", DateSetTime,
806   "setMilliseconds", DateSetMilliseconds,
807   "setUTCMilliseconds", DateSetUTCMilliseconds,
808   "setSeconds", DateSetSeconds,
809   "setUTCSeconds", DateSetUTCSeconds,
810   "setMinutes", DateSetMinutes,
811   "setUTCMinutes", DateSetUTCMinutes,
812   "setHours", DateSetHours,
813   "setUTCHours", DateSetUTCHours,
814   "setDate", DateSetDate,
815   "setUTCDate", DateSetUTCDate,
816   "setMonth", DateSetMonth,
817   "setUTCMonth", DateSetUTCMonth,
818   "setFullYear", DateSetFullYear,
819   "setUTCFullYear", DateSetUTCFullYear,
820   "toGMTString", DateToGMTString,
821   "toUTCString", DateToUTCString,
822   "getYear", DateGetYear,
823   "setYear", DateSetYear,
824   "toISOString", DateToISOString,
825   "toJSON", DateToJSON
826 ));
827
828 // Expose to the global scope.
829 $createDate = CreateDate;
830
831 })();