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