The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / date-delay.js @ 40c0f755

History | View | Annotate | Download (28.2 KB)

1 40c0f755 Ryan
// 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 $isNaN = GlobalIsNaN;
32
// const $isFinite = GlobalIsFinite;
33
34
// -------------------------------------------------------------------
35
36
// This file contains date support implemented in JavaScript.
37
38
39
// Keep reference to original values of some global properties.  This
40
// has the added benefit that the code in this file is isolated from
41
// changes to these properties.
42
const $Date = global.Date;
43
44
// ECMA 262 - 15.9.1.2
45
function Day(time) {
46
  return FLOOR(time/msPerDay);
47
}
48
49
50
// ECMA 262 - 5.2
51
function Modulo(value, remainder) {
52
  var mod = value % remainder;
53
  // Guard against returning -0.
54
  if (mod == 0) return 0;
55
  return mod >= 0 ? mod : mod + remainder;
56
}
57
58
59
function TimeWithinDay(time) {
60
  return Modulo(time, msPerDay);
61
}
62
63
64
// ECMA 262 - 15.9.1.3
65
function DaysInYear(year) {
66
  if (year % 4 != 0) return 365;
67
  if ((year % 100 == 0) && (year % 400 != 0)) return 365;
68
  return 366;
69
}
70
71
72
function DayFromYear(year) {
73
  return 365 * (year-1970)
74
      + FLOOR((year-1969)/4)
75
      - FLOOR((year-1901)/100)
76
      + FLOOR((year-1601)/400);
77
}
78
79
80
function TimeFromYear(year) {
81
  return msPerDay * DayFromYear(year);
82
}
83
84
85
function YearFromTime(time) {
86
  return FromJulianDay(Day(time) + kDayZeroInJulianDay).year;
87
}
88
89
90
function InLeapYear(time) {
91
  return DaysInYear(YearFromTime(time)) == 366 ? 1 : 0;
92
}
93
94
95
// ECMA 262 - 15.9.1.4
96
function MonthFromTime(time) {
97
  return FromJulianDay(Day(time) + kDayZeroInJulianDay).month;
98
}
99
100
101
function DayWithinYear(time) {
102
  return Day(time) - DayFromYear(YearFromTime(time));
103
}
104
105
106
// ECMA 262 - 15.9.1.5
107
function DateFromTime(time) {
108
  return FromJulianDay(Day(time) + kDayZeroInJulianDay).date;
109
}
110
111
112
// ECMA 262 - 15.9.1.9
113
function EquivalentYear(year) {
114
  // Returns an equivalent year in the range [2008-2035] matching
115
  // - leap year.
116
  // - week day of first day.
117
  var time = TimeFromYear(year);
118
  var recent_year = (InLeapYear(time) == 0 ? 1967 : 1956) + 
119
      (WeekDay(time) * 12) % 28;
120
  // Find the year in the range 2008..2037 that is equivalent mod 28.
121
  // Add 3*28 to give a positive argument to the modulus operator.
122
  return 2008 + (recent_year + 3*28 - 2008) % 28;
123
}
124
125
126
function EquivalentTime(t) {
127
  // The issue here is that some library calls don't work right for dates
128
  // that cannot be represented using a non-negative signed 32 bit integer
129
  // (measured in whole seconds based on the 1970 epoch).
130
  // We solve this by mapping the time to a year with same leap-year-ness
131
  // and same starting day for the year.  The ECMAscript specification says
132
  // we must do this, but for compatability with other browsers, we use
133
  // the actual year if it is in the range 1970..2037
134
  if (t >= 0 && t <= 2.1e12) return t;
135
  var day = MakeDay(EquivalentYear(YearFromTime(t)), MonthFromTime(t), DateFromTime(t));
136
  return TimeClip(MakeDate(day, TimeWithinDay(t)));
137
}
138
139
var daylight_cache_time = $NaN;
140
var daylight_cache_offset;
141
142
function DaylightSavingsOffset(t) {
143
  if (t == daylight_cache_time) {
144
    return daylight_cache_offset;
145
  }
146
  var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
147
  daylight_cache_time = t;
148
  daylight_cache_offset = offset;
149
  return offset;
150
}
151
152
153
var timezone_cache_time = $NaN;
154
var timezone_cache_timezone;
155
156
function LocalTimezone(t) {
157
  if(t == timezone_cache_time) {
158
    return timezone_cache_timezone;
159
  }
160
  var timezone = %DateLocalTimezone(EquivalentTime(t));
161
  timezone_cache_time = t;
162
  timezone_cache_timezone = timezone;
163
  return timezone;
164
}
165
166
167
function WeekDay(time) {
168
  return Modulo(Day(time) + 4, 7);
169
}
170
171
var local_time_offset = %DateLocalTimeOffset();
172
173
function LocalTime(time) {
174
  if ($isNaN(time)) return time;
175
  return time + local_time_offset + DaylightSavingsOffset(time);
176
}
177
178
function LocalTimeNoCheck(time) {
179
  return time + local_time_offset + DaylightSavingsOffset(time);
180
}
181
182
183
function UTC(time) {
184
  if ($isNaN(time)) return time;
185
  var tmp = time - local_time_offset;
186
  return tmp - DaylightSavingsOffset(tmp);
187
}
188
189
190
// ECMA 262 - 15.9.1.10
191
function HourFromTime(time) {
192
  return Modulo(FLOOR(time / msPerHour), HoursPerDay);
193
}
194
195
196
function MinFromTime(time) {
197
  return Modulo(FLOOR(time / msPerMinute), MinutesPerHour);
198
}
199
200
201
function SecFromTime(time) {
202
  return Modulo(FLOOR(time / msPerSecond), SecondsPerMinute);
203
}
204
205
206
function msFromTime(time) {
207
  return Modulo(time, msPerSecond);
208
}
209
210
211
// ECMA 262 - 15.9.1.11
212
function MakeTime(hour, min, sec, ms) {
213
  if (!$isFinite(hour)) return $NaN;
214
  if (!$isFinite(min)) return $NaN;
215
  if (!$isFinite(sec)) return $NaN;
216
  if (!$isFinite(ms)) return $NaN;
217
  return TO_INTEGER(hour) * msPerHour
218
      + TO_INTEGER(min) * msPerMinute
219
      + TO_INTEGER(sec) * msPerSecond
220
      + TO_INTEGER(ms);
221
}
222
223
224
// ECMA 262 - 15.9.1.12
225
function TimeInYear(year) {
226
  return DaysInYear(year) * msPerDay;
227
}
228
229
230
// Compute modified Julian day from year, month, date.
231
function ToJulianDay(year, month, date) {
232
  var jy = (month > 1) ? year : year - 1;
233
  var jm = (month > 1) ? month + 2 : month + 14;
234
  var ja = FLOOR(jy / 100);
235
  return FLOOR(FLOOR(365.25*jy) + FLOOR(30.6001*jm) + date + 1720995) + 2 - ja + FLOOR(0.25*ja);
236
}
237
238
var four_year_cycle_table = CalculateDateTable();
239
240
241
function CalculateDateTable() {
242
  var month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
243
  var four_year_cycle_table = new $Array(1461);
244
245
  var cumulative = 0;
246
  var position = 0;
247
  var leap_position = 0;
248
  for (var month = 0; month < 12; month++) {
249
    var month_bits = month << kMonthShift;
250
    var length = month_lengths[month];
251
    for (var day = 1; day <= length; day++) {
252
      four_year_cycle_table[leap_position] =
253
        month_bits + day;
254
      four_year_cycle_table[366 + position] =
255
        (1 << kYearShift) + month_bits + day;
256
      four_year_cycle_table[731 + position] =
257
        (2 << kYearShift) + month_bits + day;
258
      four_year_cycle_table[1096 + position] =
259
        (3 << kYearShift) + month_bits + day;
260
      leap_position++;
261
      position++;
262
    }
263
    if (month == 1) {
264
      four_year_cycle_table[leap_position++] = month_bits + 29;
265
    }
266
  }
267
  return four_year_cycle_table;
268
}
269
270
271
// Constructor for creating objects holding year, month, and date.
272
// Introduced to ensure the two return points in FromJulianDay match same map.
273
function DayTriplet(year, month, date) {
274
  this.year = year;
275
  this.month = month;
276
  this.date = date;
277
}
278
279
var julian_day_cache_triplet;
280
var julian_day_cache_day = $NaN;
281
282
// Compute year, month, and day from modified Julian day.
283
// The missing days in 1582 are ignored for JavaScript compatibility.
284
function FromJulianDay(julian) {
285
  if (julian_day_cache_day == julian) {
286
    return julian_day_cache_triplet;
287
  }
288
  var result;
289
  // Avoid floating point and non-Smi maths in common case.  This is also a period of
290
  // time where leap years are very regular.  The range is not too large to avoid overflow
291
  // when doing the multiply-to-divide trick.
292
  if (julian > kDayZeroInJulianDay &&
293
      (julian - kDayZeroInJulianDay) < 40177) { // 1970 - 2080
294
    var jsimple = (julian - kDayZeroInJulianDay) + 731; // Day 0 is 1st January 1968
295
    var y = 1968;
296
    // Divide by 1461 by multiplying with 22967 and shifting down by 25!
297
    var after_1968 = (jsimple * 22967) >> 25;
298
    y += after_1968 << 2;
299
    jsimple -= 1461 * after_1968;
300
    var four_year_cycle = four_year_cycle_table[jsimple];
301
    result = new DayTriplet(y + (four_year_cycle >> kYearShift),
302
                            (four_year_cycle & kMonthMask) >> kMonthShift,
303
                            four_year_cycle & kDayMask);
304
  } else {
305
    var jalpha = FLOOR((julian - 1867216.25) / 36524.25);
306
    var jb = julian + 1 + jalpha - FLOOR(0.25 * jalpha) + 1524;
307
    var jc = FLOOR(6680.0 + ((jb-2439870) - 122.1)/365.25);
308
    var jd = FLOOR(365 * jc + (0.25 * jc));
309
    var je = FLOOR((jb - jd)/30.6001);
310
    var m = je - 1;
311
    if (m > 12) m -= 13;
312
    var y = jc - 4715;
313
    if (m > 2) { --y; --m; }
314
    var d = jb - jd - FLOOR(30.6001 * je);
315
    result = new DayTriplet(y, m, d);
316
  }
317
  julian_day_cache_day = julian;
318
  julian_day_cache_triplet = result;
319
  return result;
320
}
321
322
323
// Compute number of days given a year, month, date.
324
// Note that month and date can lie outside the normal range.
325
//   For example:
326
//     MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
327
//     MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
328
//     MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
329
function MakeDay(year, month, date) {
330
  if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return $NaN;
331
332
  // Conversion to integers.
333
  year = TO_INTEGER(year);
334
  month = TO_INTEGER(month);
335
  date = TO_INTEGER(date);
336
337
  // Overflow months into year.
338
  year = year + FLOOR(month/12);
339
  month = month % 12;
340
  if (month < 0) {
341
    month += 12;
342
  }
343
344
  // Return days relative to Jan 1 1970.
345
  return ToJulianDay(year, month, date) - kDayZeroInJulianDay;
346
}
347
348
349
// ECMA 262 - 15.9.1.13
350
function MakeDate(day, time) {
351
  if (!$isFinite(day)) return $NaN;
352
  if (!$isFinite(time)) return $NaN;
353
  return day * msPerDay + time;
354
}
355
356
357
// ECMA 262 - 15.9.1.14
358
function TimeClip(time) {
359
  if (!$isFinite(time)) return $NaN;
360
  if ($abs(time) > 8.64E15) return $NaN;
361
  return TO_INTEGER(time);
362
}
363
364
365
%SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
366
  if (%IsConstructCall()) {
367
    // ECMA 262 - 15.9.3
368
    var argc = %_ArgumentsLength();
369
    if (argc == 0) {
370
      %_SetValueOf(this, %DateCurrentTime());
371
      return;
372
    }
373
    if (argc == 1) {
374
      // According to ECMA 262, no hint should be given for this
375
      // conversion.  However, ToPrimitive defaults to String Hint
376
      // for Date objects which will lose precision when the Date
377
      // constructor is called with another Date object as its
378
      // argument.  We therefore use Number Hint for the conversion
379
      // (which is the default for everything else than Date
380
      // objects).  This makes us behave like KJS and SpiderMonkey.
381
      var time = ToPrimitive(year, NUMBER_HINT);
382
      if (IS_STRING(time)) {
383
        %_SetValueOf(this, DateParse(time));
384
      } else {
385
        %_SetValueOf(this, TimeClip(ToNumber(time)));
386
      }
387
      return;
388
    }
389
    year = ToNumber(year);
390
    month = ToNumber(month);
391
    date = argc > 2 ? ToNumber(date) : 1;
392
    hours = argc > 3 ? ToNumber(hours) : 0;
393
    minutes = argc > 4 ? ToNumber(minutes) : 0;
394
    seconds = argc > 5 ? ToNumber(seconds) : 0;
395
    ms = argc > 6 ? ToNumber(ms) : 0;
396
    year = (!$isNaN(year) && 0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
397
        ? 1900 + TO_INTEGER(year) : year;
398
    var day = MakeDay(year, month, date);
399
    var time = MakeTime(hours, minutes, seconds, ms);
400
    %_SetValueOf(this, TimeClip(UTC(MakeDate(day, time))));
401
  } else {
402
    // ECMA 262 - 15.9.2
403
    return (new $Date()).toString();
404
  }
405
});
406
407
408
// Helper functions.
409
function GetTimeFrom(aDate) {
410
  if (IS_DATE(aDate)) return %_ValueOf(aDate);
411
  throw new $TypeError('this is not a Date object.');
412
}
413
414
415
function GetMillisecondsFrom(aDate) {
416
  var t = GetTimeFrom(aDate);
417
  if ($isNaN(t)) return t;
418
  return msFromTime(LocalTimeNoCheck(t));
419
}
420
421
422
function GetUTCMillisecondsFrom(aDate) {
423
  var t = GetTimeFrom(aDate);
424
  if ($isNaN(t)) return t;
425
  return msFromTime(t);
426
}
427
428
429
function GetSecondsFrom(aDate) {
430
  var t = GetTimeFrom(aDate);
431
  if ($isNaN(t)) return t;
432
  return SecFromTime(LocalTimeNoCheck(t));
433
}
434
435
436
function GetUTCSecondsFrom(aDate) {
437
  var t = GetTimeFrom(aDate);
438
  if ($isNaN(t)) return t;
439
  return SecFromTime(t);
440
}
441
442
443
function GetMinutesFrom(aDate) {
444
  var t = GetTimeFrom(aDate);
445
  if ($isNaN(t)) return t;
446
  return MinFromTime(LocalTimeNoCheck(t));
447
}
448
449
450
function GetUTCMinutesFrom(aDate) {
451
  var t = GetTimeFrom(aDate);
452
  if ($isNaN(t)) return t;
453
  return MinFromTime(t);
454
}
455
456
457
function GetHoursFrom(aDate) {
458
  var t = GetTimeFrom(aDate);
459
  if ($isNaN(t)) return t;
460
  return HourFromTime(LocalTimeNoCheck(t));
461
}
462
463
464
function GetUTCHoursFrom(aDate) {
465
  var t = GetTimeFrom(aDate);
466
  if ($isNaN(t)) return t;
467
  return HourFromTime(t);
468
}
469
470
471
function GetFullYearFrom(aDate) {
472
  var t = GetTimeFrom(aDate);
473
  if ($isNaN(t)) return t;
474
  return YearFromTime(LocalTimeNoCheck(t));
475
}
476
477
478
function GetUTCFullYearFrom(aDate) {
479
  var t = GetTimeFrom(aDate);
480
  if ($isNaN(t)) return t;
481
  return YearFromTime(t);
482
}
483
484
485
function GetMonthFrom(aDate) {
486
  var t = GetTimeFrom(aDate);
487
  if ($isNaN(t)) return t;
488
  return MonthFromTime(LocalTimeNoCheck(t));
489
}
490
491
492
function GetUTCMonthFrom(aDate) {
493
  var t = GetTimeFrom(aDate);
494
  if ($isNaN(t)) return t;
495
  return MonthFromTime(t);
496
}
497
498
499
function GetDateFrom(aDate) {
500
  var t = GetTimeFrom(aDate);
501
  if ($isNaN(t)) return t;
502
  return DateFromTime(LocalTimeNoCheck(t));
503
}
504
505
506
function GetUTCDateFrom(aDate) {
507
  var t = GetTimeFrom(aDate);
508
  if ($isNaN(t)) return t;
509
  return DateFromTime(t);
510
}
511
512
513
%FunctionSetPrototype($Date, new $Date($NaN));
514
515
516
var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
517
var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
518
519
520
function TwoDigitString(value) {
521
  return value < 10 ? "0" + value : "" + value;
522
}
523
524
525
function DateString(time) {
526
  var YMD = FromJulianDay(Day(time) + kDayZeroInJulianDay);
527
  return WeekDays[WeekDay(time)] + ' '
528
      + Months[YMD.month] + ' '
529
      + TwoDigitString(YMD.date) + ' '
530
      + YMD.year;
531
}
532
533
534
var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
535
var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
536
537
538
function LongDateString(time) {
539
  var YMD = FromJulianDay(Day(time) + kDayZeroInJulianDay);
540
  return LongWeekDays[WeekDay(time)] + ', '
541
      + LongMonths[YMD.month] + ' '
542
      + TwoDigitString(YMD.date) + ', '
543
      + YMD.year;
544
}
545
546
547
function TimeString(time) {
548
  return TwoDigitString(HourFromTime(time)) + ':'
549
      + TwoDigitString(MinFromTime(time)) + ':'
550
      + TwoDigitString(SecFromTime(time));
551
}
552
553
554
function LocalTimezoneString(time) {
555
  var timezoneOffset = (local_time_offset + DaylightSavingsOffset(time)) / msPerMinute;
556
  var sign = (timezoneOffset >= 0) ? 1 : -1;
557
  var hours = FLOOR((sign * timezoneOffset)/60);
558
  var min   = FLOOR((sign * timezoneOffset)%60);
559
  var gmt = ' GMT' + ((sign == 1) ? '+' : '-') + TwoDigitString(hours) + TwoDigitString(min);
560
  return gmt + ' (' +  LocalTimezone(time) + ')';
561
}
562
563
564
function DatePrintString(time) {
565
  return DateString(time) + ' ' + TimeString(time);
566
}
567
568
// -------------------------------------------------------------------
569
570
// Reused output buffer.
571
var parse_buffer = $Array(7);
572
573
// ECMA 262 - 15.9.4.2
574
function DateParse(string) {
575
  var arr = %DateParseString(ToString(string), parse_buffer);
576
  if (IS_NULL(arr)) return $NaN;
577
578
  var day = MakeDay(arr[0], arr[1], arr[2]);
579
  var time = MakeTime(arr[3], arr[4], arr[5], 0);
580
  var date = MakeDate(day, time);
581
582
  if (IS_NULL(arr[6])) {
583
    return TimeClip(UTC(date));
584
  } else {
585
    return TimeClip(date - arr[6] * 1000);
586
  }
587
}
588
589
590
// ECMA 262 - 15.9.4.3
591
function DateUTC(year, month, date, hours, minutes, seconds, ms) {
592
  year = ToNumber(year);
593
  month = ToNumber(month);
594
  var argc = %_ArgumentsLength();
595
  date = argc > 2 ? ToNumber(date) : 1;
596
  hours = argc > 3 ? ToNumber(hours) : 0;
597
  minutes = argc > 4 ? ToNumber(minutes) : 0;
598
  seconds = argc > 5 ? ToNumber(seconds) : 0;
599
  ms = argc > 6 ? ToNumber(ms) : 0;
600
  year = (!$isNaN(year) && 0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
601
      ? 1900 + TO_INTEGER(year) : year;
602
  var day = MakeDay(year, month, date);
603
  var time = MakeTime(hours, minutes, seconds, ms);
604
  return %_SetValueOf(this, TimeClip(MakeDate(day, time)));
605
}
606
607
608
// Mozilla-specific extension. Returns the number of milliseconds
609
// elapsed since 1 January 1970 00:00:00 UTC.
610
function DateNow() {
611
  return %DateCurrentTime();
612
}
613
614
615
// ECMA 262 - 15.9.5.2
616
function DateToString() {
617
  var t = GetTimeFrom(this);
618
  if ($isNaN(t)) return kInvalidDate;
619
  return DatePrintString(LocalTimeNoCheck(t)) + LocalTimezoneString(t);
620
}
621
622
623
// ECMA 262 - 15.9.5.3
624
function DateToDateString() {
625
  var t = GetTimeFrom(this);
626
  if ($isNaN(t)) return kInvalidDate;
627
  return DateString(LocalTimeNoCheck(t));
628
}
629
630
631
// ECMA 262 - 15.9.5.4
632
function DateToTimeString() {
633
  var t = GetTimeFrom(this);
634
  if ($isNaN(t)) return kInvalidDate;
635
  var lt = LocalTimeNoCheck(t);
636
  return TimeString(lt) + LocalTimezoneString(lt);
637
}
638
639
640
// ECMA 262 - 15.9.5.5
641
function DateToLocaleString() {
642
  return DateToString.call(this);
643
}
644
645
646
// ECMA 262 - 15.9.5.6
647
function DateToLocaleDateString() {
648
  var t = GetTimeFrom(this);
649
  if ($isNaN(t)) return kInvalidDate;
650
  return LongDateString(LocalTimeNoCheck(t));
651
}
652
653
654
// ECMA 262 - 15.9.5.7
655
function DateToLocaleTimeString() {
656
  var t = GetTimeFrom(this);
657
  if ($isNaN(t)) return kInvalidDate;
658
  var lt = LocalTimeNoCheck(t);
659
  return TimeString(lt);
660
}
661
662
663
// ECMA 262 - 15.9.5.8
664
function DateValueOf() {
665
  return GetTimeFrom(this);
666
}
667
668
669
// ECMA 262 - 15.9.5.9
670
function DateGetTime() {
671
  return GetTimeFrom(this);
672
}
673
674
675
// ECMA 262 - 15.9.5.10
676
function DateGetFullYear() {
677
  return GetFullYearFrom(this)
678
}
679
680
681
// ECMA 262 - 15.9.5.11
682
function DateGetUTCFullYear() {
683
  return GetUTCFullYearFrom(this)
684
}
685
686
687
// ECMA 262 - 15.9.5.12
688
function DateGetMonth() {
689
  return GetMonthFrom(this);
690
}
691
692
693
// ECMA 262 - 15.9.5.13
694
function DateGetUTCMonth() {
695
  return GetUTCMonthFrom(this);
696
}
697
698
699
// ECMA 262 - 15.9.5.14
700
function DateGetDate() {
701
  return GetDateFrom(this);
702
}
703
704
705
// ECMA 262 - 15.9.5.15
706
function DateGetUTCDate() {
707
  return GetUTCDateFrom(this);
708
}
709
710
711
// ECMA 262 - 15.9.5.16
712
function DateGetDay() {
713
  var t = GetTimeFrom(this);
714
  if ($isNaN(t)) return t;
715
  return WeekDay(LocalTimeNoCheck(t));
716
}
717
718
719
// ECMA 262 - 15.9.5.17
720
function DateGetUTCDay() {
721
  var t = GetTimeFrom(this);
722
  if ($isNaN(t)) return t;
723
  return WeekDay(t);
724
}
725
726
727
// ECMA 262 - 15.9.5.18
728
function DateGetHours() {
729
  return GetHoursFrom(this);
730
}
731
732
733
// ECMA 262 - 15.9.5.19
734
function DateGetUTCHours() {
735
  return GetUTCHoursFrom(this);
736
}
737
738
739
// ECMA 262 - 15.9.5.20
740
function DateGetMinutes() {
741
  return GetMinutesFrom(this);
742
}
743
744
745
// ECMA 262 - 15.9.5.21
746
function DateGetUTCMinutes() {
747
  return GetUTCMinutesFrom(this);
748
}
749
750
751
// ECMA 262 - 15.9.5.22
752
function DateGetSeconds() {
753
  return GetSecondsFrom(this);
754
}
755
756
757
// ECMA 262 - 15.9.5.23
758
function DateGetUTCSeconds() {
759
  return GetUTCSecondsFrom(this);
760
}
761
762
763
// ECMA 262 - 15.9.5.24
764
function DateGetMilliseconds() {
765
  return GetMillisecondsFrom(this);
766
}
767
768
769
// ECMA 262 - 15.9.5.25
770
function DateGetUTCMilliseconds() {
771
  return GetUTCMillisecondsFrom(this);
772
}
773
774
775
// ECMA 262 - 15.9.5.26
776
function DateGetTimezoneOffset() {
777
  var t = GetTimeFrom(this);
778
  if ($isNaN(t)) return t;
779
  return (t - LocalTimeNoCheck(t)) / msPerMinute;
780
}
781
782
783
// ECMA 262 - 15.9.5.27
784
function DateSetTime(ms) {
785
  if (!IS_DATE(this)) throw new $TypeError('this is not a Date object.');
786
  return %_SetValueOf(this, TimeClip(ToNumber(ms)));
787
}
788
789
790
// ECMA 262 - 15.9.5.28
791
function DateSetMilliseconds(ms) {
792
  var t = LocalTime(GetTimeFrom(this));
793
  ms = ToNumber(ms);
794
  var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms);
795
  return %_SetValueOf(this, TimeClip(UTC(MakeDate(Day(t), time))));
796
}
797
798
799
// ECMA 262 - 15.9.5.29
800
function DateSetUTCMilliseconds(ms) {
801
  var t = GetTimeFrom(this);
802
  ms = ToNumber(ms);
803
  var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms);
804
  return %_SetValueOf(this, TimeClip(MakeDate(Day(t), time)));
805
}
806
807
808
// ECMA 262 - 15.9.5.30
809
function DateSetSeconds(sec, ms) {
810
  var t = LocalTime(GetTimeFrom(this));
811
  sec = ToNumber(sec);
812
  ms = %_ArgumentsLength() < 2 ? GetMillisecondsFrom(this) : ToNumber(ms);
813
  var time = MakeTime(HourFromTime(t), MinFromTime(t), sec, ms);
814
  return %_SetValueOf(this, TimeClip(UTC(MakeDate(Day(t), time))));
815
}
816
817
818
// ECMA 262 - 15.9.5.31
819
function DateSetUTCSeconds(sec, ms) {
820
  var t = GetTimeFrom(this);
821
  sec = ToNumber(sec);
822
  ms = %_ArgumentsLength() < 2 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
823
  var time = MakeTime(HourFromTime(t), MinFromTime(t), sec, ms);
824
  return %_SetValueOf(this, TimeClip(MakeDate(Day(t), time)));
825
}
826
827
828
// ECMA 262 - 15.9.5.33
829
function DateSetMinutes(min, sec, ms) {
830
  var t = LocalTime(GetTimeFrom(this));
831
  min = ToNumber(min);
832
  var argc = %_ArgumentsLength();
833
  sec = argc < 2 ? GetSecondsFrom(this) : ToNumber(sec);
834
  ms = argc < 3 ? GetMillisecondsFrom(this) : ToNumber(ms);
835
  var time = MakeTime(HourFromTime(t), min, sec, ms);
836
  return %_SetValueOf(this, TimeClip(UTC(MakeDate(Day(t), time))));
837
}
838
839
840
// ECMA 262 - 15.9.5.34
841
function DateSetUTCMinutes(min, sec, ms) {
842
  var t = GetTimeFrom(this);
843
  min = ToNumber(min);
844
  var argc = %_ArgumentsLength();
845
  sec = argc < 2 ? GetUTCSecondsFrom(this) : ToNumber(sec);
846
  ms = argc < 3 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
847
  var time = MakeTime(HourFromTime(t), min, sec, ms);
848
  return %_SetValueOf(this, TimeClip(MakeDate(Day(t), time)));
849
}
850
851
852
// ECMA 262 - 15.9.5.35
853
function DateSetHours(hour, min, sec, ms) {
854
  var t = LocalTime(GetTimeFrom(this));
855
  hour = ToNumber(hour);
856
  var argc = %_ArgumentsLength();
857
  min = argc < 2 ? GetMinutesFrom(this) : ToNumber(min);
858
  sec = argc < 3 ? GetSecondsFrom(this) : ToNumber(sec);
859
  ms = argc < 4 ? GetMillisecondsFrom(this) : ToNumber(ms);
860
  var time = MakeTime(hour, min, sec, ms);
861
  return %_SetValueOf(this, TimeClip(UTC(MakeDate(Day(t), time))));
862
}
863
864
865
// ECMA 262 - 15.9.5.34
866
function DateSetUTCHours(hour, min, sec, ms) {
867
  var t = GetTimeFrom(this);
868
  hour = ToNumber(hour);
869
  var argc = %_ArgumentsLength();
870
  min = argc < 2 ? GetUTCMinutesFrom(this) : ToNumber(min);
871
  sec = argc < 3 ? GetUTCSecondsFrom(this) : ToNumber(sec);
872
  ms = argc < 4 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
873
  var time = MakeTime(hour, min, sec, ms);
874
  return %_SetValueOf(this, TimeClip(MakeDate(Day(t), time)));
875
}
876
877
878
// ECMA 262 - 15.9.5.36
879
function DateSetDate(date) {
880
  var t = LocalTime(GetTimeFrom(this));
881
  date = ToNumber(date);
882
  var day = MakeDay(YearFromTime(t), MonthFromTime(t), date);
883
  return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
884
}
885
886
887
// ECMA 262 - 15.9.5.37
888
function DateSetUTCDate(date) {
889
  var t = GetTimeFrom(this);
890
  date = ToNumber(date);
891
  var day = MakeDay(YearFromTime(t), MonthFromTime(t), date);
892
  return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
893
}
894
895
896
// ECMA 262 - 15.9.5.38
897
function DateSetMonth(month, date) {
898
  var t = LocalTime(GetTimeFrom(this));
899
  month = ToNumber(month);
900
  date = %_ArgumentsLength() < 2 ? GetDateFrom(this) : ToNumber(date);
901
  var day = MakeDay(YearFromTime(t), month, date);
902
  return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
903
}
904
905
906
// ECMA 262 - 15.9.5.39
907
function DateSetUTCMonth(month, date) {
908
  var t = GetTimeFrom(this);
909
  month = ToNumber(month);
910
  date = %_ArgumentsLength() < 2 ? GetUTCDateFrom(this) : ToNumber(date);
911
  var day = MakeDay(YearFromTime(t), month, date);
912
  return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
913
}
914
915
916
// ECMA 262 - 15.9.5.40
917
function DateSetFullYear(year, month, date) {
918
  var t = GetTimeFrom(this);
919
  t = $isNaN(t) ? 0 : LocalTimeNoCheck(t);
920
  year = ToNumber(year);
921
  var argc = %_ArgumentsLength();
922
  month = argc < 2 ? MonthFromTime(t) : ToNumber(month);
923
  date = argc < 3 ? DateFromTime(t) : ToNumber(date);
924
  var day = MakeDay(year, month, date);
925
  return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
926
}
927
928
929
// ECMA 262 - 15.9.5.41
930
function DateSetUTCFullYear(year, month, date) {
931
  var t = GetTimeFrom(this);
932
  if ($isNaN(t)) t = 0;
933
  var argc = %_ArgumentsLength();
934
  year = ToNumber(year);
935
  month = argc < 2 ? MonthFromTime(t) : ToNumber(month);
936
  date = argc < 3 ? DateFromTime(t) : ToNumber(date);
937
  var day = MakeDay(year, month, date);
938
  return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
939
}
940
941
942
// ECMA 262 - 15.9.5.42
943
function DateToUTCString() {
944
  var t = GetTimeFrom(this);
945
  if ($isNaN(t)) return kInvalidDate;
946
  // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
947
  return WeekDays[WeekDay(t)] + ', '
948
      + TwoDigitString(DateFromTime(t)) + ' '
949
      + Months[MonthFromTime(t)] + ' '
950
      + YearFromTime(t) + ' '
951
      + TimeString(t) + ' GMT';
952
}
953
954
955
// ECMA 262 - B.2.4
956
function DateGetYear() {
957
  var t = GetTimeFrom(this);
958
  if ($isNaN(t)) return $NaN;
959
  return YearFromTime(LocalTimeNoCheck(t)) - 1900;
960
}
961
962
963
// ECMA 262 - B.2.5
964
function DateSetYear(year) {
965
  var t = LocalTime(GetTimeFrom(this));
966
  if ($isNaN(t)) t = 0;
967
  year = ToNumber(year);
968
  if ($isNaN(year)) return %_SetValueOf(this, $NaN);
969
  year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
970
      ? 1900 + TO_INTEGER(year) : year;
971
  var day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
972
  return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
973
}
974
975
976
// ECMA 262 - B.2.6
977
//
978
// Notice that this does not follow ECMA 262 completely.  ECMA 262
979
// says that toGMTString should be the same Function object as
980
// toUTCString.  JSC does not do this, so for compatibility we do not
981
// do that either.  Instead, we create a new function whose name
982
// property will return toGMTString.
983
function DateToGMTString() {
984
  return DateToUTCString.call(this);
985
}
986
987
988
// -------------------------------------------------------------------
989
990
function SetupDate() {
991
  // Setup non-enumerable properties of the Date object itself.
992
  InstallFunctions($Date, DONT_ENUM, $Array(
993
    "UTC", DateUTC,
994
    "parse", DateParse,
995
    "now", DateNow
996
  ));
997
998
  // Setup non-enumerable constructor property of the Date prototype object.
999
  %SetProperty($Date.prototype, "constructor", $Date, DONT_ENUM);
1000
1001
  // Setup non-enumerable functions of the Date prototype object and
1002
  // set their names.
1003
  InstallFunctions($Date.prototype, DONT_ENUM, $Array(
1004
    "toString", DateToString,
1005
    "toDateString", DateToDateString,
1006
    "toTimeString", DateToTimeString,
1007
    "toLocaleString", DateToLocaleString,
1008
    "toLocaleDateString", DateToLocaleDateString,
1009
    "toLocaleTimeString", DateToLocaleTimeString,
1010
    "valueOf", DateValueOf,
1011
    "getTime", DateGetTime,
1012
    "getFullYear", DateGetFullYear,
1013
    "getUTCFullYear", DateGetUTCFullYear,
1014
    "getMonth", DateGetMonth,
1015
    "getUTCMonth", DateGetUTCMonth,
1016
    "getDate", DateGetDate,
1017
    "getUTCDate", DateGetUTCDate,
1018
    "getDay", DateGetDay,
1019
    "getUTCDay", DateGetUTCDay,
1020
    "getHours", DateGetHours,
1021
    "getUTCHours", DateGetUTCHours,
1022
    "getMinutes", DateGetMinutes,
1023
    "getUTCMinutes", DateGetUTCMinutes,
1024
    "getSeconds", DateGetSeconds,
1025
    "getUTCSeconds", DateGetUTCSeconds,
1026
    "getMilliseconds", DateGetMilliseconds,
1027
    "getUTCMilliseconds", DateGetUTCMilliseconds,
1028
    "getTimezoneOffset", DateGetTimezoneOffset,
1029
    "setTime", DateSetTime,
1030
    "setMilliseconds", DateSetMilliseconds,
1031
    "setUTCMilliseconds", DateSetUTCMilliseconds,
1032
    "setSeconds", DateSetSeconds,
1033
    "setUTCSeconds", DateSetUTCSeconds,
1034
    "setMinutes", DateSetMinutes,
1035
    "setUTCMinutes", DateSetUTCMinutes,
1036
    "setHours", DateSetHours,
1037
    "setUTCHours", DateSetUTCHours,
1038
    "setDate", DateSetDate,
1039
    "setUTCDate", DateSetUTCDate,
1040
    "setMonth", DateSetMonth,
1041
    "setUTCMonth", DateSetUTCMonth,
1042
    "setFullYear", DateSetFullYear,
1043
    "setUTCFullYear", DateSetUTCFullYear,
1044
    "toGMTString", DateToGMTString,
1045
    "toUTCString", DateToUTCString,
1046
    "getYear", DateGetYear,
1047
    "setYear", DateSetYear
1048
  ));
1049
}
1050
1051
SetupDate();