blob: 1fb4897921a91fb1d434909136e9d0034f584c29 [file] [log] [blame]
Andrei Popescu31002712010-02-23 13:46:05 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
29// This file relies on the fact that the following declarations have been made
30// in v8natives.js:
31// const $isFinite = GlobalIsFinite;
32
33// -------------------------------------------------------------------
34
35// This file contains date support implemented in JavaScript.
36
37
38// Keep reference to original values of some global properties. This
39// has the added benefit that the code in this file is isolated from
40// changes to these properties.
41const $Date = global.Date;
42
43// Helper function to throw error.
44function ThrowDateTypeError() {
45 throw new $TypeError('this is not a Date object.');
46}
47
48// ECMA 262 - 5.2
49function Modulo(value, remainder) {
50 var mod = value % remainder;
51 // Guard against returning -0.
52 if (mod == 0) return 0;
53 return mod >= 0 ? mod : mod + remainder;
54}
55
56
57function TimeWithinDay(time) {
58 return Modulo(time, msPerDay);
59}
60
61
62// ECMA 262 - 15.9.1.3
63function DaysInYear(year) {
64 if (year % 4 != 0) return 365;
65 if ((year % 100 == 0) && (year % 400 != 0)) return 365;
66 return 366;
67}
68
69
70function DayFromYear(year) {
71 return 365 * (year-1970)
72 + FLOOR((year-1969)/4)
73 - FLOOR((year-1901)/100)
74 + FLOOR((year-1601)/400);
75}
76
77
78function TimeFromYear(year) {
79 return msPerDay * DayFromYear(year);
80}
81
82
83function InLeapYear(time) {
Ben Murdochb0fe1622011-05-05 13:52:32 +010084 return DaysInYear(YearFromTime(time)) == 366 ? 1 : 0;
Andrei Popescu31002712010-02-23 13:46:05 +000085}
86
87
88function DayWithinYear(time) {
Ben Murdochb0fe1622011-05-05 13:52:32 +010089 return DAY(time) - DayFromYear(YearFromTime(time));
Andrei Popescu31002712010-02-23 13:46:05 +000090}
91
92
93// ECMA 262 - 15.9.1.9
94function EquivalentYear(year) {
95 // Returns an equivalent year in the range [2008-2035] matching
96 // - leap year.
97 // - week day of first day.
98 var time = TimeFromYear(year);
99 var recent_year = (InLeapYear(time) == 0 ? 1967 : 1956) +
100 (WeekDay(time) * 12) % 28;
101 // Find the year in the range 2008..2037 that is equivalent mod 28.
102 // Add 3*28 to give a positive argument to the modulus operator.
103 return 2008 + (recent_year + 3*28 - 2008) % 28;
104}
105
106
107function EquivalentTime(t) {
108 // The issue here is that some library calls don't work right for dates
109 // that cannot be represented using a non-negative signed 32 bit integer
110 // (measured in whole seconds based on the 1970 epoch).
111 // We solve this by mapping the time to a year with same leap-year-ness
112 // and same starting day for the year. The ECMAscript specification says
113 // we must do this, but for compatibility with other browsers, we use
114 // the actual year if it is in the range 1970..2037
115 if (t >= 0 && t <= 2.1e12) return t;
Steve Block6ded16b2010-05-10 14:33:55 +0100116
Ben Murdochb0fe1622011-05-05 13:52:32 +0100117 var day = MakeDay(EquivalentYear(YearFromTime(t)),
118 MonthFromTime(t),
119 DateFromTime(t));
Steve Block6ded16b2010-05-10 14:33:55 +0100120 return MakeDate(day, TimeWithinDay(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000121}
122
123
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100124// local_time_offset is initialized when the DST_offset_cache is missed.
125// It must not be used until after a call to DaylightSavingsOffset().
126// In this way, only one check, for a DST cache miss, is needed.
127var local_time_offset;
128
129
130// Because computing the DST offset is an expensive operation,
131// we keep a cache of the last computed DST offset along with a time interval
Andrei Popescu31002712010-02-23 13:46:05 +0000132// where we know the cache is valid.
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100133// When the cache is valid, local_time_offset is also valid.
Andrei Popescu31002712010-02-23 13:46:05 +0000134var DST_offset_cache = {
135 // Cached DST offset.
136 offset: 0,
137 // Time interval where the cached offset is valid.
138 start: 0, end: -1,
139 // Size of next interval expansion.
Iain Merrick75681382010-08-19 15:07:18 +0100140 increment: 0,
141 initial_increment: 19 * msPerDay
Andrei Popescu31002712010-02-23 13:46:05 +0000142};
143
144
145// NOTE: The implementation relies on the fact that no time zones have
Iain Merrick75681382010-08-19 15:07:18 +0100146// more than one daylight savings offset change per 19 days.
147//
148// In Egypt in 2010 they decided to suspend DST during Ramadan. This
149// led to a short interval where DST is in effect from September 10 to
150// September 30.
151//
Andrei Popescu31002712010-02-23 13:46:05 +0000152// If this function is called with NaN it returns NaN.
153function DaylightSavingsOffset(t) {
154 // Load the cache object from the builtins object.
155 var cache = DST_offset_cache;
156
157 // Cache the start and the end in local variables for fast access.
158 var start = cache.start;
159 var end = cache.end;
160
161 if (start <= t) {
162 // If the time fits in the cached interval, return the cached offset.
163 if (t <= end) return cache.offset;
164
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100165 // If the cache misses, the local_time_offset may not be initialized.
166 if (IS_UNDEFINED(local_time_offset)) {
167 local_time_offset = %DateLocalTimeOffset();
168 }
169
Andrei Popescu31002712010-02-23 13:46:05 +0000170 // Compute a possible new interval end.
171 var new_end = end + cache.increment;
172
173 if (t <= new_end) {
174 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end));
175 if (cache.offset == end_offset) {
176 // If the offset at the end of the new interval still matches
177 // the offset in the cache, we grow the cached time interval
178 // and return the offset.
179 cache.end = new_end;
Iain Merrick75681382010-08-19 15:07:18 +0100180 cache.increment = cache.initial_increment;
Andrei Popescu31002712010-02-23 13:46:05 +0000181 return end_offset;
182 } else {
183 var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
184 if (offset == end_offset) {
185 // The offset at the given time is equal to the offset at the
186 // new end of the interval, so that means that we've just skipped
187 // the point in time where the DST offset change occurred. Updated
188 // the interval to reflect this and reset the increment.
189 cache.start = t;
190 cache.end = new_end;
Iain Merrick75681382010-08-19 15:07:18 +0100191 cache.increment = cache.initial_increment;
Andrei Popescu31002712010-02-23 13:46:05 +0000192 } else {
193 // The interval contains a DST offset change and the given time is
194 // before it. Adjust the increment to avoid a linear search for
195 // the offset change point and change the end of the interval.
196 cache.increment /= 3;
197 cache.end = t;
198 }
199 // Update the offset in the cache and return it.
200 cache.offset = offset;
201 return offset;
202 }
203 }
204 }
205
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100206 // If the cache misses, the local_time_offset may not be initialized.
207 if (IS_UNDEFINED(local_time_offset)) {
208 local_time_offset = %DateLocalTimeOffset();
209 }
Andrei Popescu31002712010-02-23 13:46:05 +0000210 // Compute the DST offset for the time and shrink the cache interval
211 // to only contain the time. This allows fast repeated DST offset
212 // computations for the same time.
213 var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
214 cache.offset = offset;
215 cache.start = cache.end = t;
Iain Merrick75681382010-08-19 15:07:18 +0100216 cache.increment = cache.initial_increment;
Andrei Popescu31002712010-02-23 13:46:05 +0000217 return offset;
218}
219
220
221var timezone_cache_time = $NaN;
222var timezone_cache_timezone;
223
224function LocalTimezone(t) {
225 if (NUMBER_IS_NAN(t)) return "";
226 if (t == timezone_cache_time) {
227 return timezone_cache_timezone;
228 }
229 var timezone = %DateLocalTimezone(EquivalentTime(t));
230 timezone_cache_time = t;
231 timezone_cache_timezone = timezone;
232 return timezone;
233}
234
235
236function WeekDay(time) {
237 return Modulo(DAY(time) + 4, 7);
238}
239
Andrei Popescu31002712010-02-23 13:46:05 +0000240
241function LocalTime(time) {
242 if (NUMBER_IS_NAN(time)) return time;
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100243 // DaylightSavingsOffset called before local_time_offset used.
244 return time + DaylightSavingsOffset(time) + local_time_offset;
Andrei Popescu31002712010-02-23 13:46:05 +0000245}
246
Kristian Monsen25f61362010-05-21 11:50:48 +0100247
248var ltcache = {
Ben Murdochf87a2032010-10-22 12:50:53 +0100249 key: null,
Kristian Monsen25f61362010-05-21 11:50:48 +0100250 val: null
251};
252
Andrei Popescu31002712010-02-23 13:46:05 +0000253function LocalTimeNoCheck(time) {
Kristian Monsen25f61362010-05-21 11:50:48 +0100254 var ltc = ltcache;
255 if (%_ObjectEquals(time, ltc.key)) return ltc.val;
Steve Block6ded16b2010-05-10 14:33:55 +0100256
Andrei Popescu31002712010-02-23 13:46:05 +0000257 // Inline the DST offset cache checks for speed.
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100258 // The cache is hit, or DaylightSavingsOffset is called,
259 // before local_time_offset is used.
Andrei Popescu31002712010-02-23 13:46:05 +0000260 var cache = DST_offset_cache;
261 if (cache.start <= time && time <= cache.end) {
262 var dst_offset = cache.offset;
263 } else {
264 var dst_offset = DaylightSavingsOffset(time);
265 }
Kristian Monsen25f61362010-05-21 11:50:48 +0100266 ltc.key = time;
267 return (ltc.val = time + local_time_offset + dst_offset);
Andrei Popescu31002712010-02-23 13:46:05 +0000268}
269
270
271function UTC(time) {
272 if (NUMBER_IS_NAN(time)) return time;
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100273 // local_time_offset is needed before the call to DaylightSavingsOffset,
274 // so it may be uninitialized.
275 if (IS_UNDEFINED(local_time_offset)) {
276 local_time_offset = %DateLocalTimeOffset();
277 }
Andrei Popescu31002712010-02-23 13:46:05 +0000278 var tmp = time - local_time_offset;
279 return tmp - DaylightSavingsOffset(tmp);
280}
281
282
283// ECMA 262 - 15.9.1.11
284function MakeTime(hour, min, sec, ms) {
285 if (!$isFinite(hour)) return $NaN;
286 if (!$isFinite(min)) return $NaN;
287 if (!$isFinite(sec)) return $NaN;
288 if (!$isFinite(ms)) return $NaN;
289 return TO_INTEGER(hour) * msPerHour
290 + TO_INTEGER(min) * msPerMinute
291 + TO_INTEGER(sec) * msPerSecond
292 + TO_INTEGER(ms);
293}
294
295
296// ECMA 262 - 15.9.1.12
297function TimeInYear(year) {
298 return DaysInYear(year) * msPerDay;
299}
300
301
Steve Block6ded16b2010-05-10 14:33:55 +0100302var ymd_from_time_cache = [$NaN, $NaN, $NaN];
303var ymd_from_time_cached_time = $NaN;
Andrei Popescu31002712010-02-23 13:46:05 +0000304
Steve Block6ded16b2010-05-10 14:33:55 +0100305function YearFromTime(t) {
306 if (t !== ymd_from_time_cached_time) {
307 if (!$isFinite(t)) {
308 return $NaN;
Andrei Popescu31002712010-02-23 13:46:05 +0000309 }
Steve Block6ded16b2010-05-10 14:33:55 +0100310
311 %DateYMDFromTime(t, ymd_from_time_cache);
312 ymd_from_time_cached_time = t
313 }
314
315 return ymd_from_time_cache[0];
316}
317
318function MonthFromTime(t) {
319 if (t !== ymd_from_time_cached_time) {
320 if (!$isFinite(t)) {
321 return $NaN;
Andrei Popescu31002712010-02-23 13:46:05 +0000322 }
Steve Block6ded16b2010-05-10 14:33:55 +0100323 %DateYMDFromTime(t, ymd_from_time_cache);
324 ymd_from_time_cached_time = t
Andrei Popescu31002712010-02-23 13:46:05 +0000325 }
Steve Block6ded16b2010-05-10 14:33:55 +0100326
327 return ymd_from_time_cache[1];
Andrei Popescu31002712010-02-23 13:46:05 +0000328}
329
Steve Block6ded16b2010-05-10 14:33:55 +0100330function DateFromTime(t) {
331 if (t !== ymd_from_time_cached_time) {
332 if (!$isFinite(t)) {
333 return $NaN;
334 }
Andrei Popescu31002712010-02-23 13:46:05 +0000335
Steve Block6ded16b2010-05-10 14:33:55 +0100336 %DateYMDFromTime(t, ymd_from_time_cache);
337 ymd_from_time_cached_time = t
Andrei Popescu31002712010-02-23 13:46:05 +0000338 }
Steve Block6ded16b2010-05-10 14:33:55 +0100339
340 return ymd_from_time_cache[2];
Andrei Popescu31002712010-02-23 13:46:05 +0000341}
342
343
344// Compute number of days given a year, month, date.
345// Note that month and date can lie outside the normal range.
346// For example:
347// MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
348// MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
349// MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
350function MakeDay(year, month, date) {
351 if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return $NaN;
352
Steve Block8defd9f2010-07-08 12:39:36 +0100353 // Convert to integer and map -0 to 0.
354 year = TO_INTEGER_MAP_MINUS_ZERO(year);
355 month = TO_INTEGER_MAP_MINUS_ZERO(month);
356 date = TO_INTEGER_MAP_MINUS_ZERO(date);
Andrei Popescu31002712010-02-23 13:46:05 +0000357
Steve Block6ded16b2010-05-10 14:33:55 +0100358 if (year < kMinYear || year > kMaxYear ||
359 month < kMinMonth || month > kMaxMonth ||
360 date < kMinDate || date > kMaxDate) {
361 return $NaN;
Andrei Popescu31002712010-02-23 13:46:05 +0000362 }
363
Steve Block6ded16b2010-05-10 14:33:55 +0100364 // Now we rely on year, month and date being SMIs.
365 return %DateMakeDay(year, month, date);
Andrei Popescu31002712010-02-23 13:46:05 +0000366}
367
368
369// ECMA 262 - 15.9.1.13
370function MakeDate(day, time) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100371 var time = day * msPerDay + time;
372 // Some of our runtime funtions for computing UTC(time) rely on
373 // times not being significantly larger than MAX_TIME_MS. If there
374 // is no way that the time can be within range even after UTC
375 // conversion we return NaN immediately instead of relying on
376 // TimeClip to do it.
377 if ($abs(time) > MAX_TIME_BEFORE_UTC) return $NaN;
378 return time;
Andrei Popescu31002712010-02-23 13:46:05 +0000379}
380
381
382// ECMA 262 - 15.9.1.14
383function TimeClip(time) {
384 if (!$isFinite(time)) return $NaN;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100385 if ($abs(time) > MAX_TIME_MS) return $NaN;
Andrei Popescu31002712010-02-23 13:46:05 +0000386 return TO_INTEGER(time);
387}
388
389
390// The Date cache is used to limit the cost of parsing the same Date
391// strings over and over again.
392var Date_cache = {
393 // Cached time value.
394 time: $NaN,
395 // Cached year when interpreting the time as a local time. Only
396 // valid when the time matches cached time.
397 year: $NaN,
398 // String input for which the cached time is valid.
399 string: null
400};
401
402
403%SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
404 if (!%_IsConstructCall()) {
405 // ECMA 262 - 15.9.2
406 return (new $Date()).toString();
407 }
408
409 // ECMA 262 - 15.9.3
410 var argc = %_ArgumentsLength();
411 var value;
412 if (argc == 0) {
413 value = %DateCurrentTime();
414
415 } else if (argc == 1) {
416 if (IS_NUMBER(year)) {
417 value = TimeClip(year);
418
419 } else if (IS_STRING(year)) {
420 // Probe the Date cache. If we already have a time value for the
421 // given time, we re-use that instead of parsing the string again.
422 var cache = Date_cache;
423 if (cache.string === year) {
424 value = cache.time;
425 } else {
426 value = DateParse(year);
427 if (!NUMBER_IS_NAN(value)) {
428 cache.time = value;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100429 cache.year = YearFromTime(LocalTimeNoCheck(value));
Andrei Popescu31002712010-02-23 13:46:05 +0000430 cache.string = year;
431 }
432 }
433
434 } else {
435 // According to ECMA 262, no hint should be given for this
436 // conversion. However, ToPrimitive defaults to STRING_HINT for
437 // Date objects which will lose precision when the Date
438 // constructor is called with another Date object as its
439 // argument. We therefore use NUMBER_HINT for the conversion,
440 // which is the default for everything else than Date objects.
441 // This makes us behave like KJS and SpiderMonkey.
442 var time = ToPrimitive(year, NUMBER_HINT);
443 value = IS_STRING(time) ? DateParse(time) : TimeClip(ToNumber(time));
444 }
445
446 } else {
447 year = ToNumber(year);
448 month = ToNumber(month);
449 date = argc > 2 ? ToNumber(date) : 1;
450 hours = argc > 3 ? ToNumber(hours) : 0;
451 minutes = argc > 4 ? ToNumber(minutes) : 0;
452 seconds = argc > 5 ? ToNumber(seconds) : 0;
453 ms = argc > 6 ? ToNumber(ms) : 0;
454 year = (!NUMBER_IS_NAN(year) && 0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
455 ? 1900 + TO_INTEGER(year) : year;
456 var day = MakeDay(year, month, date);
457 var time = MakeTime(hours, minutes, seconds, ms);
458 value = TimeClip(UTC(MakeDate(day, time)));
459 }
460 %_SetValueOf(this, value);
461});
462
463
Andrei Popescu31002712010-02-23 13:46:05 +0000464%FunctionSetPrototype($Date, new $Date($NaN));
465
466
467var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
468var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
469
470
471function TwoDigitString(value) {
472 return value < 10 ? "0" + value : "" + value;
473}
474
475
476function DateString(time) {
Andrei Popescu31002712010-02-23 13:46:05 +0000477 return WeekDays[WeekDay(time)] + ' '
Steve Block6ded16b2010-05-10 14:33:55 +0100478 + Months[MonthFromTime(time)] + ' '
479 + TwoDigitString(DateFromTime(time)) + ' '
480 + YearFromTime(time);
Andrei Popescu31002712010-02-23 13:46:05 +0000481}
482
483
484var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
485var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
486
487
488function LongDateString(time) {
Andrei Popescu31002712010-02-23 13:46:05 +0000489 return LongWeekDays[WeekDay(time)] + ', '
Steve Block6ded16b2010-05-10 14:33:55 +0100490 + LongMonths[MonthFromTime(time)] + ' '
491 + TwoDigitString(DateFromTime(time)) + ', '
492 + YearFromTime(time);
Andrei Popescu31002712010-02-23 13:46:05 +0000493}
494
495
496function TimeString(time) {
497 return TwoDigitString(HOUR_FROM_TIME(time)) + ':'
498 + TwoDigitString(MIN_FROM_TIME(time)) + ':'
499 + TwoDigitString(SEC_FROM_TIME(time));
500}
501
502
503function LocalTimezoneString(time) {
Ben Murdochd69d2e32010-03-30 12:55:27 +0100504 var old_timezone = timezone_cache_timezone;
505 var timezone = LocalTimezone(time);
506 if (old_timezone && timezone != old_timezone) {
507 // If the timezone string has changed from the one that we cached,
508 // the local time offset may now be wrong. So we need to update it
509 // and try again.
510 local_time_offset = %DateLocalTimeOffset();
511 // We also need to invalidate the DST cache as the new timezone may have
512 // different DST times.
513 var dst_cache = DST_offset_cache;
514 dst_cache.start = 0;
515 dst_cache.end = -1;
516 }
517
Andrei Popescu31002712010-02-23 13:46:05 +0000518 var timezoneOffset =
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100519 (DaylightSavingsOffset(time) + local_time_offset) / msPerMinute;
Andrei Popescu31002712010-02-23 13:46:05 +0000520 var sign = (timezoneOffset >= 0) ? 1 : -1;
521 var hours = FLOOR((sign * timezoneOffset)/60);
522 var min = FLOOR((sign * timezoneOffset)%60);
523 var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
524 TwoDigitString(hours) + TwoDigitString(min);
Ben Murdochd69d2e32010-03-30 12:55:27 +0100525 return gmt + ' (' + timezone + ')';
Andrei Popescu31002712010-02-23 13:46:05 +0000526}
527
528
529function DatePrintString(time) {
530 return DateString(time) + ' ' + TimeString(time);
531}
532
533// -------------------------------------------------------------------
534
535// Reused output buffer. Used when parsing date strings.
Steve Block6ded16b2010-05-10 14:33:55 +0100536var parse_buffer = $Array(8);
Andrei Popescu31002712010-02-23 13:46:05 +0000537
538// ECMA 262 - 15.9.4.2
539function DateParse(string) {
540 var arr = %DateParseString(ToString(string), parse_buffer);
541 if (IS_NULL(arr)) return $NaN;
542
543 var day = MakeDay(arr[0], arr[1], arr[2]);
Steve Block6ded16b2010-05-10 14:33:55 +0100544 var time = MakeTime(arr[3], arr[4], arr[5], arr[6]);
Andrei Popescu31002712010-02-23 13:46:05 +0000545 var date = MakeDate(day, time);
546
Steve Block6ded16b2010-05-10 14:33:55 +0100547 if (IS_NULL(arr[7])) {
Andrei Popescu31002712010-02-23 13:46:05 +0000548 return TimeClip(UTC(date));
549 } else {
Steve Block6ded16b2010-05-10 14:33:55 +0100550 return TimeClip(date - arr[7] * 1000);
Andrei Popescu31002712010-02-23 13:46:05 +0000551 }
552}
553
554
555// ECMA 262 - 15.9.4.3
556function DateUTC(year, month, date, hours, minutes, seconds, ms) {
557 year = ToNumber(year);
558 month = ToNumber(month);
559 var argc = %_ArgumentsLength();
560 date = argc > 2 ? ToNumber(date) : 1;
561 hours = argc > 3 ? ToNumber(hours) : 0;
562 minutes = argc > 4 ? ToNumber(minutes) : 0;
563 seconds = argc > 5 ? ToNumber(seconds) : 0;
564 ms = argc > 6 ? ToNumber(ms) : 0;
565 year = (!NUMBER_IS_NAN(year) && 0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
566 ? 1900 + TO_INTEGER(year) : year;
567 var day = MakeDay(year, month, date);
568 var time = MakeTime(hours, minutes, seconds, ms);
569 return %_SetValueOf(this, TimeClip(MakeDate(day, time)));
570}
571
572
573// Mozilla-specific extension. Returns the number of milliseconds
574// elapsed since 1 January 1970 00:00:00 UTC.
575function DateNow() {
576 return %DateCurrentTime();
577}
578
579
580// ECMA 262 - 15.9.5.2
581function DateToString() {
582 var t = DATE_VALUE(this);
583 if (NUMBER_IS_NAN(t)) return kInvalidDate;
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100584 var time_zone_string = LocalTimezoneString(t); // May update local offset.
585 return DatePrintString(LocalTimeNoCheck(t)) + time_zone_string;
Andrei Popescu31002712010-02-23 13:46:05 +0000586}
587
588
589// ECMA 262 - 15.9.5.3
590function DateToDateString() {
591 var t = DATE_VALUE(this);
592 if (NUMBER_IS_NAN(t)) return kInvalidDate;
593 return DateString(LocalTimeNoCheck(t));
594}
595
596
597// ECMA 262 - 15.9.5.4
598function DateToTimeString() {
599 var t = DATE_VALUE(this);
600 if (NUMBER_IS_NAN(t)) return kInvalidDate;
Andrei Popescu6599b9d2010-04-28 13:01:47 +0100601 var time_zone_string = LocalTimezoneString(t); // May update local offset.
602 return TimeString(LocalTimeNoCheck(t)) + time_zone_string;
Andrei Popescu31002712010-02-23 13:46:05 +0000603}
604
605
606// ECMA 262 - 15.9.5.5
607function DateToLocaleString() {
Steve Block1e0659c2011-05-24 12:43:12 +0100608 return %_CallFunction(this, DateToString);
Andrei Popescu31002712010-02-23 13:46:05 +0000609}
610
611
612// ECMA 262 - 15.9.5.6
613function DateToLocaleDateString() {
614 var t = DATE_VALUE(this);
615 if (NUMBER_IS_NAN(t)) return kInvalidDate;
616 return LongDateString(LocalTimeNoCheck(t));
617}
618
619
620// ECMA 262 - 15.9.5.7
621function DateToLocaleTimeString() {
622 var t = DATE_VALUE(this);
623 if (NUMBER_IS_NAN(t)) return kInvalidDate;
624 var lt = LocalTimeNoCheck(t);
625 return TimeString(lt);
626}
627
628
629// ECMA 262 - 15.9.5.8
630function DateValueOf() {
631 return DATE_VALUE(this);
632}
633
634
635// ECMA 262 - 15.9.5.9
Andrei Popescu402d9372010-02-26 13:31:12 +0000636function DateGetTime() {
Andrei Popescu31002712010-02-23 13:46:05 +0000637 return DATE_VALUE(this);
638}
639
640
641// ECMA 262 - 15.9.5.10
642function DateGetFullYear() {
Leon Clarkeac952652010-07-15 11:15:24 +0100643 var t = DATE_VALUE(this);
644 if (NUMBER_IS_NAN(t)) return t;
645 var cache = Date_cache;
646 if (cache.time === t) return cache.year;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100647 return YearFromTime(LocalTimeNoCheck(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000648}
649
650
651// ECMA 262 - 15.9.5.11
652function DateGetUTCFullYear() {
Leon Clarkeac952652010-07-15 11:15:24 +0100653 var t = DATE_VALUE(this);
654 if (NUMBER_IS_NAN(t)) return t;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100655 return YearFromTime(t);
Andrei Popescu31002712010-02-23 13:46:05 +0000656}
657
658
659// ECMA 262 - 15.9.5.12
660function DateGetMonth() {
Leon Clarkeac952652010-07-15 11:15:24 +0100661 var t = DATE_VALUE(this);
662 if (NUMBER_IS_NAN(t)) return t;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100663 return MonthFromTime(LocalTimeNoCheck(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000664}
665
666
667// ECMA 262 - 15.9.5.13
668function DateGetUTCMonth() {
Leon Clarkeac952652010-07-15 11:15:24 +0100669 var t = DATE_VALUE(this);
670 if (NUMBER_IS_NAN(t)) return t;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100671 return MonthFromTime(t);
Andrei Popescu31002712010-02-23 13:46:05 +0000672}
673
674
675// ECMA 262 - 15.9.5.14
676function DateGetDate() {
Leon Clarkeac952652010-07-15 11:15:24 +0100677 var t = DATE_VALUE(this);
678 if (NUMBER_IS_NAN(t)) return t;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100679 return DateFromTime(LocalTimeNoCheck(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000680}
681
682
683// ECMA 262 - 15.9.5.15
684function DateGetUTCDate() {
Leon Clarkeac952652010-07-15 11:15:24 +0100685 var t = DATE_VALUE(this);
686 return NAN_OR_DATE_FROM_TIME(t);
Andrei Popescu31002712010-02-23 13:46:05 +0000687}
688
689
690// ECMA 262 - 15.9.5.16
691function DateGetDay() {
692 var t = %_ValueOf(this);
693 if (NUMBER_IS_NAN(t)) return t;
694 return WeekDay(LocalTimeNoCheck(t));
695}
696
697
698// ECMA 262 - 15.9.5.17
699function DateGetUTCDay() {
700 var t = %_ValueOf(this);
701 if (NUMBER_IS_NAN(t)) return t;
702 return WeekDay(t);
703}
704
705
706// ECMA 262 - 15.9.5.18
707function DateGetHours() {
Leon Clarkeac952652010-07-15 11:15:24 +0100708 var t = DATE_VALUE(this);
709 if (NUMBER_IS_NAN(t)) return t;
710 return HOUR_FROM_TIME(LocalTimeNoCheck(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000711}
712
713
714// ECMA 262 - 15.9.5.19
715function DateGetUTCHours() {
Leon Clarkeac952652010-07-15 11:15:24 +0100716 var t = DATE_VALUE(this);
717 if (NUMBER_IS_NAN(t)) return t;
718 return HOUR_FROM_TIME(t);
Andrei Popescu31002712010-02-23 13:46:05 +0000719}
720
721
722// ECMA 262 - 15.9.5.20
723function DateGetMinutes() {
Leon Clarkeac952652010-07-15 11:15:24 +0100724 var t = DATE_VALUE(this);
725 if (NUMBER_IS_NAN(t)) return t;
726 return MIN_FROM_TIME(LocalTimeNoCheck(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000727}
728
729
730// ECMA 262 - 15.9.5.21
731function DateGetUTCMinutes() {
Leon Clarkeac952652010-07-15 11:15:24 +0100732 var t = DATE_VALUE(this);
733 return NAN_OR_MIN_FROM_TIME(t);
Andrei Popescu31002712010-02-23 13:46:05 +0000734}
735
736
737// ECMA 262 - 15.9.5.22
738function DateGetSeconds() {
Leon Clarkeac952652010-07-15 11:15:24 +0100739 var t = DATE_VALUE(this);
740 if (NUMBER_IS_NAN(t)) return t;
741 return SEC_FROM_TIME(LocalTimeNoCheck(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000742}
743
744
745// ECMA 262 - 15.9.5.23
746function DateGetUTCSeconds() {
Leon Clarkeac952652010-07-15 11:15:24 +0100747 var t = DATE_VALUE(this);
748 return NAN_OR_SEC_FROM_TIME(t);
Andrei Popescu31002712010-02-23 13:46:05 +0000749}
750
751
752// ECMA 262 - 15.9.5.24
753function DateGetMilliseconds() {
Leon Clarkeac952652010-07-15 11:15:24 +0100754 var t = DATE_VALUE(this);
755 if (NUMBER_IS_NAN(t)) return t;
756 return MS_FROM_TIME(LocalTimeNoCheck(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000757}
758
759
760// ECMA 262 - 15.9.5.25
761function DateGetUTCMilliseconds() {
Leon Clarkeac952652010-07-15 11:15:24 +0100762 var t = DATE_VALUE(this);
763 return NAN_OR_MS_FROM_TIME(t);
Andrei Popescu31002712010-02-23 13:46:05 +0000764}
765
766
767// ECMA 262 - 15.9.5.26
768function DateGetTimezoneOffset() {
769 var t = DATE_VALUE(this);
770 if (NUMBER_IS_NAN(t)) return t;
771 return (t - LocalTimeNoCheck(t)) / msPerMinute;
772}
773
774
775// ECMA 262 - 15.9.5.27
776function DateSetTime(ms) {
777 if (!IS_DATE(this)) ThrowDateTypeError();
778 return %_SetValueOf(this, TimeClip(ToNumber(ms)));
779}
780
781
782// ECMA 262 - 15.9.5.28
783function DateSetMilliseconds(ms) {
784 var t = LocalTime(DATE_VALUE(this));
785 ms = ToNumber(ms);
786 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), SEC_FROM_TIME(t), ms);
787 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
788}
789
790
791// ECMA 262 - 15.9.5.29
792function DateSetUTCMilliseconds(ms) {
793 var t = DATE_VALUE(this);
794 ms = ToNumber(ms);
795 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), SEC_FROM_TIME(t), ms);
796 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
797}
798
799
800// ECMA 262 - 15.9.5.30
801function DateSetSeconds(sec, ms) {
802 var t = LocalTime(DATE_VALUE(this));
803 sec = ToNumber(sec);
Leon Clarkeac952652010-07-15 11:15:24 +0100804 ms = %_ArgumentsLength() < 2 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms);
Andrei Popescu31002712010-02-23 13:46:05 +0000805 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), sec, ms);
806 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
807}
808
809
810// ECMA 262 - 15.9.5.31
811function DateSetUTCSeconds(sec, ms) {
812 var t = DATE_VALUE(this);
813 sec = ToNumber(sec);
Leon Clarkeac952652010-07-15 11:15:24 +0100814 ms = %_ArgumentsLength() < 2 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms);
Andrei Popescu31002712010-02-23 13:46:05 +0000815 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), sec, ms);
816 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
817}
818
819
820// ECMA 262 - 15.9.5.33
821function DateSetMinutes(min, sec, ms) {
822 var t = LocalTime(DATE_VALUE(this));
823 min = ToNumber(min);
824 var argc = %_ArgumentsLength();
Leon Clarkeac952652010-07-15 11:15:24 +0100825 sec = argc < 2 ? NAN_OR_SEC_FROM_TIME(t) : ToNumber(sec);
826 ms = argc < 3 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms);
Andrei Popescu31002712010-02-23 13:46:05 +0000827 var time = MakeTime(HOUR_FROM_TIME(t), min, sec, ms);
828 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
829}
830
831
832// ECMA 262 - 15.9.5.34
833function DateSetUTCMinutes(min, sec, ms) {
834 var t = DATE_VALUE(this);
835 min = ToNumber(min);
836 var argc = %_ArgumentsLength();
Leon Clarkeac952652010-07-15 11:15:24 +0100837 sec = argc < 2 ? NAN_OR_SEC_FROM_TIME(t) : ToNumber(sec);
838 ms = argc < 3 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms);
Andrei Popescu31002712010-02-23 13:46:05 +0000839 var time = MakeTime(HOUR_FROM_TIME(t), min, sec, ms);
840 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
841}
842
843
844// ECMA 262 - 15.9.5.35
845function DateSetHours(hour, min, sec, ms) {
846 var t = LocalTime(DATE_VALUE(this));
847 hour = ToNumber(hour);
848 var argc = %_ArgumentsLength();
Leon Clarkeac952652010-07-15 11:15:24 +0100849 min = argc < 2 ? NAN_OR_MIN_FROM_TIME(t) : ToNumber(min);
850 sec = argc < 3 ? NAN_OR_SEC_FROM_TIME(t) : ToNumber(sec);
851 ms = argc < 4 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms);
Andrei Popescu31002712010-02-23 13:46:05 +0000852 var time = MakeTime(hour, min, sec, ms);
853 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
854}
855
856
857// ECMA 262 - 15.9.5.34
858function DateSetUTCHours(hour, min, sec, ms) {
859 var t = DATE_VALUE(this);
860 hour = ToNumber(hour);
861 var argc = %_ArgumentsLength();
Leon Clarkeac952652010-07-15 11:15:24 +0100862 min = argc < 2 ? NAN_OR_MIN_FROM_TIME(t) : ToNumber(min);
863 sec = argc < 3 ? NAN_OR_SEC_FROM_TIME(t) : ToNumber(sec);
864 ms = argc < 4 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms);
Andrei Popescu31002712010-02-23 13:46:05 +0000865 var time = MakeTime(hour, min, sec, ms);
866 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
867}
868
869
870// ECMA 262 - 15.9.5.36
871function DateSetDate(date) {
872 var t = LocalTime(DATE_VALUE(this));
873 date = ToNumber(date);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100874 var day = MakeDay(YearFromTime(t), MonthFromTime(t), date);
Andrei Popescu31002712010-02-23 13:46:05 +0000875 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
876}
877
878
879// ECMA 262 - 15.9.5.37
880function DateSetUTCDate(date) {
881 var t = DATE_VALUE(this);
882 date = ToNumber(date);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100883 var day = MakeDay(YearFromTime(t), MonthFromTime(t), date);
Andrei Popescu31002712010-02-23 13:46:05 +0000884 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
885}
886
887
888// ECMA 262 - 15.9.5.38
889function DateSetMonth(month, date) {
890 var t = LocalTime(DATE_VALUE(this));
891 month = ToNumber(month);
Leon Clarkeac952652010-07-15 11:15:24 +0100892 date = %_ArgumentsLength() < 2 ? NAN_OR_DATE_FROM_TIME(t) : ToNumber(date);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100893 var day = MakeDay(YearFromTime(t), month, date);
Andrei Popescu31002712010-02-23 13:46:05 +0000894 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
895}
896
897
898// ECMA 262 - 15.9.5.39
899function DateSetUTCMonth(month, date) {
900 var t = DATE_VALUE(this);
901 month = ToNumber(month);
Leon Clarkeac952652010-07-15 11:15:24 +0100902 date = %_ArgumentsLength() < 2 ? NAN_OR_DATE_FROM_TIME(t) : ToNumber(date);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100903 var day = MakeDay(YearFromTime(t), month, date);
Andrei Popescu31002712010-02-23 13:46:05 +0000904 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
905}
906
907
908// ECMA 262 - 15.9.5.40
909function DateSetFullYear(year, month, date) {
910 var t = DATE_VALUE(this);
911 t = NUMBER_IS_NAN(t) ? 0 : LocalTimeNoCheck(t);
912 year = ToNumber(year);
913 var argc = %_ArgumentsLength();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100914 month = argc < 2 ? MonthFromTime(t) : ToNumber(month);
915 date = argc < 3 ? DateFromTime(t) : ToNumber(date);
Andrei Popescu31002712010-02-23 13:46:05 +0000916 var day = MakeDay(year, month, date);
917 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
918}
919
920
921// ECMA 262 - 15.9.5.41
922function DateSetUTCFullYear(year, month, date) {
923 var t = DATE_VALUE(this);
924 if (NUMBER_IS_NAN(t)) t = 0;
925 var argc = %_ArgumentsLength();
926 year = ToNumber(year);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100927 month = argc < 2 ? MonthFromTime(t) : ToNumber(month);
928 date = argc < 3 ? DateFromTime(t) : ToNumber(date);
Andrei Popescu31002712010-02-23 13:46:05 +0000929 var day = MakeDay(year, month, date);
930 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
931}
932
933
934// ECMA 262 - 15.9.5.42
935function DateToUTCString() {
936 var t = DATE_VALUE(this);
937 if (NUMBER_IS_NAN(t)) return kInvalidDate;
938 // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
939 return WeekDays[WeekDay(t)] + ', '
Ben Murdochb0fe1622011-05-05 13:52:32 +0100940 + TwoDigitString(DateFromTime(t)) + ' '
941 + Months[MonthFromTime(t)] + ' '
942 + YearFromTime(t) + ' '
Andrei Popescu31002712010-02-23 13:46:05 +0000943 + TimeString(t) + ' GMT';
944}
945
946
947// ECMA 262 - B.2.4
948function DateGetYear() {
949 var t = DATE_VALUE(this);
950 if (NUMBER_IS_NAN(t)) return $NaN;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100951 return YearFromTime(LocalTimeNoCheck(t)) - 1900;
Andrei Popescu31002712010-02-23 13:46:05 +0000952}
953
954
955// ECMA 262 - B.2.5
956function DateSetYear(year) {
957 var t = LocalTime(DATE_VALUE(this));
958 if (NUMBER_IS_NAN(t)) t = 0;
959 year = ToNumber(year);
960 if (NUMBER_IS_NAN(year)) return %_SetValueOf(this, $NaN);
961 year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
962 ? 1900 + TO_INTEGER(year) : year;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100963 var day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
Andrei Popescu31002712010-02-23 13:46:05 +0000964 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
965}
966
967
968// ECMA 262 - B.2.6
969//
970// Notice that this does not follow ECMA 262 completely. ECMA 262
971// says that toGMTString should be the same Function object as
972// toUTCString. JSC does not do this, so for compatibility we do not
973// do that either. Instead, we create a new function whose name
974// property will return toGMTString.
975function DateToGMTString() {
Steve Block1e0659c2011-05-24 12:43:12 +0100976 return %_CallFunction(this, DateToUTCString);
Andrei Popescu31002712010-02-23 13:46:05 +0000977}
978
979
980function PadInt(n, digits) {
981 if (digits == 1) return n;
982 return n < MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
983}
984
985
986function DateToISOString() {
987 var t = DATE_VALUE(this);
988 if (NUMBER_IS_NAN(t)) return kInvalidDate;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100989 return this.getUTCFullYear() +
990 '-' + PadInt(this.getUTCMonth() + 1, 2) +
991 '-' + PadInt(this.getUTCDate(), 2) +
992 'T' + PadInt(this.getUTCHours(), 2) +
993 ':' + PadInt(this.getUTCMinutes(), 2) +
994 ':' + PadInt(this.getUTCSeconds(), 2) +
Andrei Popescu31002712010-02-23 13:46:05 +0000995 '.' + PadInt(this.getUTCMilliseconds(), 3) +
996 'Z';
997}
998
999
1000function DateToJSON(key) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001001 var o = ToObject(this);
1002 var tv = DefaultNumber(o);
Steve Block9fac8402011-05-12 15:51:54 +01001003 if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001004 return null;
1005 }
1006 return o.toISOString();
1007}
1008
1009
1010function ResetDateCache() {
1011
1012 // Reset the local_time_offset:
1013 local_time_offset = %DateLocalTimeOffset();
1014
1015 // Reset the DST offset cache:
1016 var cache = DST_offset_cache;
1017 cache.offset = 0;
1018 cache.start = 0;
1019 cache.end = -1;
1020 cache.increment = 0;
1021 cache.initial_increment = 19 * msPerDay;
1022
1023 // Reset the timezone cache:
1024 timezone_cache_time = $NaN;
1025 timezone_cache_timezone = undefined;
1026
1027 // Reset the ltcache:
1028 ltcache.key = null;
1029 ltcache.val = null;
1030
1031 // Reset the ymd_from_time_cache:
1032 ymd_from_time_cache = [$NaN, $NaN, $NaN];
1033 ymd_from_time_cached_time = $NaN;
1034
1035 // Reset the date cache:
1036 cache = Date_cache;
1037 cache.time = $NaN;
1038 cache.year = $NaN;
1039 cache.string = null;
Andrei Popescu31002712010-02-23 13:46:05 +00001040}
1041
1042
1043// -------------------------------------------------------------------
1044
1045function SetupDate() {
1046 // Setup non-enumerable properties of the Date object itself.
1047 InstallFunctions($Date, DONT_ENUM, $Array(
1048 "UTC", DateUTC,
1049 "parse", DateParse,
1050 "now", DateNow
1051 ));
1052
1053 // Setup non-enumerable constructor property of the Date prototype object.
1054 %SetProperty($Date.prototype, "constructor", $Date, DONT_ENUM);
1055
1056 // Setup non-enumerable functions of the Date prototype object and
1057 // set their names.
1058 InstallFunctionsOnHiddenPrototype($Date.prototype, DONT_ENUM, $Array(
1059 "toString", DateToString,
1060 "toDateString", DateToDateString,
1061 "toTimeString", DateToTimeString,
1062 "toLocaleString", DateToLocaleString,
1063 "toLocaleDateString", DateToLocaleDateString,
1064 "toLocaleTimeString", DateToLocaleTimeString,
1065 "valueOf", DateValueOf,
1066 "getTime", DateGetTime,
1067 "getFullYear", DateGetFullYear,
1068 "getUTCFullYear", DateGetUTCFullYear,
1069 "getMonth", DateGetMonth,
1070 "getUTCMonth", DateGetUTCMonth,
1071 "getDate", DateGetDate,
1072 "getUTCDate", DateGetUTCDate,
1073 "getDay", DateGetDay,
1074 "getUTCDay", DateGetUTCDay,
1075 "getHours", DateGetHours,
1076 "getUTCHours", DateGetUTCHours,
1077 "getMinutes", DateGetMinutes,
1078 "getUTCMinutes", DateGetUTCMinutes,
1079 "getSeconds", DateGetSeconds,
1080 "getUTCSeconds", DateGetUTCSeconds,
1081 "getMilliseconds", DateGetMilliseconds,
1082 "getUTCMilliseconds", DateGetUTCMilliseconds,
1083 "getTimezoneOffset", DateGetTimezoneOffset,
1084 "setTime", DateSetTime,
1085 "setMilliseconds", DateSetMilliseconds,
1086 "setUTCMilliseconds", DateSetUTCMilliseconds,
1087 "setSeconds", DateSetSeconds,
1088 "setUTCSeconds", DateSetUTCSeconds,
1089 "setMinutes", DateSetMinutes,
1090 "setUTCMinutes", DateSetUTCMinutes,
1091 "setHours", DateSetHours,
1092 "setUTCHours", DateSetUTCHours,
1093 "setDate", DateSetDate,
1094 "setUTCDate", DateSetUTCDate,
1095 "setMonth", DateSetMonth,
1096 "setUTCMonth", DateSetUTCMonth,
1097 "setFullYear", DateSetFullYear,
1098 "setUTCFullYear", DateSetUTCFullYear,
1099 "toGMTString", DateToGMTString,
1100 "toUTCString", DateToUTCString,
1101 "getYear", DateGetYear,
1102 "setYear", DateSetYear,
1103 "toISOString", DateToISOString,
1104 "toJSON", DateToJSON
1105 ));
1106}
1107
1108SetupDate();