Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: src/date-delay.js

Issue 1094014: Merge the partial_snapshots branch back into bleeding_edge. For... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
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.
41 const $Date = global.Date;
42
43 // Helper function to throw error.
44 function ThrowDateTypeError() {
45 throw new $TypeError('this is not a Date object.');
46 }
47
48 // ECMA 262 - 5.2
49 function 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
57 function TimeWithinDay(time) {
58 return Modulo(time, msPerDay);
59 }
60
61
62 // ECMA 262 - 15.9.1.3
63 function 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
70 function 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
78 function TimeFromYear(year) {
79 return msPerDay * DayFromYear(year);
80 }
81
82
83 function InLeapYear(time) {
84 return DaysInYear(YEAR_FROM_TIME(time)) == 366 ? 1 : 0;
85 }
86
87
88 function DayWithinYear(time) {
89 return DAY(time) - DayFromYear(YEAR_FROM_TIME(time));
90 }
91
92
93 // ECMA 262 - 15.9.1.9
94 function 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
107 function 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;
116
117 var day = MakeDay(EquivalentYear(YEAR_FROM_TIME(t)),
118 MONTH_FROM_TIME(t),
119 DATE_FROM_TIME(t));
120 return MakeDate(day, TimeWithinDay(t));
121 }
122
123
124 // Because computing the DST offset is a pretty expensive operation
125 // we keep a cache of last computed offset along with a time interval
126 // where we know the cache is valid.
127 var DST_offset_cache = {
128 // Cached DST offset.
129 offset: 0,
130 // Time interval where the cached offset is valid.
131 start: 0, end: -1,
132 // Size of next interval expansion.
133 increment: 0
134 };
135
136
137 // NOTE: The implementation relies on the fact that no time zones have
138 // more than one daylight savings offset change per month.
139 // If this function is called with NaN it returns NaN.
140 function DaylightSavingsOffset(t) {
141 // Load the cache object from the builtins object.
142 var cache = DST_offset_cache;
143
144 // Cache the start and the end in local variables for fast access.
145 var start = cache.start;
146 var end = cache.end;
147
148 if (start <= t) {
149 // If the time fits in the cached interval, return the cached offset.
150 if (t <= end) return cache.offset;
151
152 // Compute a possible new interval end.
153 var new_end = end + cache.increment;
154
155 if (t <= new_end) {
156 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end));
157 if (cache.offset == end_offset) {
158 // If the offset at the end of the new interval still matches
159 // the offset in the cache, we grow the cached time interval
160 // and return the offset.
161 cache.end = new_end;
162 cache.increment = msPerMonth;
163 return end_offset;
164 } else {
165 var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
166 if (offset == end_offset) {
167 // The offset at the given time is equal to the offset at the
168 // new end of the interval, so that means that we've just skipped
169 // the point in time where the DST offset change occurred. Updated
170 // the interval to reflect this and reset the increment.
171 cache.start = t;
172 cache.end = new_end;
173 cache.increment = msPerMonth;
174 } else {
175 // The interval contains a DST offset change and the given time is
176 // before it. Adjust the increment to avoid a linear search for
177 // the offset change point and change the end of the interval.
178 cache.increment /= 3;
179 cache.end = t;
180 }
181 // Update the offset in the cache and return it.
182 cache.offset = offset;
183 return offset;
184 }
185 }
186 }
187
188 // Compute the DST offset for the time and shrink the cache interval
189 // to only contain the time. This allows fast repeated DST offset
190 // computations for the same time.
191 var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
192 cache.offset = offset;
193 cache.start = cache.end = t;
194 cache.increment = msPerMonth;
195 return offset;
196 }
197
198
199 var timezone_cache_time = $NaN;
200 var timezone_cache_timezone;
201
202 function LocalTimezone(t) {
203 if (NUMBER_IS_NAN(t)) return "";
204 if (t == timezone_cache_time) {
205 return timezone_cache_timezone;
206 }
207 var timezone = %DateLocalTimezone(EquivalentTime(t));
208 timezone_cache_time = t;
209 timezone_cache_timezone = timezone;
210 return timezone;
211 }
212
213
214 function WeekDay(time) {
215 return Modulo(DAY(time) + 4, 7);
216 }
217
218 var local_time_offset = %DateLocalTimeOffset();
219
220 function LocalTime(time) {
221 if (NUMBER_IS_NAN(time)) return time;
222 return time + local_time_offset + DaylightSavingsOffset(time);
223 }
224
225 function LocalTimeNoCheck(time) {
226 // Inline the DST offset cache checks for speed.
227 var cache = DST_offset_cache;
228 if (cache.start <= time && time <= cache.end) {
229 var dst_offset = cache.offset;
230 } else {
231 var dst_offset = DaylightSavingsOffset(time);
232 }
233 return time + local_time_offset + dst_offset;
234 }
235
236
237 function UTC(time) {
238 if (NUMBER_IS_NAN(time)) return time;
239 var tmp = time - local_time_offset;
240 return tmp - DaylightSavingsOffset(tmp);
241 }
242
243
244 // ECMA 262 - 15.9.1.11
245 function MakeTime(hour, min, sec, ms) {
246 if (!$isFinite(hour)) return $NaN;
247 if (!$isFinite(min)) return $NaN;
248 if (!$isFinite(sec)) return $NaN;
249 if (!$isFinite(ms)) return $NaN;
250 return TO_INTEGER(hour) * msPerHour
251 + TO_INTEGER(min) * msPerMinute
252 + TO_INTEGER(sec) * msPerSecond
253 + TO_INTEGER(ms);
254 }
255
256
257 // ECMA 262 - 15.9.1.12
258 function TimeInYear(year) {
259 return DaysInYear(year) * msPerDay;
260 }
261
262
263 var ymd_from_time_cache = [$NaN, $NaN, $NaN];
264 var ymd_from_time_cached_time = $NaN;
265
266 function YearFromTime(t) {
267 if (t !== ymd_from_time_cached_time) {
268 // Limits according to ECMA 262 15.9.1.1
269 if (!$isFinite(t) || t < -8640000000000000 || t > 8640000000000000) {
270 return $NaN;
271 }
272
273 %DateYMDFromTime(t, ymd_from_time_cache);
274 ymd_from_time_cached_time = t
275 }
276
277 return ymd_from_time_cache[0];
278 }
279
280 function MonthFromTime(t) {
281 if (t !== ymd_from_time_cached_time) {
282 // Limits according to ECMA 262 15.9.1.1
283 if (!$isFinite(t) || t < -8640000000000000 || t > 8640000000000000) {
284 return $NaN;
285 }
286 %DateYMDFromTime(t, ymd_from_time_cache);
287 ymd_from_time_cached_time = t
288 }
289
290 return ymd_from_time_cache[1];
291 }
292
293 function DateFromTime(t) {
294 if (t !== ymd_from_time_cached_time) {
295 // Limits according to ECMA 262 15.9.1.1
296 if (!$isFinite(t) || t < -8640000000000000 || t > 8640000000000000) {
297 return $NaN;
298 }
299
300 %DateYMDFromTime(t, ymd_from_time_cache);
301 ymd_from_time_cached_time = t
302 }
303
304 return ymd_from_time_cache[2];
305 }
306
307
308 // Compute number of days given a year, month, date.
309 // Note that month and date can lie outside the normal range.
310 // For example:
311 // MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
312 // MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
313 // MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
314 function MakeDay(year, month, date) {
315 if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return $NaN;
316
317 year = TO_INTEGER(year);
318 month = TO_INTEGER(month);
319 date = TO_INTEGER(date);
320
321 if (year < kMinYear || year > kMaxYear ||
322 month < kMinMonth || month > kMaxMonth ||
323 date < kMinDate || date > kMaxDate) {
324 return $NaN;
325 }
326
327 // Now we rely on year, month and date being SMIs.
328 return %DateMakeDay(year, month, date);
329 }
330
331
332 // ECMA 262 - 15.9.1.13
333 function MakeDate(day, time) {
334 if (!$isFinite(day)) return $NaN;
335 if (!$isFinite(time)) return $NaN;
336 return day * msPerDay + time;
337 }
338
339
340 // ECMA 262 - 15.9.1.14
341 function TimeClip(time) {
342 if (!$isFinite(time)) return $NaN;
343 if ($abs(time) > 8.64E15) return $NaN;
344 return TO_INTEGER(time);
345 }
346
347
348 // The Date cache is used to limit the cost of parsing the same Date
349 // strings over and over again.
350 var Date_cache = {
351 // Cached time value.
352 time: $NaN,
353 // Cached year when interpreting the time as a local time. Only
354 // valid when the time matches cached time.
355 year: $NaN,
356 // String input for which the cached time is valid.
357 string: null
358 };
359
360
361 %SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
362 if (!%_IsConstructCall()) {
363 // ECMA 262 - 15.9.2
364 return (new $Date()).toString();
365 }
366
367 // ECMA 262 - 15.9.3
368 var argc = %_ArgumentsLength();
369 var value;
370 if (argc == 0) {
371 value = %DateCurrentTime();
372
373 } else if (argc == 1) {
374 if (IS_NUMBER(year)) {
375 value = TimeClip(year);
376
377 } else if (IS_STRING(year)) {
378 // Probe the Date cache. If we already have a time value for the
379 // given time, we re-use that instead of parsing the string again.
380 var cache = Date_cache;
381 if (cache.string === year) {
382 value = cache.time;
383 } else {
384 value = DateParse(year);
385 if (!NUMBER_IS_NAN(value)) {
386 cache.time = value;
387 cache.year = YEAR_FROM_TIME(LocalTimeNoCheck(value));
388 cache.string = year;
389 }
390 }
391
392 } else {
393 // According to ECMA 262, no hint should be given for this
394 // conversion. However, ToPrimitive defaults to STRING_HINT for
395 // Date objects which will lose precision when the Date
396 // constructor is called with another Date object as its
397 // argument. We therefore use NUMBER_HINT for the conversion,
398 // which is the default for everything else than Date objects.
399 // This makes us behave like KJS and SpiderMonkey.
400 var time = ToPrimitive(year, NUMBER_HINT);
401 value = IS_STRING(time) ? DateParse(time) : TimeClip(ToNumber(time));
402 }
403
404 } else {
405 year = ToNumber(year);
406 month = ToNumber(month);
407 date = argc > 2 ? ToNumber(date) : 1;
408 hours = argc > 3 ? ToNumber(hours) : 0;
409 minutes = argc > 4 ? ToNumber(minutes) : 0;
410 seconds = argc > 5 ? ToNumber(seconds) : 0;
411 ms = argc > 6 ? ToNumber(ms) : 0;
412 year = (!NUMBER_IS_NAN(year) && 0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
413 ? 1900 + TO_INTEGER(year) : year;
414 var day = MakeDay(year, month, date);
415 var time = MakeTime(hours, minutes, seconds, ms);
416 value = TimeClip(UTC(MakeDate(day, time)));
417 }
418 %_SetValueOf(this, value);
419 });
420
421
422 // Helper functions.
423 function GetTimeFrom(aDate) {
424 return DATE_VALUE(aDate);
425 }
426
427 function GetMillisecondsFrom(aDate) {
428 var t = DATE_VALUE(aDate);
429 if (NUMBER_IS_NAN(t)) return t;
430 return MS_FROM_TIME(LocalTimeNoCheck(t));
431 }
432
433
434 function GetUTCMillisecondsFrom(aDate) {
435 var t = DATE_VALUE(aDate);
436 if (NUMBER_IS_NAN(t)) return t;
437 return MS_FROM_TIME(t);
438 }
439
440
441 function GetSecondsFrom(aDate) {
442 var t = DATE_VALUE(aDate);
443 if (NUMBER_IS_NAN(t)) return t;
444 return SEC_FROM_TIME(LocalTimeNoCheck(t));
445 }
446
447
448 function GetUTCSecondsFrom(aDate) {
449 var t = DATE_VALUE(aDate);
450 if (NUMBER_IS_NAN(t)) return t;
451 return SEC_FROM_TIME(t);
452 }
453
454
455 function GetMinutesFrom(aDate) {
456 var t = DATE_VALUE(aDate);
457 if (NUMBER_IS_NAN(t)) return t;
458 return MIN_FROM_TIME(LocalTimeNoCheck(t));
459 }
460
461
462 function GetUTCMinutesFrom(aDate) {
463 var t = DATE_VALUE(aDate);
464 if (NUMBER_IS_NAN(t)) return t;
465 return MIN_FROM_TIME(t);
466 }
467
468
469 function GetHoursFrom(aDate) {
470 var t = DATE_VALUE(aDate);
471 if (NUMBER_IS_NAN(t)) return t;
472 return HOUR_FROM_TIME(LocalTimeNoCheck(t));
473 }
474
475
476 function GetUTCHoursFrom(aDate) {
477 var t = DATE_VALUE(aDate);
478 if (NUMBER_IS_NAN(t)) return t;
479 return HOUR_FROM_TIME(t);
480 }
481
482
483 function GetFullYearFrom(aDate) {
484 var t = DATE_VALUE(aDate);
485 if (NUMBER_IS_NAN(t)) return t;
486 var cache = Date_cache;
487 if (cache.time === t) return cache.year;
488 return YEAR_FROM_TIME(LocalTimeNoCheck(t));
489 }
490
491
492 function GetUTCFullYearFrom(aDate) {
493 var t = DATE_VALUE(aDate);
494 if (NUMBER_IS_NAN(t)) return t;
495 return YEAR_FROM_TIME(t);
496 }
497
498
499 function GetMonthFrom(aDate) {
500 var t = DATE_VALUE(aDate);
501 if (NUMBER_IS_NAN(t)) return t;
502 return MONTH_FROM_TIME(LocalTimeNoCheck(t));
503 }
504
505
506 function GetUTCMonthFrom(aDate) {
507 var t = DATE_VALUE(aDate);
508 if (NUMBER_IS_NAN(t)) return t;
509 return MONTH_FROM_TIME(t);
510 }
511
512
513 function GetDateFrom(aDate) {
514 var t = DATE_VALUE(aDate);
515 if (NUMBER_IS_NAN(t)) return t;
516 return DATE_FROM_TIME(LocalTimeNoCheck(t));
517 }
518
519
520 function GetUTCDateFrom(aDate) {
521 var t = DATE_VALUE(aDate);
522 if (NUMBER_IS_NAN(t)) return t;
523 return DATE_FROM_TIME(t);
524 }
525
526
527 %FunctionSetPrototype($Date, new $Date($NaN));
528
529
530 var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
531 var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oc t', 'Nov', 'Dec'];
532
533
534 function TwoDigitString(value) {
535 return value < 10 ? "0" + value : "" + value;
536 }
537
538
539 function DateString(time) {
540 return WeekDays[WeekDay(time)] + ' '
541 + Months[MonthFromTime(time)] + ' '
542 + TwoDigitString(DateFromTime(time)) + ' '
543 + YearFromTime(time);
544 }
545
546
547 var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Fri day', 'Saturday'];
548 var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July' , 'August', 'September', 'October', 'November', 'December'];
549
550
551 function LongDateString(time) {
552 return LongWeekDays[WeekDay(time)] + ', '
553 + LongMonths[MonthFromTime(time)] + ' '
554 + TwoDigitString(DateFromTime(time)) + ', '
555 + YearFromTime(time);
556 }
557
558
559 function TimeString(time) {
560 return TwoDigitString(HOUR_FROM_TIME(time)) + ':'
561 + TwoDigitString(MIN_FROM_TIME(time)) + ':'
562 + TwoDigitString(SEC_FROM_TIME(time));
563 }
564
565
566 function LocalTimezoneString(time) {
567 var timezoneOffset =
568 (local_time_offset + DaylightSavingsOffset(time)) / msPerMinute;
569 var sign = (timezoneOffset >= 0) ? 1 : -1;
570 var hours = FLOOR((sign * timezoneOffset)/60);
571 var min = FLOOR((sign * timezoneOffset)%60);
572 var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
573 TwoDigitString(hours) + TwoDigitString(min);
574 return gmt + ' (' + LocalTimezone(time) + ')';
575 }
576
577
578 function DatePrintString(time) {
579 return DateString(time) + ' ' + TimeString(time);
580 }
581
582 // -------------------------------------------------------------------
583
584 // Reused output buffer. Used when parsing date strings.
585 var parse_buffer = $Array(7);
586
587 // ECMA 262 - 15.9.4.2
588 function DateParse(string) {
589 var arr = %DateParseString(ToString(string), parse_buffer);
590 if (IS_NULL(arr)) return $NaN;
591
592 var day = MakeDay(arr[0], arr[1], arr[2]);
593 var time = MakeTime(arr[3], arr[4], arr[5], 0);
594 var date = MakeDate(day, time);
595
596 if (IS_NULL(arr[6])) {
597 return TimeClip(UTC(date));
598 } else {
599 return TimeClip(date - arr[6] * 1000);
600 }
601 }
602
603
604 // ECMA 262 - 15.9.4.3
605 function DateUTC(year, month, date, hours, minutes, seconds, ms) {
606 year = ToNumber(year);
607 month = ToNumber(month);
608 var argc = %_ArgumentsLength();
609 date = argc > 2 ? ToNumber(date) : 1;
610 hours = argc > 3 ? ToNumber(hours) : 0;
611 minutes = argc > 4 ? ToNumber(minutes) : 0;
612 seconds = argc > 5 ? ToNumber(seconds) : 0;
613 ms = argc > 6 ? ToNumber(ms) : 0;
614 year = (!NUMBER_IS_NAN(year) && 0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 9 9)
615 ? 1900 + TO_INTEGER(year) : year;
616 var day = MakeDay(year, month, date);
617 var time = MakeTime(hours, minutes, seconds, ms);
618 return %_SetValueOf(this, TimeClip(MakeDate(day, time)));
619 }
620
621
622 // Mozilla-specific extension. Returns the number of milliseconds
623 // elapsed since 1 January 1970 00:00:00 UTC.
624 function DateNow() {
625 return %DateCurrentTime();
626 }
627
628
629 // ECMA 262 - 15.9.5.2
630 function DateToString() {
631 var t = DATE_VALUE(this);
632 if (NUMBER_IS_NAN(t)) return kInvalidDate;
633 return DatePrintString(LocalTimeNoCheck(t)) + LocalTimezoneString(t);
634 }
635
636
637 // ECMA 262 - 15.9.5.3
638 function DateToDateString() {
639 var t = DATE_VALUE(this);
640 if (NUMBER_IS_NAN(t)) return kInvalidDate;
641 return DateString(LocalTimeNoCheck(t));
642 }
643
644
645 // ECMA 262 - 15.9.5.4
646 function DateToTimeString() {
647 var t = DATE_VALUE(this);
648 if (NUMBER_IS_NAN(t)) return kInvalidDate;
649 var lt = LocalTimeNoCheck(t);
650 return TimeString(lt) + LocalTimezoneString(lt);
651 }
652
653
654 // ECMA 262 - 15.9.5.5
655 function DateToLocaleString() {
656 return DateToString.call(this);
657 }
658
659
660 // ECMA 262 - 15.9.5.6
661 function DateToLocaleDateString() {
662 var t = DATE_VALUE(this);
663 if (NUMBER_IS_NAN(t)) return kInvalidDate;
664 return LongDateString(LocalTimeNoCheck(t));
665 }
666
667
668 // ECMA 262 - 15.9.5.7
669 function DateToLocaleTimeString() {
670 var t = DATE_VALUE(this);
671 if (NUMBER_IS_NAN(t)) return kInvalidDate;
672 var lt = LocalTimeNoCheck(t);
673 return TimeString(lt);
674 }
675
676
677 // ECMA 262 - 15.9.5.8
678 function DateValueOf() {
679 return DATE_VALUE(this);
680 }
681
682
683 // ECMA 262 - 15.9.5.9
684 function DateGetTime() {
685 return DATE_VALUE(this);
686 }
687
688
689 // ECMA 262 - 15.9.5.10
690 function DateGetFullYear() {
691 return GetFullYearFrom(this)
692 }
693
694
695 // ECMA 262 - 15.9.5.11
696 function DateGetUTCFullYear() {
697 return GetUTCFullYearFrom(this)
698 }
699
700
701 // ECMA 262 - 15.9.5.12
702 function DateGetMonth() {
703 return GetMonthFrom(this);
704 }
705
706
707 // ECMA 262 - 15.9.5.13
708 function DateGetUTCMonth() {
709 return GetUTCMonthFrom(this);
710 }
711
712
713 // ECMA 262 - 15.9.5.14
714 function DateGetDate() {
715 return GetDateFrom(this);
716 }
717
718
719 // ECMA 262 - 15.9.5.15
720 function DateGetUTCDate() {
721 return GetUTCDateFrom(this);
722 }
723
724
725 // ECMA 262 - 15.9.5.16
726 function DateGetDay() {
727 var t = %_ValueOf(this);
728 if (NUMBER_IS_NAN(t)) return t;
729 return WeekDay(LocalTimeNoCheck(t));
730 }
731
732
733 // ECMA 262 - 15.9.5.17
734 function DateGetUTCDay() {
735 var t = %_ValueOf(this);
736 if (NUMBER_IS_NAN(t)) return t;
737 return WeekDay(t);
738 }
739
740
741 // ECMA 262 - 15.9.5.18
742 function DateGetHours() {
743 return GetHoursFrom(this);
744 }
745
746
747 // ECMA 262 - 15.9.5.19
748 function DateGetUTCHours() {
749 return GetUTCHoursFrom(this);
750 }
751
752
753 // ECMA 262 - 15.9.5.20
754 function DateGetMinutes() {
755 return GetMinutesFrom(this);
756 }
757
758
759 // ECMA 262 - 15.9.5.21
760 function DateGetUTCMinutes() {
761 return GetUTCMinutesFrom(this);
762 }
763
764
765 // ECMA 262 - 15.9.5.22
766 function DateGetSeconds() {
767 return GetSecondsFrom(this);
768 }
769
770
771 // ECMA 262 - 15.9.5.23
772 function DateGetUTCSeconds() {
773 return GetUTCSecondsFrom(this);
774 }
775
776
777 // ECMA 262 - 15.9.5.24
778 function DateGetMilliseconds() {
779 return GetMillisecondsFrom(this);
780 }
781
782
783 // ECMA 262 - 15.9.5.25
784 function DateGetUTCMilliseconds() {
785 return GetUTCMillisecondsFrom(this);
786 }
787
788
789 // ECMA 262 - 15.9.5.26
790 function DateGetTimezoneOffset() {
791 var t = DATE_VALUE(this);
792 if (NUMBER_IS_NAN(t)) return t;
793 return (t - LocalTimeNoCheck(t)) / msPerMinute;
794 }
795
796
797 // ECMA 262 - 15.9.5.27
798 function DateSetTime(ms) {
799 if (!IS_DATE(this)) ThrowDateTypeError();
800 return %_SetValueOf(this, TimeClip(ToNumber(ms)));
801 }
802
803
804 // ECMA 262 - 15.9.5.28
805 function DateSetMilliseconds(ms) {
806 var t = LocalTime(DATE_VALUE(this));
807 ms = ToNumber(ms);
808 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), SEC_FROM_TIME(t), ms) ;
809 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
810 }
811
812
813 // ECMA 262 - 15.9.5.29
814 function DateSetUTCMilliseconds(ms) {
815 var t = DATE_VALUE(this);
816 ms = ToNumber(ms);
817 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), SEC_FROM_TIME(t), ms) ;
818 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
819 }
820
821
822 // ECMA 262 - 15.9.5.30
823 function DateSetSeconds(sec, ms) {
824 var t = LocalTime(DATE_VALUE(this));
825 sec = ToNumber(sec);
826 ms = %_ArgumentsLength() < 2 ? GetMillisecondsFrom(this) : ToNumber(ms);
827 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), sec, ms);
828 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
829 }
830
831
832 // ECMA 262 - 15.9.5.31
833 function DateSetUTCSeconds(sec, ms) {
834 var t = DATE_VALUE(this);
835 sec = ToNumber(sec);
836 ms = %_ArgumentsLength() < 2 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
837 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), sec, ms);
838 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
839 }
840
841
842 // ECMA 262 - 15.9.5.33
843 function DateSetMinutes(min, sec, ms) {
844 var t = LocalTime(DATE_VALUE(this));
845 min = ToNumber(min);
846 var argc = %_ArgumentsLength();
847 sec = argc < 2 ? GetSecondsFrom(this) : ToNumber(sec);
848 ms = argc < 3 ? GetMillisecondsFrom(this) : ToNumber(ms);
849 var time = MakeTime(HOUR_FROM_TIME(t), min, sec, ms);
850 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
851 }
852
853
854 // ECMA 262 - 15.9.5.34
855 function DateSetUTCMinutes(min, sec, ms) {
856 var t = DATE_VALUE(this);
857 min = ToNumber(min);
858 var argc = %_ArgumentsLength();
859 sec = argc < 2 ? GetUTCSecondsFrom(this) : ToNumber(sec);
860 ms = argc < 3 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
861 var time = MakeTime(HOUR_FROM_TIME(t), min, sec, ms);
862 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
863 }
864
865
866 // ECMA 262 - 15.9.5.35
867 function DateSetHours(hour, min, sec, ms) {
868 var t = LocalTime(DATE_VALUE(this));
869 hour = ToNumber(hour);
870 var argc = %_ArgumentsLength();
871 min = argc < 2 ? GetMinutesFrom(this) : ToNumber(min);
872 sec = argc < 3 ? GetSecondsFrom(this) : ToNumber(sec);
873 ms = argc < 4 ? GetMillisecondsFrom(this) : ToNumber(ms);
874 var time = MakeTime(hour, min, sec, ms);
875 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
876 }
877
878
879 // ECMA 262 - 15.9.5.34
880 function DateSetUTCHours(hour, min, sec, ms) {
881 var t = DATE_VALUE(this);
882 hour = ToNumber(hour);
883 var argc = %_ArgumentsLength();
884 min = argc < 2 ? GetUTCMinutesFrom(this) : ToNumber(min);
885 sec = argc < 3 ? GetUTCSecondsFrom(this) : ToNumber(sec);
886 ms = argc < 4 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
887 var time = MakeTime(hour, min, sec, ms);
888 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time)));
889 }
890
891
892 // ECMA 262 - 15.9.5.36
893 function DateSetDate(date) {
894 var t = LocalTime(DATE_VALUE(this));
895 date = ToNumber(date);
896 var day = MakeDay(YEAR_FROM_TIME(t), MONTH_FROM_TIME(t), date);
897 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
898 }
899
900
901 // ECMA 262 - 15.9.5.37
902 function DateSetUTCDate(date) {
903 var t = DATE_VALUE(this);
904 date = ToNumber(date);
905 var day = MakeDay(YEAR_FROM_TIME(t), MONTH_FROM_TIME(t), date);
906 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
907 }
908
909
910 // ECMA 262 - 15.9.5.38
911 function DateSetMonth(month, date) {
912 var t = LocalTime(DATE_VALUE(this));
913 month = ToNumber(month);
914 date = %_ArgumentsLength() < 2 ? GetDateFrom(this) : ToNumber(date);
915 var day = MakeDay(YEAR_FROM_TIME(t), month, date);
916 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
917 }
918
919
920 // ECMA 262 - 15.9.5.39
921 function DateSetUTCMonth(month, date) {
922 var t = DATE_VALUE(this);
923 month = ToNumber(month);
924 date = %_ArgumentsLength() < 2 ? GetUTCDateFrom(this) : ToNumber(date);
925 var day = MakeDay(YEAR_FROM_TIME(t), month, date);
926 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
927 }
928
929
930 // ECMA 262 - 15.9.5.40
931 function DateSetFullYear(year, month, date) {
932 var t = DATE_VALUE(this);
933 t = NUMBER_IS_NAN(t) ? 0 : LocalTimeNoCheck(t);
934 year = ToNumber(year);
935 var argc = %_ArgumentsLength();
936 month = argc < 2 ? MONTH_FROM_TIME(t) : ToNumber(month);
937 date = argc < 3 ? DATE_FROM_TIME(t) : ToNumber(date);
938 var day = MakeDay(year, month, date);
939 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
940 }
941
942
943 // ECMA 262 - 15.9.5.41
944 function DateSetUTCFullYear(year, month, date) {
945 var t = DATE_VALUE(this);
946 if (NUMBER_IS_NAN(t)) t = 0;
947 var argc = %_ArgumentsLength();
948 year = ToNumber(year);
949 month = argc < 2 ? MONTH_FROM_TIME(t) : ToNumber(month);
950 date = argc < 3 ? DATE_FROM_TIME(t) : ToNumber(date);
951 var day = MakeDay(year, month, date);
952 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
953 }
954
955
956 // ECMA 262 - 15.9.5.42
957 function DateToUTCString() {
958 var t = DATE_VALUE(this);
959 if (NUMBER_IS_NAN(t)) return kInvalidDate;
960 // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
961 return WeekDays[WeekDay(t)] + ', '
962 + TwoDigitString(DATE_FROM_TIME(t)) + ' '
963 + Months[MONTH_FROM_TIME(t)] + ' '
964 + YEAR_FROM_TIME(t) + ' '
965 + TimeString(t) + ' GMT';
966 }
967
968
969 // ECMA 262 - B.2.4
970 function DateGetYear() {
971 var t = DATE_VALUE(this);
972 if (NUMBER_IS_NAN(t)) return $NaN;
973 return YEAR_FROM_TIME(LocalTimeNoCheck(t)) - 1900;
974 }
975
976
977 // ECMA 262 - B.2.5
978 function DateSetYear(year) {
979 var t = LocalTime(DATE_VALUE(this));
980 if (NUMBER_IS_NAN(t)) t = 0;
981 year = ToNumber(year);
982 if (NUMBER_IS_NAN(year)) return %_SetValueOf(this, $NaN);
983 year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
984 ? 1900 + TO_INTEGER(year) : year;
985 var day = MakeDay(year, MONTH_FROM_TIME(t), DATE_FROM_TIME(t));
986 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
987 }
988
989
990 // ECMA 262 - B.2.6
991 //
992 // Notice that this does not follow ECMA 262 completely. ECMA 262
993 // says that toGMTString should be the same Function object as
994 // toUTCString. JSC does not do this, so for compatibility we do not
995 // do that either. Instead, we create a new function whose name
996 // property will return toGMTString.
997 function DateToGMTString() {
998 return DateToUTCString.call(this);
999 }
1000
1001
1002 function PadInt(n, digits) {
1003 if (digits == 1) return n;
1004 return n < MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
1005 }
1006
1007
1008 function DateToISOString() {
1009 var t = DATE_VALUE(this);
1010 if (NUMBER_IS_NAN(t)) return kInvalidDate;
1011 return this.getUTCFullYear() + '-' + PadInt(this.getUTCMonth() + 1, 2) +
1012 '-' + PadInt(this.getUTCDate(), 2) + 'T' + PadInt(this.getUTCHours(), 2) +
1013 ':' + PadInt(this.getUTCMinutes(), 2) + ':' + PadInt(this.getUTCSeconds(), 2) +
1014 '.' + PadInt(this.getUTCMilliseconds(), 3) +
1015 'Z';
1016 }
1017
1018
1019 function DateToJSON(key) {
1020 return CheckJSONPrimitive(this.toISOString());
1021 }
1022
1023
1024 // -------------------------------------------------------------------
1025
1026 function SetupDate() {
1027 // Setup non-enumerable properties of the Date object itself.
1028 InstallFunctions($Date, DONT_ENUM, $Array(
1029 "UTC", DateUTC,
1030 "parse", DateParse,
1031 "now", DateNow
1032 ));
1033
1034 // Setup non-enumerable constructor property of the Date prototype object.
1035 %SetProperty($Date.prototype, "constructor", $Date, DONT_ENUM);
1036
1037 // Setup non-enumerable functions of the Date prototype object and
1038 // set their names.
1039 InstallFunctionsOnHiddenPrototype($Date.prototype, DONT_ENUM, $Array(
1040 "toString", DateToString,
1041 "toDateString", DateToDateString,
1042 "toTimeString", DateToTimeString,
1043 "toLocaleString", DateToLocaleString,
1044 "toLocaleDateString", DateToLocaleDateString,
1045 "toLocaleTimeString", DateToLocaleTimeString,
1046 "valueOf", DateValueOf,
1047 "getTime", DateGetTime,
1048 "getFullYear", DateGetFullYear,
1049 "getUTCFullYear", DateGetUTCFullYear,
1050 "getMonth", DateGetMonth,
1051 "getUTCMonth", DateGetUTCMonth,
1052 "getDate", DateGetDate,
1053 "getUTCDate", DateGetUTCDate,
1054 "getDay", DateGetDay,
1055 "getUTCDay", DateGetUTCDay,
1056 "getHours", DateGetHours,
1057 "getUTCHours", DateGetUTCHours,
1058 "getMinutes", DateGetMinutes,
1059 "getUTCMinutes", DateGetUTCMinutes,
1060 "getSeconds", DateGetSeconds,
1061 "getUTCSeconds", DateGetUTCSeconds,
1062 "getMilliseconds", DateGetMilliseconds,
1063 "getUTCMilliseconds", DateGetUTCMilliseconds,
1064 "getTimezoneOffset", DateGetTimezoneOffset,
1065 "setTime", DateSetTime,
1066 "setMilliseconds", DateSetMilliseconds,
1067 "setUTCMilliseconds", DateSetUTCMilliseconds,
1068 "setSeconds", DateSetSeconds,
1069 "setUTCSeconds", DateSetUTCSeconds,
1070 "setMinutes", DateSetMinutes,
1071 "setUTCMinutes", DateSetUTCMinutes,
1072 "setHours", DateSetHours,
1073 "setUTCHours", DateSetUTCHours,
1074 "setDate", DateSetDate,
1075 "setUTCDate", DateSetUTCDate,
1076 "setMonth", DateSetMonth,
1077 "setUTCMonth", DateSetUTCMonth,
1078 "setFullYear", DateSetFullYear,
1079 "setUTCFullYear", DateSetUTCFullYear,
1080 "toGMTString", DateToGMTString,
1081 "toUTCString", DateToUTCString,
1082 "getYear", DateGetYear,
1083 "setYear", DateSetYear,
1084 "toISOString", DateToISOString,
1085 "toJSON", DateToJSON
1086 ));
1087 }
1088
1089 SetupDate();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698