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.js @ f230a1cf

History | View | Annotate | Download (22.3 KB)

1
// 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
// This file relies on the fact that the following declarations have been made
29
// in v8natives.js:
30
// var $isFinite = GlobalIsFinite;
31

    
32
var $Date = global.Date;
33

    
34
// -------------------------------------------------------------------
35

    
36
// This file contains date support implemented in JavaScript.
37

    
38
// Helper function to throw error.
39
function ThrowDateTypeError() {
40
  throw new $TypeError('this is not a Date object.');
41
}
42

    
43

    
44
var timezone_cache_time = NAN;
45
var timezone_cache_timezone;
46

    
47
function LocalTimezone(t) {
48
  if (NUMBER_IS_NAN(t)) return "";
49
  if (t == timezone_cache_time) {
50
    return timezone_cache_timezone;
51
  }
52
  var timezone = %DateLocalTimezone(t);
53
  timezone_cache_time = t;
54
  timezone_cache_timezone = timezone;
55
  return timezone;
56
}
57

    
58

    
59
function UTC(time) {
60
  if (NUMBER_IS_NAN(time)) return time;
61
  // local_time_offset is needed before the call to DaylightSavingsOffset,
62
  // so it may be uninitialized.
63
  return %DateToUTC(time);
64
}
65

    
66

    
67
// ECMA 262 - 15.9.1.11
68
function MakeTime(hour, min, sec, ms) {
69
  if (!$isFinite(hour)) return NAN;
70
  if (!$isFinite(min)) return NAN;
71
  if (!$isFinite(sec)) return NAN;
72
  if (!$isFinite(ms)) return NAN;
73
  return TO_INTEGER(hour) * msPerHour
74
      + TO_INTEGER(min) * msPerMinute
75
      + TO_INTEGER(sec) * msPerSecond
76
      + TO_INTEGER(ms);
77
}
78

    
79

    
80
// ECMA 262 - 15.9.1.12
81
function TimeInYear(year) {
82
  return DaysInYear(year) * msPerDay;
83
}
84

    
85

    
86
// Compute number of days given a year, month, date.
87
// Note that month and date can lie outside the normal range.
88
//   For example:
89
//     MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
90
//     MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
91
//     MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
92
function MakeDay(year, month, date) {
93
  if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return NAN;
94

    
95
  // Convert to integer and map -0 to 0.
96
  year = TO_INTEGER_MAP_MINUS_ZERO(year);
97
  month = TO_INTEGER_MAP_MINUS_ZERO(month);
98
  date = TO_INTEGER_MAP_MINUS_ZERO(date);
99

    
100
  if (year < kMinYear || year > kMaxYear ||
101
      month < kMinMonth || month > kMaxMonth) {
102
    return NAN;
103
  }
104

    
105
  // Now we rely on year and month being SMIs.
106
  return %DateMakeDay(year | 0, month | 0) + date - 1;
107
}
108

    
109

    
110
// ECMA 262 - 15.9.1.13
111
function MakeDate(day, time) {
112
  var time = day * msPerDay + time;
113
  // Some of our runtime funtions for computing UTC(time) rely on
114
  // times not being significantly larger than MAX_TIME_MS. If there
115
  // is no way that the time can be within range even after UTC
116
  // conversion we return NaN immediately instead of relying on
117
  // TimeClip to do it.
118
  if ($abs(time) > MAX_TIME_BEFORE_UTC) return NAN;
119
  return time;
120
}
121

    
122

    
123
// ECMA 262 - 15.9.1.14
124
function TimeClip(time) {
125
  if (!$isFinite(time)) return NAN;
126
  if ($abs(time) > MAX_TIME_MS) return NAN;
127
  return TO_INTEGER(time);
128
}
129

    
130

    
131
// The Date cache is used to limit the cost of parsing the same Date
132
// strings over and over again.
133
var Date_cache = {
134
  // Cached time value.
135
  time: NAN,
136
  // String input for which the cached time is valid.
137
  string: null
138
};
139

    
140

    
141
function DateConstructor(year, month, date, hours, minutes, seconds, ms) {
142
  if (!%_IsConstructCall()) {
143
    // ECMA 262 - 15.9.2
144
    return (new $Date()).toString();
145
  }
146

    
147
  // ECMA 262 - 15.9.3
148
  var argc = %_ArgumentsLength();
149
  var value;
150
  if (argc == 0) {
151
    value = %DateCurrentTime();
152
    SET_UTC_DATE_VALUE(this, value);
153
  } else if (argc == 1) {
154
    if (IS_NUMBER(year)) {
155
      value = year;
156
    } else if (IS_STRING(year)) {
157
      // Probe the Date cache. If we already have a time value for the
158
      // given time, we re-use that instead of parsing the string again.
159
      var cache = Date_cache;
160
      if (cache.string === year) {
161
        value = cache.time;
162
      } else {
163
        value = DateParse(year);
164
        if (!NUMBER_IS_NAN(value)) {
165
          cache.time = value;
166
          cache.string = year;
167
        }
168
      }
169

    
170
    } else {
171
      // According to ECMA 262, no hint should be given for this
172
      // conversion. However, ToPrimitive defaults to STRING_HINT for
173
      // Date objects which will lose precision when the Date
174
      // constructor is called with another Date object as its
175
      // argument. We therefore use NUMBER_HINT for the conversion,
176
      // which is the default for everything else than Date objects.
177
      // This makes us behave like KJS and SpiderMonkey.
178
      var time = ToPrimitive(year, NUMBER_HINT);
179
      value = IS_STRING(time) ? DateParse(time) : ToNumber(time);
180
    }
181
    SET_UTC_DATE_VALUE(this, value);
182
  } else {
183
    year = ToNumber(year);
184
    month = ToNumber(month);
185
    date = argc > 2 ? ToNumber(date) : 1;
186
    hours = argc > 3 ? ToNumber(hours) : 0;
187
    minutes = argc > 4 ? ToNumber(minutes) : 0;
188
    seconds = argc > 5 ? ToNumber(seconds) : 0;
189
    ms = argc > 6 ? ToNumber(ms) : 0;
190
    year = (!NUMBER_IS_NAN(year) &&
191
            0 <= TO_INTEGER(year) &&
192
            TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
193
    var day = MakeDay(year, month, date);
194
    var time = MakeTime(hours, minutes, seconds, ms);
195
    value = MakeDate(day, time);
196
    SET_LOCAL_DATE_VALUE(this, value);
197
  }
198
}
199

    
200

    
201
var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
202
var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
203
              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
204

    
205

    
206
function TwoDigitString(value) {
207
  return value < 10 ? "0" + value : "" + value;
208
}
209

    
210

    
211
function DateString(date) {
212
  return WeekDays[LOCAL_WEEKDAY(date)] + ' '
213
      + Months[LOCAL_MONTH(date)] + ' '
214
      + TwoDigitString(LOCAL_DAY(date)) + ' '
215
      + LOCAL_YEAR(date);
216
}
217

    
218

    
219
var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
220
    'Thursday', 'Friday', 'Saturday'];
221
var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June',
222
    'July', 'August', 'September', 'October', 'November', 'December'];
223

    
224

    
225
function LongDateString(date) {
226
  return LongWeekDays[LOCAL_WEEKDAY(date)] + ', '
227
      + LongMonths[LOCAL_MONTH(date)] + ' '
228
      + TwoDigitString(LOCAL_DAY(date)) + ', '
229
      + LOCAL_YEAR(date);
230
}
231

    
232

    
233
function TimeString(date) {
234
  return TwoDigitString(LOCAL_HOUR(date)) + ':'
235
      + TwoDigitString(LOCAL_MIN(date)) + ':'
236
      + TwoDigitString(LOCAL_SEC(date));
237
}
238

    
239

    
240
function TimeStringUTC(date) {
241
  return TwoDigitString(UTC_HOUR(date)) + ':'
242
      + TwoDigitString(UTC_MIN(date)) + ':'
243
      + TwoDigitString(UTC_SEC(date));
244
}
245

    
246

    
247
function LocalTimezoneString(date) {
248
  var timezone = LocalTimezone(UTC_DATE_VALUE(date));
249

    
250
  var timezoneOffset = -TIMEZONE_OFFSET(date);
251
  var sign = (timezoneOffset >= 0) ? 1 : -1;
252
  var hours = FLOOR((sign * timezoneOffset)/60);
253
  var min   = FLOOR((sign * timezoneOffset)%60);
254
  var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
255
      TwoDigitString(hours) + TwoDigitString(min);
256
  return gmt + ' (' +  timezone + ')';
257
}
258

    
259

    
260
function DatePrintString(date) {
261
  return DateString(date) + ' ' + TimeString(date);
262
}
263

    
264
// -------------------------------------------------------------------
265

    
266
// Reused output buffer. Used when parsing date strings.
267
var parse_buffer = $Array(8);
268

    
269
// ECMA 262 - 15.9.4.2
270
function DateParse(string) {
271
  var arr = %DateParseString(ToString(string), parse_buffer);
272
  if (IS_NULL(arr)) return NAN;
273

    
274
  var day = MakeDay(arr[0], arr[1], arr[2]);
275
  var time = MakeTime(arr[3], arr[4], arr[5], arr[6]);
276
  var date = MakeDate(day, time);
277

    
278
  if (IS_NULL(arr[7])) {
279
    return TimeClip(UTC(date));
280
  } else {
281
    return TimeClip(date - arr[7] * 1000);
282
  }
283
}
284

    
285

    
286
// ECMA 262 - 15.9.4.3
287
function DateUTC(year, month, date, hours, minutes, seconds, ms) {
288
  year = ToNumber(year);
289
  month = ToNumber(month);
290
  var argc = %_ArgumentsLength();
291
  date = argc > 2 ? ToNumber(date) : 1;
292
  hours = argc > 3 ? ToNumber(hours) : 0;
293
  minutes = argc > 4 ? ToNumber(minutes) : 0;
294
  seconds = argc > 5 ? ToNumber(seconds) : 0;
295
  ms = argc > 6 ? ToNumber(ms) : 0;
296
  year = (!NUMBER_IS_NAN(year) &&
297
          0 <= TO_INTEGER(year) &&
298
          TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
299
  var day = MakeDay(year, month, date);
300
  var time = MakeTime(hours, minutes, seconds, ms);
301
  return TimeClip(MakeDate(day, time));
302
}
303

    
304

    
305
// Mozilla-specific extension. Returns the number of milliseconds
306
// elapsed since 1 January 1970 00:00:00 UTC.
307
function DateNow() {
308
  return %DateCurrentTime();
309
}
310

    
311

    
312
// ECMA 262 - 15.9.5.2
313
function DateToString() {
314
  var t = UTC_DATE_VALUE(this)
315
  if (NUMBER_IS_NAN(t)) return kInvalidDate;
316
  var time_zone_string = LocalTimezoneString(this)
317
  return DatePrintString(this) + time_zone_string;
318
}
319

    
320

    
321
// ECMA 262 - 15.9.5.3
322
function DateToDateString() {
323
  var t = UTC_DATE_VALUE(this);
324
  if (NUMBER_IS_NAN(t)) return kInvalidDate;
325
  return DateString(this);
326
}
327

    
328

    
329
// ECMA 262 - 15.9.5.4
330
function DateToTimeString() {
331
  var t = UTC_DATE_VALUE(this);
332
  if (NUMBER_IS_NAN(t)) return kInvalidDate;
333
  var time_zone_string = LocalTimezoneString(this);
334
  return TimeString(this) + time_zone_string;
335
}
336

    
337

    
338
// ECMA 262 - 15.9.5.5
339
function DateToLocaleString() {
340
  return %_CallFunction(this, DateToString);
341
}
342

    
343

    
344
// ECMA 262 - 15.9.5.6
345
function DateToLocaleDateString() {
346
  var t = UTC_DATE_VALUE(this);
347
  if (NUMBER_IS_NAN(t)) return kInvalidDate;
348
  return LongDateString(this);
349
}
350

    
351

    
352
// ECMA 262 - 15.9.5.7
353
function DateToLocaleTimeString() {
354
  var t = UTC_DATE_VALUE(this);
355
  if (NUMBER_IS_NAN(t)) return kInvalidDate;
356
  return TimeString(this);
357
}
358

    
359

    
360
// ECMA 262 - 15.9.5.8
361
function DateValueOf() {
362
  return UTC_DATE_VALUE(this);
363
}
364

    
365

    
366
// ECMA 262 - 15.9.5.9
367
function DateGetTime() {
368
  return UTC_DATE_VALUE(this);
369
}
370

    
371

    
372
// ECMA 262 - 15.9.5.10
373
function DateGetFullYear() {
374
  return LOCAL_YEAR(this);
375
}
376

    
377

    
378
// ECMA 262 - 15.9.5.11
379
function DateGetUTCFullYear() {
380
  return UTC_YEAR(this);
381
}
382

    
383

    
384
// ECMA 262 - 15.9.5.12
385
function DateGetMonth() {
386
  return LOCAL_MONTH(this);
387
}
388

    
389

    
390
// ECMA 262 - 15.9.5.13
391
function DateGetUTCMonth() {
392
  return UTC_MONTH(this);
393
}
394

    
395

    
396
// ECMA 262 - 15.9.5.14
397
function DateGetDate() {
398
  return LOCAL_DAY(this);
399
}
400

    
401

    
402
// ECMA 262 - 15.9.5.15
403
function DateGetUTCDate() {
404
  return UTC_DAY(this);
405
}
406

    
407

    
408
// ECMA 262 - 15.9.5.16
409
function DateGetDay() {
410
  return LOCAL_WEEKDAY(this);
411
}
412

    
413

    
414
// ECMA 262 - 15.9.5.17
415
function DateGetUTCDay() {
416
  return UTC_WEEKDAY(this);
417
}
418

    
419

    
420
// ECMA 262 - 15.9.5.18
421
function DateGetHours() {
422
  return LOCAL_HOUR(this);
423
}
424

    
425

    
426
// ECMA 262 - 15.9.5.19
427
function DateGetUTCHours() {
428
  return UTC_HOUR(this);
429
}
430

    
431

    
432
// ECMA 262 - 15.9.5.20
433
function DateGetMinutes() {
434
  return LOCAL_MIN(this);
435
}
436

    
437

    
438
// ECMA 262 - 15.9.5.21
439
function DateGetUTCMinutes() {
440
  return UTC_MIN(this);
441
}
442

    
443

    
444
// ECMA 262 - 15.9.5.22
445
function DateGetSeconds() {
446
  return LOCAL_SEC(this);
447
}
448

    
449

    
450
// ECMA 262 - 15.9.5.23
451
function DateGetUTCSeconds() {
452
  return UTC_SEC(this)
453
}
454

    
455

    
456
// ECMA 262 - 15.9.5.24
457
function DateGetMilliseconds() {
458
  return LOCAL_MS(this);
459
}
460

    
461

    
462
// ECMA 262 - 15.9.5.25
463
function DateGetUTCMilliseconds() {
464
  return UTC_MS(this);
465
}
466

    
467

    
468
// ECMA 262 - 15.9.5.26
469
function DateGetTimezoneOffset() {
470
  return TIMEZONE_OFFSET(this);
471
}
472

    
473

    
474
// ECMA 262 - 15.9.5.27
475
function DateSetTime(ms) {
476
  CHECK_DATE(this);
477
  SET_UTC_DATE_VALUE(this, ToNumber(ms));
478
  return UTC_DATE_VALUE(this);
479
}
480

    
481

    
482
// ECMA 262 - 15.9.5.28
483
function DateSetMilliseconds(ms) {
484
  var t = LOCAL_DATE_VALUE(this);
485
  ms = ToNumber(ms);
486
  var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), LOCAL_SEC(this), ms);
487
  return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
488
}
489

    
490

    
491
// ECMA 262 - 15.9.5.29
492
function DateSetUTCMilliseconds(ms) {
493
  var t = UTC_DATE_VALUE(this);
494
  ms = ToNumber(ms);
495
  var time = MakeTime(UTC_HOUR(this),
496
                      UTC_MIN(this),
497
                      UTC_SEC(this),
498
                      ms);
499
  return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
500
}
501

    
502

    
503
// ECMA 262 - 15.9.5.30
504
function DateSetSeconds(sec, ms) {
505
  var t = LOCAL_DATE_VALUE(this);
506
  sec = ToNumber(sec);
507
  ms = %_ArgumentsLength() < 2 ? LOCAL_MS(this) : ToNumber(ms);
508
  var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), sec, ms);
509
  return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
510
}
511

    
512

    
513
// ECMA 262 - 15.9.5.31
514
function DateSetUTCSeconds(sec, ms) {
515
  var t = UTC_DATE_VALUE(this);
516
  sec = ToNumber(sec);
517
  ms = %_ArgumentsLength() < 2 ? UTC_MS(this) : ToNumber(ms);
518
  var time = MakeTime(UTC_HOUR(this), UTC_MIN(this), sec, ms);
519
  return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
520
}
521

    
522

    
523
// ECMA 262 - 15.9.5.33
524
function DateSetMinutes(min, sec, ms) {
525
  var t = LOCAL_DATE_VALUE(this);
526
  min = ToNumber(min);
527
  var argc = %_ArgumentsLength();
528
  sec = argc < 2 ? LOCAL_SEC(this) : ToNumber(sec);
529
  ms = argc < 3 ? LOCAL_MS(this) : ToNumber(ms);
530
  var time = MakeTime(LOCAL_HOUR(this), min, sec, ms);
531
  return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
532
}
533

    
534

    
535
// ECMA 262 - 15.9.5.34
536
function DateSetUTCMinutes(min, sec, ms) {
537
  var t = UTC_DATE_VALUE(this);
538
  min = ToNumber(min);
539
  var argc = %_ArgumentsLength();
540
  sec = argc < 2 ? UTC_SEC(this) : ToNumber(sec);
541
  ms = argc < 3 ? UTC_MS(this) : ToNumber(ms);
542
  var time = MakeTime(UTC_HOUR(this), min, sec, ms);
543
  return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
544
}
545

    
546

    
547
// ECMA 262 - 15.9.5.35
548
function DateSetHours(hour, min, sec, ms) {
549
  var t = LOCAL_DATE_VALUE(this);
550
  hour = ToNumber(hour);
551
  var argc = %_ArgumentsLength();
552
  min = argc < 2 ? LOCAL_MIN(this) : ToNumber(min);
553
  sec = argc < 3 ? LOCAL_SEC(this) : ToNumber(sec);
554
  ms = argc < 4 ? LOCAL_MS(this) : ToNumber(ms);
555
  var time = MakeTime(hour, min, sec, ms);
556
  return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
557
}
558

    
559

    
560
// ECMA 262 - 15.9.5.34
561
function DateSetUTCHours(hour, min, sec, ms) {
562
  var t = UTC_DATE_VALUE(this);
563
  hour = ToNumber(hour);
564
  var argc = %_ArgumentsLength();
565
  min = argc < 2 ? UTC_MIN(this) : ToNumber(min);
566
  sec = argc < 3 ? UTC_SEC(this) : ToNumber(sec);
567
  ms = argc < 4 ? UTC_MS(this) : ToNumber(ms);
568
  var time = MakeTime(hour, min, sec, ms);
569
  return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
570
}
571

    
572

    
573
// ECMA 262 - 15.9.5.36
574
function DateSetDate(date) {
575
  var t = LOCAL_DATE_VALUE(this);
576
  date = ToNumber(date);
577
  var day = MakeDay(LOCAL_YEAR(this), LOCAL_MONTH(this), date);
578
  return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
579
}
580

    
581

    
582
// ECMA 262 - 15.9.5.37
583
function DateSetUTCDate(date) {
584
  var t = UTC_DATE_VALUE(this);
585
  date = ToNumber(date);
586
  var day = MakeDay(UTC_YEAR(this), UTC_MONTH(this), date);
587
  return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
588
}
589

    
590

    
591
// ECMA 262 - 15.9.5.38
592
function DateSetMonth(month, date) {
593
  var t = LOCAL_DATE_VALUE(this);
594
  month = ToNumber(month);
595
  date = %_ArgumentsLength() < 2 ? LOCAL_DAY(this) : ToNumber(date);
596
  var day = MakeDay(LOCAL_YEAR(this), month, date);
597
  return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
598
}
599

    
600

    
601
// ECMA 262 - 15.9.5.39
602
function DateSetUTCMonth(month, date) {
603
  var t = UTC_DATE_VALUE(this);
604
  month = ToNumber(month);
605
  date = %_ArgumentsLength() < 2 ? UTC_DAY(this) : ToNumber(date);
606
  var day = MakeDay(UTC_YEAR(this), month, date);
607
  return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
608
}
609

    
610

    
611
// ECMA 262 - 15.9.5.40
612
function DateSetFullYear(year, month, date) {
613
  var t = LOCAL_DATE_VALUE(this);
614
  year = ToNumber(year);
615
  var argc = %_ArgumentsLength();
616
  var time ;
617
  if (NUMBER_IS_NAN(t)) {
618
    month = argc < 2 ? 0 : ToNumber(month);
619
    date = argc < 3 ? 1 : ToNumber(date);
620
    time = 0;
621
  } else {
622
    month = argc < 2 ? LOCAL_MONTH(this) : ToNumber(month);
623
    date = argc < 3 ? LOCAL_DAY(this) : ToNumber(date);
624
    time = LOCAL_TIME_IN_DAY(this);
625
  }
626
  var day = MakeDay(year, month, date);
627
  return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
628
}
629

    
630

    
631
// ECMA 262 - 15.9.5.41
632
function DateSetUTCFullYear(year, month, date) {
633
  var t = UTC_DATE_VALUE(this);
634
  year = ToNumber(year);
635
  var argc = %_ArgumentsLength();
636
  var time ;
637
  if (NUMBER_IS_NAN(t)) {
638
    month = argc < 2 ? 0 : ToNumber(month);
639
    date = argc < 3 ? 1 : ToNumber(date);
640
    time = 0;
641
  } else {
642
    month = argc < 2 ? UTC_MONTH(this) : ToNumber(month);
643
    date = argc < 3 ? UTC_DAY(this) : ToNumber(date);
644
    time = UTC_TIME_IN_DAY(this);
645
  }
646
  var day = MakeDay(year, month, date);
647
  return SET_UTC_DATE_VALUE(this, MakeDate(day, time));
648
}
649

    
650

    
651
// ECMA 262 - 15.9.5.42
652
function DateToUTCString() {
653
  var t = UTC_DATE_VALUE(this);
654
  if (NUMBER_IS_NAN(t)) return kInvalidDate;
655
  // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
656
  return WeekDays[UTC_WEEKDAY(this)] + ', '
657
      + TwoDigitString(UTC_DAY(this)) + ' '
658
      + Months[UTC_MONTH(this)] + ' '
659
      + UTC_YEAR(this) + ' '
660
      + TimeStringUTC(this) + ' GMT';
661
}
662

    
663

    
664
// ECMA 262 - B.2.4
665
function DateGetYear() {
666
  return LOCAL_YEAR(this) - 1900;
667
}
668

    
669

    
670
// ECMA 262 - B.2.5
671
function DateSetYear(year) {
672
  CHECK_DATE(this);
673
  year = ToNumber(year);
674
  if (NUMBER_IS_NAN(year)) return SET_UTC_DATE_VALUE(this, NAN);
675
  year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
676
      ? 1900 + TO_INTEGER(year) : year;
677
  var t = LOCAL_DATE_VALUE(this);
678
  var month, date, time;
679
  if (NUMBER_IS_NAN(t))  {
680
    month = 0;
681
    date = 1;
682
    time = 0;
683
  } else {
684
    month = LOCAL_MONTH(this);
685
    date = LOCAL_DAY(this);
686
    time = LOCAL_TIME_IN_DAY(this);
687
  }
688
  var day = MakeDay(year, month, date);
689
  return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
690
}
691

    
692

    
693
// ECMA 262 - B.2.6
694
//
695
// Notice that this does not follow ECMA 262 completely.  ECMA 262
696
// says that toGMTString should be the same Function object as
697
// toUTCString.  JSC does not do this, so for compatibility we do not
698
// do that either.  Instead, we create a new function whose name
699
// property will return toGMTString.
700
function DateToGMTString() {
701
  return %_CallFunction(this, DateToUTCString);
702
}
703

    
704

    
705
function PadInt(n, digits) {
706
  if (digits == 1) return n;
707
  return n < MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
708
}
709

    
710

    
711
// ECMA 262 - 15.9.5.43
712
function DateToISOString() {
713
  var t = UTC_DATE_VALUE(this);
714
  if (NUMBER_IS_NAN(t)) throw MakeRangeError("invalid_time_value", []);
715
  var year = this.getUTCFullYear();
716
  var year_string;
717
  if (year >= 0 && year <= 9999) {
718
    year_string = PadInt(year, 4);
719
  } else {
720
    if (year < 0) {
721
      year_string = "-" + PadInt(-year, 6);
722
    } else {
723
      year_string = "+" + PadInt(year, 6);
724
    }
725
  }
726
  return year_string +
727
      '-' + PadInt(this.getUTCMonth() + 1, 2) +
728
      '-' + PadInt(this.getUTCDate(), 2) +
729
      'T' + PadInt(this.getUTCHours(), 2) +
730
      ':' + PadInt(this.getUTCMinutes(), 2) +
731
      ':' + PadInt(this.getUTCSeconds(), 2) +
732
      '.' + PadInt(this.getUTCMilliseconds(), 3) +
733
      'Z';
734
}
735

    
736

    
737
function DateToJSON(key) {
738
  var o = ToObject(this);
739
  var tv = DefaultNumber(o);
740
  if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
741
    return null;
742
  }
743
  return o.toISOString();
744
}
745

    
746

    
747
function ResetDateCache() {
748
  // Reset the timezone cache:
749
  timezone_cache_time = NAN;
750
  timezone_cache_timezone = undefined;
751

    
752
  // Reset the date cache:
753
  cache = Date_cache;
754
  cache.time = NAN;
755
  cache.string = null;
756
}
757

    
758

    
759
// -------------------------------------------------------------------
760

    
761
function SetUpDate() {
762
  %CheckIsBootstrapping();
763

    
764
  %SetCode($Date, DateConstructor);
765
  %FunctionSetPrototype($Date, new $Date(NAN));
766

    
767
  // Set up non-enumerable properties of the Date object itself.
768
  InstallFunctions($Date, 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
  %SetProperty($Date.prototype, "constructor", $Date, DONT_ENUM);
776

    
777
  // Set up non-enumerable functions of the Date prototype object and
778
  // set their names.
779
  InstallFunctions($Date.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

    
829
SetUpDate();