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

Side by Side Diff: src/date.js

Issue 9572008: Implement date library functions in C++. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: whitespace Created 8 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
« src/date.cc ('K') | « src/date.cc ('k') | src/hydrogen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 26 matching lines...) Expand all
37 // Keep reference to original values of some global properties. This 37 // Keep reference to original values of some global properties. This
38 // has the added benefit that the code in this file is isolated from 38 // has the added benefit that the code in this file is isolated from
39 // changes to these properties. 39 // changes to these properties.
40 var $Date = global.Date; 40 var $Date = global.Date;
41 41
42 // Helper function to throw error. 42 // Helper function to throw error.
43 function ThrowDateTypeError() { 43 function ThrowDateTypeError() {
44 throw new $TypeError('this is not a Date object.'); 44 throw new $TypeError('this is not a Date object.');
45 } 45 }
46 46
47 // ECMA 262 - 5.2
48 function Modulo(value, remainder) {
49 var mod = value % remainder;
50 // Guard against returning -0.
51 if (mod == 0) return 0;
52 return mod >= 0 ? mod : mod + remainder;
53 }
54
55
56 function TimeWithinDay(time) {
57 return Modulo(time, msPerDay);
58 }
59
60
61 // ECMA 262 - 15.9.1.3
62 function DaysInYear(year) {
63 if (year % 4 != 0) return 365;
64 if ((year % 100 == 0) && (year % 400 != 0)) return 365;
65 return 366;
66 }
67
68
69 function DayFromYear(year) {
70 return 365 * (year-1970)
71 + FLOOR((year-1969)/4)
72 - FLOOR((year-1901)/100)
73 + FLOOR((year-1601)/400);
74 }
75
76
77 function TimeFromYear(year) {
78 return msPerDay * DayFromYear(year);
79 }
80
81
82 function InLeapYear(time) {
83 return DaysInYear(YearFromTime(time)) - 365; // Returns 1 or 0.
84 }
85
86
87 // ECMA 262 - 15.9.1.9
88 function EquivalentYear(year) {
89 // Returns an equivalent year in the range [2008-2035] matching
90 // - leap year.
91 // - week day of first day.
92 var time = TimeFromYear(year);
93 var recent_year = (InLeapYear(time) == 0 ? 1967 : 1956) +
94 (WeekDay(time) * 12) % 28;
95 // Find the year in the range 2008..2037 that is equivalent mod 28.
96 // Add 3*28 to give a positive argument to the modulus operator.
97 return 2008 + (recent_year + 3*28 - 2008) % 28;
98 }
99
100
101 function EquivalentTime(t) {
102 // The issue here is that some library calls don't work right for dates
103 // that cannot be represented using a non-negative signed 32 bit integer
104 // (measured in whole seconds based on the 1970 epoch).
105 // We solve this by mapping the time to a year with same leap-year-ness
106 // and same starting day for the year. The ECMAscript specification says
107 // we must do this, but for compatibility with other browsers, we use
108 // the actual year if it is in the range 1970..2037
109 if (t >= 0 && t <= 2.1e12) return t;
110
111 var day = MakeDay(EquivalentYear(YearFromTime(t)),
112 MonthFromTime(t),
113 DateFromTime(t));
114 return MakeDate(day, TimeWithinDay(t));
115 }
116
117
118 // local_time_offset is initialized when the DST_offset_cache is missed.
119 // It must not be used until after a call to DaylightSavingsOffset().
120 // In this way, only one check, for a DST cache miss, is needed.
121 var local_time_offset;
122
123
124 // Because computing the DST offset is an expensive operation,
125 // we keep a cache of the last computed DST offset along with a time interval
126 // where we know the cache is valid.
127 // When the cache is valid, local_time_offset is also valid.
128 var DST_offset_cache = {
129 // Cached DST offset.
130 offset: 0,
131 // Time interval where the cached offset is valid.
132 start: 0, end: -1,
133 // Size of next interval expansion.
134 increment: 0,
135 initial_increment: 19 * msPerDay
136 };
137
138
139 // NOTE: The implementation relies on the fact that no time zones have
140 // more than one daylight savings offset change per 19 days.
141 //
142 // In Egypt in 2010 they decided to suspend DST during Ramadan. This
143 // led to a short interval where DST is in effect from September 10 to
144 // September 30.
145 //
146 // If this function is called with NaN it returns NaN.
147 function DaylightSavingsOffset(t) {
148 // Load the cache object from the builtins object.
149 var cache = DST_offset_cache;
150
151 // Cache the start and the end in local variables for fast access.
152 var start = cache.start;
153 var end = cache.end;
154
155 if (start <= t) {
156 // If the time fits in the cached interval, return the cached offset.
157 if (t <= end) return cache.offset;
158
159 // If the cache misses, the local_time_offset may not be initialized.
160 if (IS_UNDEFINED(local_time_offset)) {
161 local_time_offset = %DateLocalTimeOffset();
162 }
163
164 // Compute a possible new interval end.
165 var new_end = end + cache.increment;
166
167 if (t <= new_end) {
168 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end));
169 if (cache.offset == end_offset) {
170 // If the offset at the end of the new interval still matches
171 // the offset in the cache, we grow the cached time interval
172 // and return the offset.
173 cache.end = new_end;
174 cache.increment = cache.initial_increment;
175 return end_offset;
176 } else {
177 var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
178 if (offset == end_offset) {
179 // The offset at the given time is equal to the offset at the
180 // new end of the interval, so that means that we've just skipped
181 // the point in time where the DST offset change occurred. Updated
182 // the interval to reflect this and reset the increment.
183 cache.start = t;
184 cache.end = new_end;
185 cache.increment = cache.initial_increment;
186 } else {
187 // The interval contains a DST offset change and the given time is
188 // before it. Adjust the increment to avoid a linear search for
189 // the offset change point and change the end of the interval.
190 cache.increment /= 3;
191 cache.end = t;
192 }
193 // Update the offset in the cache and return it.
194 cache.offset = offset;
195 return offset;
196 }
197 }
198 }
199
200 // If the cache misses, the local_time_offset may not be initialized.
201 if (IS_UNDEFINED(local_time_offset)) {
202 local_time_offset = %DateLocalTimeOffset();
203 }
204 // Compute the DST offset for the time and shrink the cache interval
205 // to only contain the time. This allows fast repeated DST offset
206 // computations for the same time.
207 var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
208 cache.offset = offset;
209 cache.start = cache.end = t;
210 cache.increment = cache.initial_increment;
211 return offset;
212 }
213
214 47
215 var timezone_cache_time = $NaN; 48 var timezone_cache_time = $NaN;
216 var timezone_cache_timezone; 49 var timezone_cache_timezone;
217 50
218 function LocalTimezone(t) { 51 function LocalTimezone(t) {
219 if (NUMBER_IS_NAN(t)) return ""; 52 if (NUMBER_IS_NAN(t)) return "";
220 if (t == timezone_cache_time) { 53 if (t == timezone_cache_time) {
221 return timezone_cache_timezone; 54 return timezone_cache_timezone;
222 } 55 }
223 var timezone = %DateLocalTimezone(EquivalentTime(t)); 56 var timezone = %DateLocalTimezone(t);
224 timezone_cache_time = t; 57 timezone_cache_time = t;
225 timezone_cache_timezone = timezone; 58 timezone_cache_timezone = timezone;
226 return timezone; 59 return timezone;
227 } 60 }
228 61
229 62
230 function WeekDay(time) {
231 return Modulo(DAY(time) + 4, 7);
232 }
233
234
235 function LocalTime(time) {
236 if (NUMBER_IS_NAN(time)) return time;
237 // DaylightSavingsOffset called before local_time_offset used.
238 return time + DaylightSavingsOffset(time) + local_time_offset;
239 }
240
241
242 var ltcache = {
243 key: null,
244 val: null
245 };
246
247 function LocalTimeNoCheck(time) {
248 var ltc = ltcache;
249 if (%_ObjectEquals(time, ltc.key)) return ltc.val;
250
251 // Inline the DST offset cache checks for speed.
252 // The cache is hit, or DaylightSavingsOffset is called,
253 // before local_time_offset is used.
254 var cache = DST_offset_cache;
255 if (cache.start <= time && time <= cache.end) {
256 var dst_offset = cache.offset;
257 } else {
258 var dst_offset = DaylightSavingsOffset(time);
259 }
260 ltc.key = time;
261 return (ltc.val = time + local_time_offset + dst_offset);
262 }
263
264
265 function UTC(time) { 63 function UTC(time) {
266 if (NUMBER_IS_NAN(time)) return time; 64 if (NUMBER_IS_NAN(time)) return time;
267 // local_time_offset is needed before the call to DaylightSavingsOffset, 65 // local_time_offset is needed before the call to DaylightSavingsOffset,
268 // so it may be uninitialized. 66 // so it may be uninitialized.
269 if (IS_UNDEFINED(local_time_offset)) { 67 return %DateToUTC(time);
270 local_time_offset = %DateLocalTimeOffset();
271 }
272 var tmp = time - local_time_offset;
273 return tmp - DaylightSavingsOffset(tmp);
274 } 68 }
275 69
276 70
277 // ECMA 262 - 15.9.1.11 71 // ECMA 262 - 15.9.1.11
278 function MakeTime(hour, min, sec, ms) { 72 function MakeTime(hour, min, sec, ms) {
279 if (!$isFinite(hour)) return $NaN; 73 if (!$isFinite(hour)) return $NaN;
280 if (!$isFinite(min)) return $NaN; 74 if (!$isFinite(min)) return $NaN;
281 if (!$isFinite(sec)) return $NaN; 75 if (!$isFinite(sec)) return $NaN;
282 if (!$isFinite(ms)) return $NaN; 76 if (!$isFinite(ms)) return $NaN;
283 return TO_INTEGER(hour) * msPerHour 77 return TO_INTEGER(hour) * msPerHour
284 + TO_INTEGER(min) * msPerMinute 78 + TO_INTEGER(min) * msPerMinute
285 + TO_INTEGER(sec) * msPerSecond 79 + TO_INTEGER(sec) * msPerSecond
286 + TO_INTEGER(ms); 80 + TO_INTEGER(ms);
287 } 81 }
288 82
289 83
290 // ECMA 262 - 15.9.1.12 84 // ECMA 262 - 15.9.1.12
291 function TimeInYear(year) { 85 function TimeInYear(year) {
292 return DaysInYear(year) * msPerDay; 86 return DaysInYear(year) * msPerDay;
293 } 87 }
294 88
295 89
296 var ymd_from_time_cache = [1970, 0, 1];
297 var ymd_from_time_cached_time = 0;
298
299 function YearFromTime(t) {
300 if (t !== ymd_from_time_cached_time) {
301 if (!$isFinite(t)) {
302 return $NaN;
303 }
304
305 %DateYMDFromTime(t, ymd_from_time_cache);
306 ymd_from_time_cached_time = t;
307 }
308
309 return ymd_from_time_cache[0];
310 }
311
312 function MonthFromTime(t) {
313 if (t !== ymd_from_time_cached_time) {
314 if (!$isFinite(t)) {
315 return $NaN;
316 }
317 %DateYMDFromTime(t, ymd_from_time_cache);
318 ymd_from_time_cached_time = t;
319 }
320
321 return ymd_from_time_cache[1];
322 }
323
324 function DateFromTime(t) {
325 if (t !== ymd_from_time_cached_time) {
326 if (!$isFinite(t)) {
327 return $NaN;
328 }
329
330 %DateYMDFromTime(t, ymd_from_time_cache);
331 ymd_from_time_cached_time = t;
332 }
333
334 return ymd_from_time_cache[2];
335 }
336
337
338 // Compute number of days given a year, month, date. 90 // Compute number of days given a year, month, date.
339 // Note that month and date can lie outside the normal range. 91 // Note that month and date can lie outside the normal range.
340 // For example: 92 // For example:
341 // MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20) 93 // MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
342 // MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1) 94 // MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
343 // MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11) 95 // MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
344 function MakeDay(year, month, date) { 96 function MakeDay(year, month, date) {
345 if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return $NaN; 97 if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return $NaN;
346 98
347 // Convert to integer and map -0 to 0. 99 // Convert to integer and map -0 to 0.
(...skipping 30 matching lines...) Expand all
378 if ($abs(time) > MAX_TIME_MS) return $NaN; 130 if ($abs(time) > MAX_TIME_MS) return $NaN;
379 return TO_INTEGER(time); 131 return TO_INTEGER(time);
380 } 132 }
381 133
382 134
383 // The Date cache is used to limit the cost of parsing the same Date 135 // The Date cache is used to limit the cost of parsing the same Date
384 // strings over and over again. 136 // strings over and over again.
385 var Date_cache = { 137 var Date_cache = {
386 // Cached time value. 138 // Cached time value.
387 time: $NaN, 139 time: $NaN,
388 // Cached year when interpreting the time as a local time. Only
389 // valid when the time matches cached time.
390 year: $NaN,
391 // String input for which the cached time is valid. 140 // String input for which the cached time is valid.
392 string: null 141 string: null
393 }; 142 };
394 143
395 144
396 %SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) { 145 %SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
397 if (!%_IsConstructCall()) { 146 if (!%_IsConstructCall()) {
398 // ECMA 262 - 15.9.2 147 // ECMA 262 - 15.9.2
399 return (new $Date()).toString(); 148 return (new $Date()).toString();
400 } 149 }
401 150
402 // ECMA 262 - 15.9.3 151 // ECMA 262 - 15.9.3
403 var argc = %_ArgumentsLength(); 152 var argc = %_ArgumentsLength();
404 var value; 153 var value;
405 if (argc == 0) { 154 if (argc == 0) {
406 value = %DateCurrentTime(); 155 value = %DateCurrentTime();
407 156 SET_UTC_DATE_VALUE(this, value);
408 } else if (argc == 1) { 157 } else if (argc == 1) {
409 if (IS_NUMBER(year)) { 158 if (IS_NUMBER(year)) {
410 value = TimeClip(year); 159 value = year;
411
412 } else if (IS_STRING(year)) { 160 } else if (IS_STRING(year)) {
413 // Probe the Date cache. If we already have a time value for the 161 // Probe the Date cache. If we already have a time value for the
414 // given time, we re-use that instead of parsing the string again. 162 // given time, we re-use that instead of parsing the string again.
415 var cache = Date_cache; 163 var cache = Date_cache;
416 if (cache.string === year) { 164 if (cache.string === year) {
417 value = cache.time; 165 value = cache.time;
418 } else { 166 } else {
419 value = DateParse(year); 167 value = DateParse(year);
420 if (!NUMBER_IS_NAN(value)) { 168 if (!NUMBER_IS_NAN(value)) {
421 cache.time = value; 169 cache.time = value;
422 cache.year = YearFromTime(LocalTimeNoCheck(value));
423 cache.string = year; 170 cache.string = year;
424 } 171 }
425 } 172 }
426 173
427 } else { 174 } else {
428 // According to ECMA 262, no hint should be given for this 175 // According to ECMA 262, no hint should be given for this
429 // conversion. However, ToPrimitive defaults to STRING_HINT for 176 // conversion. However, ToPrimitive defaults to STRING_HINT for
430 // Date objects which will lose precision when the Date 177 // Date objects which will lose precision when the Date
431 // constructor is called with another Date object as its 178 // constructor is called with another Date object as its
432 // argument. We therefore use NUMBER_HINT for the conversion, 179 // argument. We therefore use NUMBER_HINT for the conversion,
433 // which is the default for everything else than Date objects. 180 // which is the default for everything else than Date objects.
434 // This makes us behave like KJS and SpiderMonkey. 181 // This makes us behave like KJS and SpiderMonkey.
435 var time = ToPrimitive(year, NUMBER_HINT); 182 var time = ToPrimitive(year, NUMBER_HINT);
436 value = IS_STRING(time) ? DateParse(time) : TimeClip(ToNumber(time)); 183 value = IS_STRING(time) ? DateParse(time) : ToNumber(time);
437 } 184 }
438 185 SET_UTC_DATE_VALUE(this, value);
439 } else { 186 } else {
440 year = ToNumber(year); 187 year = ToNumber(year);
441 month = ToNumber(month); 188 month = ToNumber(month);
442 date = argc > 2 ? ToNumber(date) : 1; 189 date = argc > 2 ? ToNumber(date) : 1;
443 hours = argc > 3 ? ToNumber(hours) : 0; 190 hours = argc > 3 ? ToNumber(hours) : 0;
444 minutes = argc > 4 ? ToNumber(minutes) : 0; 191 minutes = argc > 4 ? ToNumber(minutes) : 0;
445 seconds = argc > 5 ? ToNumber(seconds) : 0; 192 seconds = argc > 5 ? ToNumber(seconds) : 0;
446 ms = argc > 6 ? ToNumber(ms) : 0; 193 ms = argc > 6 ? ToNumber(ms) : 0;
447 year = (!NUMBER_IS_NAN(year) && 194 year = (!NUMBER_IS_NAN(year) &&
448 0 <= TO_INTEGER(year) && 195 0 <= TO_INTEGER(year) &&
449 TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year; 196 TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
450 var day = MakeDay(year, month, date); 197 var day = MakeDay(year, month, date);
451 var time = MakeTime(hours, minutes, seconds, ms); 198 var time = MakeTime(hours, minutes, seconds, ms);
452 value = TimeClip(UTC(MakeDate(day, time))); 199 value = MakeDate(day, time);
200 SET_LOCAL_DATE_VALUE(this, value);
453 } 201 }
454 %_SetValueOf(this, value);
455 }); 202 });
456 203
457 204
458 %FunctionSetPrototype($Date, new $Date($NaN)); 205 %FunctionSetPrototype($Date, new $Date($NaN));
459 206
460 207
461 var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; 208 var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
462 var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 209 var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
463 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; 210 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
464 211
465 212
466 function TwoDigitString(value) { 213 function TwoDigitString(value) {
467 return value < 10 ? "0" + value : "" + value; 214 return value < 10 ? "0" + value : "" + value;
468 } 215 }
469 216
470 217
471 function DateString(time) { 218 function DateString(date) {
472 return WeekDays[WeekDay(time)] + ' ' 219 return WeekDays[LOCAL_WEEKDAY(date)] + ' '
473 + Months[MonthFromTime(time)] + ' ' 220 + Months[LOCAL_MONTH(date)] + ' '
474 + TwoDigitString(DateFromTime(time)) + ' ' 221 + TwoDigitString(LOCAL_DAY(date)) + ' '
475 + YearFromTime(time); 222 + LOCAL_YEAR(date);
476 } 223 }
477 224
478 225
479 var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 226 var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
480 'Thursday', 'Friday', 'Saturday']; 227 'Thursday', 'Friday', 'Saturday'];
481 var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June', 228 var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June',
482 'July', 'August', 'September', 'October', 'November', 'December']; 229 'July', 'August', 'September', 'October', 'November', 'December'];
483 230
484 231
485 function LongDateString(time) { 232 function LongDateString(date) {
486 return LongWeekDays[WeekDay(time)] + ', ' 233 return LongWeekDays[LOCAL_WEEKDAY(date)] + ', '
487 + LongMonths[MonthFromTime(time)] + ' ' 234 + LongMonths[LOCAL_MONTH(date)] + ' '
488 + TwoDigitString(DateFromTime(time)) + ', ' 235 + TwoDigitString(LOCAL_DAY(date)) + ', '
489 + YearFromTime(time); 236 + LOCAL_YEAR(date);
490 } 237 }
491 238
492 239
493 function TimeString(time) { 240 function TimeString(date) {
494 return TwoDigitString(HOUR_FROM_TIME(time)) + ':' 241 return TwoDigitString(LOCAL_HOUR(date)) + ':'
495 + TwoDigitString(MIN_FROM_TIME(time)) + ':' 242 + TwoDigitString(LOCAL_MIN(date)) + ':'
496 + TwoDigitString(SEC_FROM_TIME(time)); 243 + TwoDigitString(LOCAL_SEC(date));
497 } 244 }
498 245
499 246
500 function LocalTimezoneString(time) { 247 function LocalTimezoneString(date) {
501 var old_timezone = timezone_cache_timezone; 248 var timezone = LocalTimezone(UTC_DATE_VALUE(date));
502 var timezone = LocalTimezone(time);
503 if (old_timezone && timezone != old_timezone) {
504 // If the timezone string has changed from the one that we cached,
505 // the local time offset may now be wrong. So we need to update it
506 // and try again.
507 local_time_offset = %DateLocalTimeOffset();
508 // We also need to invalidate the DST cache as the new timezone may have
509 // different DST times.
510 var dst_cache = DST_offset_cache;
511 dst_cache.start = 0;
512 dst_cache.end = -1;
513 }
514 249
515 var timezoneOffset = 250 var timezoneOffset = TIMEZONE_OFFSET(date);
516 (DaylightSavingsOffset(time) + local_time_offset) / msPerMinute;
517 var sign = (timezoneOffset >= 0) ? 1 : -1; 251 var sign = (timezoneOffset >= 0) ? 1 : -1;
518 var hours = FLOOR((sign * timezoneOffset)/60); 252 var hours = FLOOR((sign * timezoneOffset)/60);
519 var min = FLOOR((sign * timezoneOffset)%60); 253 var min = FLOOR((sign * timezoneOffset)%60);
520 var gmt = ' GMT' + ((sign == 1) ? '+' : '-') + 254 var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
521 TwoDigitString(hours) + TwoDigitString(min); 255 TwoDigitString(hours) + TwoDigitString(min);
522 return gmt + ' (' + timezone + ')'; 256 return gmt + ' (' + timezone + ')';
523 } 257 }
524 258
525 259
526 function DatePrintString(time) { 260 function DatePrintString(date) {
527 return DateString(time) + ' ' + TimeString(time); 261 return DateString(date) + ' ' + TimeString(date);
528 } 262 }
529 263
530 // ------------------------------------------------------------------- 264 // -------------------------------------------------------------------
531 265
532 // Reused output buffer. Used when parsing date strings. 266 // Reused output buffer. Used when parsing date strings.
533 var parse_buffer = $Array(8); 267 var parse_buffer = $Array(8);
534 268
535 // ECMA 262 - 15.9.4.2 269 // ECMA 262 - 15.9.4.2
536 function DateParse(string) { 270 function DateParse(string) {
537 var arr = %DateParseString(ToString(string), parse_buffer); 271 var arr = %DateParseString(ToString(string), parse_buffer);
(...skipping 19 matching lines...) Expand all
557 date = argc > 2 ? ToNumber(date) : 1; 291 date = argc > 2 ? ToNumber(date) : 1;
558 hours = argc > 3 ? ToNumber(hours) : 0; 292 hours = argc > 3 ? ToNumber(hours) : 0;
559 minutes = argc > 4 ? ToNumber(minutes) : 0; 293 minutes = argc > 4 ? ToNumber(minutes) : 0;
560 seconds = argc > 5 ? ToNumber(seconds) : 0; 294 seconds = argc > 5 ? ToNumber(seconds) : 0;
561 ms = argc > 6 ? ToNumber(ms) : 0; 295 ms = argc > 6 ? ToNumber(ms) : 0;
562 year = (!NUMBER_IS_NAN(year) && 296 year = (!NUMBER_IS_NAN(year) &&
563 0 <= TO_INTEGER(year) && 297 0 <= TO_INTEGER(year) &&
564 TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year; 298 TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year;
565 var day = MakeDay(year, month, date); 299 var day = MakeDay(year, month, date);
566 var time = MakeTime(hours, minutes, seconds, ms); 300 var time = MakeTime(hours, minutes, seconds, ms);
567 return %_SetValueOf(this, TimeClip(MakeDate(day, time))); 301 return TimeClip(MakeDate(day, time));
568 } 302 }
569 303
570 304
571 // Mozilla-specific extension. Returns the number of milliseconds 305 // Mozilla-specific extension. Returns the number of milliseconds
572 // elapsed since 1 January 1970 00:00:00 UTC. 306 // elapsed since 1 January 1970 00:00:00 UTC.
573 function DateNow() { 307 function DateNow() {
574 return %DateCurrentTime(); 308 return %DateCurrentTime();
575 } 309 }
576 310
577 311
578 // ECMA 262 - 15.9.5.2 312 // ECMA 262 - 15.9.5.2
579 function DateToString() { 313 function DateToString() {
580 var t = DATE_VALUE(this); 314 CHECK_DATE(this);
315 var t = UTC_DATE_VALUE(this)
581 if (NUMBER_IS_NAN(t)) return kInvalidDate; 316 if (NUMBER_IS_NAN(t)) return kInvalidDate;
582 var time_zone_string = LocalTimezoneString(t); // May update local offset. 317 var time_zone_string = LocalTimezoneString(this)
583 return DatePrintString(LocalTimeNoCheck(t)) + time_zone_string; 318 return DatePrintString(this) + time_zone_string;
584 } 319 }
585 320
586 321
587 // ECMA 262 - 15.9.5.3 322 // ECMA 262 - 15.9.5.3
588 function DateToDateString() { 323 function DateToDateString() {
589 var t = DATE_VALUE(this); 324 CHECK_DATE(this);
325 var t = UTC_DATE_VALUE(this);
590 if (NUMBER_IS_NAN(t)) return kInvalidDate; 326 if (NUMBER_IS_NAN(t)) return kInvalidDate;
591 return DateString(LocalTimeNoCheck(t)); 327 return DateString(this);
592 } 328 }
593 329
594 330
595 // ECMA 262 - 15.9.5.4 331 // ECMA 262 - 15.9.5.4
596 function DateToTimeString() { 332 function DateToTimeString() {
597 var t = DATE_VALUE(this); 333 CHECK_DATE(this);
334 var t = UTC_DATE_VALUE(this);
598 if (NUMBER_IS_NAN(t)) return kInvalidDate; 335 if (NUMBER_IS_NAN(t)) return kInvalidDate;
599 var time_zone_string = LocalTimezoneString(t); // May update local offset. 336 var time_zone_string = LocalTimezoneString(this);
600 return TimeString(LocalTimeNoCheck(t)) + time_zone_string; 337 return TimeString(this) + time_zone_string;
601 } 338 }
602 339
603 340
604 // ECMA 262 - 15.9.5.5 341 // ECMA 262 - 15.9.5.5
605 function DateToLocaleString() { 342 function DateToLocaleString() {
606 return %_CallFunction(this, DateToString); 343 return %_CallFunction(this, DateToString);
607 } 344 }
608 345
609 346
610 // ECMA 262 - 15.9.5.6 347 // ECMA 262 - 15.9.5.6
611 function DateToLocaleDateString() { 348 function DateToLocaleDateString() {
612 var t = DATE_VALUE(this); 349 CHECK_DATE(this);
350 var t = UTC_DATE_VALUE(this);
613 if (NUMBER_IS_NAN(t)) return kInvalidDate; 351 if (NUMBER_IS_NAN(t)) return kInvalidDate;
614 return LongDateString(LocalTimeNoCheck(t)); 352 return LongDateString(this);
615 } 353 }
616 354
617 355
618 // ECMA 262 - 15.9.5.7 356 // ECMA 262 - 15.9.5.7
619 function DateToLocaleTimeString() { 357 function DateToLocaleTimeString() {
620 var t = DATE_VALUE(this); 358 CHECK_DATE(this);
359 var t = UTC_DATE_VALUE(this);
621 if (NUMBER_IS_NAN(t)) return kInvalidDate; 360 if (NUMBER_IS_NAN(t)) return kInvalidDate;
622 var lt = LocalTimeNoCheck(t); 361 return TimeString(this);
623 return TimeString(lt);
624 } 362 }
625 363
626 364
627 // ECMA 262 - 15.9.5.8 365 // ECMA 262 - 15.9.5.8
628 function DateValueOf() { 366 function DateValueOf() {
629 return DATE_VALUE(this); 367 CHECK_DATE(this);
368 return UTC_DATE_VALUE(this);
630 } 369 }
631 370
632 371
633 // ECMA 262 - 15.9.5.9 372 // ECMA 262 - 15.9.5.9
634 function DateGetTime() { 373 function DateGetTime() {
635 return DATE_VALUE(this); 374 CHECK_DATE(this);
375 return UTC_DATE_VALUE(this);
636 } 376 }
637 377
638 378
639 // ECMA 262 - 15.9.5.10 379 // ECMA 262 - 15.9.5.10
640 function DateGetFullYear() { 380 function DateGetFullYear() {
641 var t = DATE_VALUE(this); 381 CHECK_DATE(this);
642 if (NUMBER_IS_NAN(t)) return t; 382 return LOCAL_YEAR(this);
643 var cache = Date_cache;
644 if (cache.time === t) return cache.year;
645 return YearFromTime(LocalTimeNoCheck(t));
646 } 383 }
647 384
648 385
649 // ECMA 262 - 15.9.5.11 386 // ECMA 262 - 15.9.5.11
650 function DateGetUTCFullYear() { 387 function DateGetUTCFullYear() {
651 var t = DATE_VALUE(this); 388 CHECK_DATE(this);
652 if (NUMBER_IS_NAN(t)) return t; 389 return UTC_YEAR(this);
653 return YearFromTime(t);
654 } 390 }
655 391
656 392
657 // ECMA 262 - 15.9.5.12 393 // ECMA 262 - 15.9.5.12
658 function DateGetMonth() { 394 function DateGetMonth() {
659 var t = DATE_VALUE(this); 395 CHECK_DATE(this);
660 if (NUMBER_IS_NAN(t)) return t; 396 return LOCAL_MONTH(this);
661 return MonthFromTime(LocalTimeNoCheck(t));
662 } 397 }
663 398
664 399
665 // ECMA 262 - 15.9.5.13 400 // ECMA 262 - 15.9.5.13
666 function DateGetUTCMonth() { 401 function DateGetUTCMonth() {
667 var t = DATE_VALUE(this); 402 CHECK_DATE(this);
668 if (NUMBER_IS_NAN(t)) return t; 403 return UTC_MONTH(this);
669 return MonthFromTime(t);
670 } 404 }
671 405
672 406
673 // ECMA 262 - 15.9.5.14 407 // ECMA 262 - 15.9.5.14
674 function DateGetDate() { 408 function DateGetDate() {
675 var t = DATE_VALUE(this); 409 CHECK_DATE(this);
676 if (NUMBER_IS_NAN(t)) return t; 410 return LOCAL_DAY(this);
677 return DateFromTime(LocalTimeNoCheck(t));
678 } 411 }
679 412
680 413
681 // ECMA 262 - 15.9.5.15 414 // ECMA 262 - 15.9.5.15
682 function DateGetUTCDate() { 415 function DateGetUTCDate() {
683 var t = DATE_VALUE(this); 416 CHECK_DATE(this);
684 return NAN_OR_DATE_FROM_TIME(t); 417 return UTC_DAY(this);
685 } 418 }
686 419
687 420
688 // ECMA 262 - 15.9.5.16 421 // ECMA 262 - 15.9.5.16
689 function DateGetDay() { 422 function DateGetDay() {
690 var t = DATE_VALUE(this); 423 CHECK_DATE(this);
691 if (NUMBER_IS_NAN(t)) return t; 424 return LOCAL_WEEKDAY(this);
692 return WeekDay(LocalTimeNoCheck(t));
693 } 425 }
694 426
695 427
696 // ECMA 262 - 15.9.5.17 428 // ECMA 262 - 15.9.5.17
697 function DateGetUTCDay() { 429 function DateGetUTCDay() {
698 var t = DATE_VALUE(this); 430 CHECK_DATE(this);
699 if (NUMBER_IS_NAN(t)) return t; 431 return UTC_WEEKDAY(this);
700 return WeekDay(t);
701 } 432 }
702 433
703 434
704 // ECMA 262 - 15.9.5.18 435 // ECMA 262 - 15.9.5.18
705 function DateGetHours() { 436 function DateGetHours() {
706 var t = DATE_VALUE(this); 437 CHECK_DATE(this);
707 if (NUMBER_IS_NAN(t)) return t; 438 return LOCAL_HOUR(this);
708 return HOUR_FROM_TIME(LocalTimeNoCheck(t));
709 } 439 }
710 440
711 441
712 // ECMA 262 - 15.9.5.19 442 // ECMA 262 - 15.9.5.19
713 function DateGetUTCHours() { 443 function DateGetUTCHours() {
714 var t = DATE_VALUE(this); 444 CHECK_DATE(this);
715 if (NUMBER_IS_NAN(t)) return t; 445 return UTC_HOUR(this);
716 return HOUR_FROM_TIME(t);
717 } 446 }
718 447
719 448
720 // ECMA 262 - 15.9.5.20 449 // ECMA 262 - 15.9.5.20
721 function DateGetMinutes() { 450 function DateGetMinutes() {
722 var t = DATE_VALUE(this); 451 CHECK_DATE(this);
723 if (NUMBER_IS_NAN(t)) return t; 452 return LOCAL_MIN(this);
724 return MIN_FROM_TIME(LocalTimeNoCheck(t));
725 } 453 }
726 454
727 455
728 // ECMA 262 - 15.9.5.21 456 // ECMA 262 - 15.9.5.21
729 function DateGetUTCMinutes() { 457 function DateGetUTCMinutes() {
730 var t = DATE_VALUE(this); 458 CHECK_DATE(this);
731 return NAN_OR_MIN_FROM_TIME(t); 459 return UTC_MIN(this);
732 } 460 }
733 461
734 462
735 // ECMA 262 - 15.9.5.22 463 // ECMA 262 - 15.9.5.22
736 function DateGetSeconds() { 464 function DateGetSeconds() {
737 var t = DATE_VALUE(this); 465 CHECK_DATE(this);
738 if (NUMBER_IS_NAN(t)) return t; 466 return LOCAL_SEC(this);
739 return SEC_FROM_TIME(LocalTimeNoCheck(t));
740 } 467 }
741 468
742 469
743 // ECMA 262 - 15.9.5.23 470 // ECMA 262 - 15.9.5.23
744 function DateGetUTCSeconds() { 471 function DateGetUTCSeconds() {
745 var t = DATE_VALUE(this); 472 CHECK_DATE(this);
746 return NAN_OR_SEC_FROM_TIME(t); 473 return UTC_SEC(this)
747 } 474 }
748 475
749 476
750 // ECMA 262 - 15.9.5.24 477 // ECMA 262 - 15.9.5.24
751 function DateGetMilliseconds() { 478 function DateGetMilliseconds() {
752 var t = DATE_VALUE(this); 479 CHECK_DATE(this);
753 if (NUMBER_IS_NAN(t)) return t; 480 return LOCAL_MS(this);
754 return MS_FROM_TIME(LocalTimeNoCheck(t));
755 } 481 }
756 482
757 483
758 // ECMA 262 - 15.9.5.25 484 // ECMA 262 - 15.9.5.25
759 function DateGetUTCMilliseconds() { 485 function DateGetUTCMilliseconds() {
760 var t = DATE_VALUE(this); 486 CHECK_DATE(this);
761 return NAN_OR_MS_FROM_TIME(t); 487 return UTC_MS(this);
762 } 488 }
763 489
764 490
765 // ECMA 262 - 15.9.5.26 491 // ECMA 262 - 15.9.5.26
766 function DateGetTimezoneOffset() { 492 function DateGetTimezoneOffset() {
767 var t = DATE_VALUE(this); 493 CHECK_DATE(this);
768 if (NUMBER_IS_NAN(t)) return t; 494 return TIMEZONE_OFFSET(this);
769 return (t - LocalTimeNoCheck(t)) / msPerMinute;
770 } 495 }
771 496
772 497
773 // ECMA 262 - 15.9.5.27 498 // ECMA 262 - 15.9.5.27
774 function DateSetTime(ms) { 499 function DateSetTime(ms) {
775 if (!IS_DATE(this)) ThrowDateTypeError(); 500 CHECK_DATE(this);
776 return %_SetValueOf(this, TimeClip(ToNumber(ms))); 501 return SET_UTC_DATE_VALUE(this, ToNumber(ms));
777 } 502 }
778 503
779 504
780 // ECMA 262 - 15.9.5.28 505 // ECMA 262 - 15.9.5.28
781 function DateSetMilliseconds(ms) { 506 function DateSetMilliseconds(ms) {
782 var t = LocalTime(DATE_VALUE(this)); 507 CHECK_DATE(this);
508 var t = LOCAL_DATE_VALUE(this);
783 ms = ToNumber(ms); 509 ms = ToNumber(ms);
784 var time = MakeTime(HOUR_FROM_TIME(t), 510 var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), LOCAL_SEC(this), ms);
785 MIN_FROM_TIME(t), 511 SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
786 SEC_FROM_TIME(t), 512 return this;
787 ms);
788 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time))));
789 } 513 }
790 514
791 515
792 // ECMA 262 - 15.9.5.29 516 // ECMA 262 - 15.9.5.29
793 function DateSetUTCMilliseconds(ms) { 517 function DateSetUTCMilliseconds(ms) {
794 var t = DATE_VALUE(this); 518 CHECK_DATE(this);
519 var t = UTC_DATE_VALUE(this);
795 ms = ToNumber(ms); 520 ms = ToNumber(ms);
796 var time = MakeTime(HOUR_FROM_TIME(t), 521 var time = MakeTime(UTC_HOUR(this),
797 MIN_FROM_TIME(t), 522 UTC_MIN(this),
798 SEC_FROM_TIME(t), 523 UTC_SEC(this),
799 ms); 524 ms);
800 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time))); 525 return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
801 } 526 }
802 527
803 528
804 // ECMA 262 - 15.9.5.30 529 // ECMA 262 - 15.9.5.30
805 function DateSetSeconds(sec, ms) { 530 function DateSetSeconds(sec, ms) {
806 var t = LocalTime(DATE_VALUE(this)); 531 CHECK_DATE(this);
532 var t = LOCAL_DATE_VALUE(this);
807 sec = ToNumber(sec); 533 sec = ToNumber(sec);
808 ms = %_ArgumentsLength() < 2 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms); 534 ms = %_ArgumentsLength() < 2 ? LOCAL_MS(this) : ToNumber(ms);
809 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), sec, ms); 535 var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), sec, ms);
810 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time)))); 536 return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
811 } 537 }
812 538
813 539
814 // ECMA 262 - 15.9.5.31 540 // ECMA 262 - 15.9.5.31
815 function DateSetUTCSeconds(sec, ms) { 541 function DateSetUTCSeconds(sec, ms) {
816 var t = DATE_VALUE(this); 542 CHECK_DATE(this);
543 var t = UTC_DATE_VALUE(this);
817 sec = ToNumber(sec); 544 sec = ToNumber(sec);
818 ms = %_ArgumentsLength() < 2 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms); 545 ms = %_ArgumentsLength() < 2 ? UTC_MS(this) : ToNumber(ms);
819 var time = MakeTime(HOUR_FROM_TIME(t), MIN_FROM_TIME(t), sec, ms); 546 var time = MakeTime(UTC_HOUR(this), UTC_MIN(this), sec, ms);
820 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time))); 547 return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
821 } 548 }
822 549
823 550
824 // ECMA 262 - 15.9.5.33 551 // ECMA 262 - 15.9.5.33
825 function DateSetMinutes(min, sec, ms) { 552 function DateSetMinutes(min, sec, ms) {
826 var t = LocalTime(DATE_VALUE(this)); 553 CHECK_DATE(this);
554 var t = LOCAL_DATE_VALUE(this);
827 min = ToNumber(min); 555 min = ToNumber(min);
828 var argc = %_ArgumentsLength(); 556 var argc = %_ArgumentsLength();
829 sec = argc < 2 ? NAN_OR_SEC_FROM_TIME(t) : ToNumber(sec); 557 sec = argc < 2 ? LOCAL_SEC(this) : ToNumber(sec);
830 ms = argc < 3 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms); 558 ms = argc < 3 ? LOCAL_MS(this) : ToNumber(ms);
831 var time = MakeTime(HOUR_FROM_TIME(t), min, sec, ms); 559 var time = MakeTime(LOCAL_HOUR(this), min, sec, ms);
832 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time)))); 560 return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
833 } 561 }
834 562
835 563
836 // ECMA 262 - 15.9.5.34 564 // ECMA 262 - 15.9.5.34
837 function DateSetUTCMinutes(min, sec, ms) { 565 function DateSetUTCMinutes(min, sec, ms) {
838 var t = DATE_VALUE(this); 566 CHECK_DATE(this);
567 var t = UTC_DATE_VALUE(this);
839 min = ToNumber(min); 568 min = ToNumber(min);
840 var argc = %_ArgumentsLength(); 569 var argc = %_ArgumentsLength();
841 sec = argc < 2 ? NAN_OR_SEC_FROM_TIME(t) : ToNumber(sec); 570 sec = argc < 2 ? UTC_SEC(this) : ToNumber(sec);
842 ms = argc < 3 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms); 571 ms = argc < 3 ? UTC_MS(this) : ToNumber(ms);
843 var time = MakeTime(HOUR_FROM_TIME(t), min, sec, ms); 572 var time = MakeTime(UTC_HOUR(this), min, sec, ms);
844 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time))); 573 return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
845 } 574 }
846 575
847 576
848 // ECMA 262 - 15.9.5.35 577 // ECMA 262 - 15.9.5.35
849 function DateSetHours(hour, min, sec, ms) { 578 function DateSetHours(hour, min, sec, ms) {
850 var t = LocalTime(DATE_VALUE(this)); 579 CHECK_DATE(this);
580 var t = LOCAL_DATE_VALUE(this);
851 hour = ToNumber(hour); 581 hour = ToNumber(hour);
852 var argc = %_ArgumentsLength(); 582 var argc = %_ArgumentsLength();
853 min = argc < 2 ? NAN_OR_MIN_FROM_TIME(t) : ToNumber(min); 583 min = argc < 2 ? LOCAL_MIN(this) : ToNumber(min);
854 sec = argc < 3 ? NAN_OR_SEC_FROM_TIME(t) : ToNumber(sec); 584 sec = argc < 3 ? LOCAL_SEC(this) : ToNumber(sec);
855 ms = argc < 4 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms); 585 ms = argc < 4 ? LOCAL_MS(this) : ToNumber(ms);
856 var time = MakeTime(hour, min, sec, ms); 586 var time = MakeTime(hour, min, sec, ms);
857 return %_SetValueOf(this, TimeClip(UTC(MakeDate(DAY(t), time)))); 587 return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
858 } 588 }
859 589
860 590
861 // ECMA 262 - 15.9.5.34 591 // ECMA 262 - 15.9.5.34
862 function DateSetUTCHours(hour, min, sec, ms) { 592 function DateSetUTCHours(hour, min, sec, ms) {
863 var t = DATE_VALUE(this); 593 CHECK_DATE(this);
594 var t = UTC_DATE_VALUE(this);
864 hour = ToNumber(hour); 595 hour = ToNumber(hour);
865 var argc = %_ArgumentsLength(); 596 var argc = %_ArgumentsLength();
866 min = argc < 2 ? NAN_OR_MIN_FROM_TIME(t) : ToNumber(min); 597 min = argc < 2 ? UTC_MIN(this) : ToNumber(min);
867 sec = argc < 3 ? NAN_OR_SEC_FROM_TIME(t) : ToNumber(sec); 598 sec = argc < 3 ? UTC_SEC(this) : ToNumber(sec);
868 ms = argc < 4 ? NAN_OR_MS_FROM_TIME(t) : ToNumber(ms); 599 ms = argc < 4 ? UTC_MS(this) : ToNumber(ms);
869 var time = MakeTime(hour, min, sec, ms); 600 var time = MakeTime(hour, min, sec, ms);
870 return %_SetValueOf(this, TimeClip(MakeDate(DAY(t), time))); 601 return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
871 } 602 }
872 603
873 604
874 // ECMA 262 - 15.9.5.36 605 // ECMA 262 - 15.9.5.36
875 function DateSetDate(date) { 606 function DateSetDate(date) {
876 var t = LocalTime(DATE_VALUE(this)); 607 CHECK_DATE(this);
608 var t = LOCAL_DATE_VALUE(this);
877 date = ToNumber(date); 609 date = ToNumber(date);
878 var day = MakeDay(YearFromTime(t), MonthFromTime(t), date); 610 var day = MakeDay(LOCAL_YEAR(this), LOCAL_MONTH(this), date);
879 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t))))); 611 return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
880 } 612 }
881 613
882 614
883 // ECMA 262 - 15.9.5.37 615 // ECMA 262 - 15.9.5.37
884 function DateSetUTCDate(date) { 616 function DateSetUTCDate(date) {
885 var t = DATE_VALUE(this); 617 CHECK_DATE(this);
618 var t = UTC_DATE_VALUE(this);
886 date = ToNumber(date); 619 date = ToNumber(date);
887 var day = MakeDay(YearFromTime(t), MonthFromTime(t), date); 620 var day = MakeDay(UTC_YEAR(this), UTC_MONTH(this), date);
888 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t)))); 621 return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
889 } 622 }
890 623
891 624
892 // ECMA 262 - 15.9.5.38 625 // ECMA 262 - 15.9.5.38
893 function DateSetMonth(month, date) { 626 function DateSetMonth(month, date) {
894 var t = LocalTime(DATE_VALUE(this)); 627 CHECK_DATE(this);
628 var t = LOCAL_DATE_VALUE(this);
895 month = ToNumber(month); 629 month = ToNumber(month);
896 date = %_ArgumentsLength() < 2 ? NAN_OR_DATE_FROM_TIME(t) : ToNumber(date); 630 date = %_ArgumentsLength() < 2 ? LOCAL_DAY(this) : ToNumber(date);
897 var day = MakeDay(YearFromTime(t), month, date); 631 var day = MakeDay(LOCAL_YEAR(this), month, date);
898 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t))))); 632 return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
899 } 633 }
900 634
901 635
902 // ECMA 262 - 15.9.5.39 636 // ECMA 262 - 15.9.5.39
903 function DateSetUTCMonth(month, date) { 637 function DateSetUTCMonth(month, date) {
904 var t = DATE_VALUE(this); 638 CHECK_DATE(this);
639 var t = UTC_DATE_VALUE(this);
905 month = ToNumber(month); 640 month = ToNumber(month);
906 date = %_ArgumentsLength() < 2 ? NAN_OR_DATE_FROM_TIME(t) : ToNumber(date); 641 date = %_ArgumentsLength() < 2 ? UTC_DAY(this) : ToNumber(date);
907 var day = MakeDay(YearFromTime(t), month, date); 642 var day = MakeDay(UTC_YEAR(this), month, date);
908 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t)))); 643 return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
909 } 644 }
910 645
911 646
912 // ECMA 262 - 15.9.5.40 647 // ECMA 262 - 15.9.5.40
913 function DateSetFullYear(year, month, date) { 648 function DateSetFullYear(year, month, date) {
914 var t = DATE_VALUE(this); 649 CHECK_DATE(this);
915 t = NUMBER_IS_NAN(t) ? 0 : LocalTimeNoCheck(t); 650 var t = LOCAL_DATE_VALUE(this);
916 year = ToNumber(year); 651 year = ToNumber(year);
917 var argc = %_ArgumentsLength(); 652 var argc = %_ArgumentsLength();
918 month = argc < 2 ? MonthFromTime(t) : ToNumber(month); 653 var time ;
919 date = argc < 3 ? DateFromTime(t) : ToNumber(date); 654 if (NUMBER_IS_NAN(t)) {
655 month = argc < 2 ? 0 : ToNumber(month);
656 date = argc < 3 ? 1 : ToNumber(date);
657 time = 0;
658 } else {
659 month = argc < 2 ? LOCAL_MONTH(this) : ToNumber(month);
660 date = argc < 3 ? LOCAL_DAY(this) : ToNumber(date);
661 time = LOCAL_TIME_IN_DAY(this);
662 }
920 var day = MakeDay(year, month, date); 663 var day = MakeDay(year, month, date);
921 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t))))); 664 return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
922 } 665 }
923 666
924 667
925 // ECMA 262 - 15.9.5.41 668 // ECMA 262 - 15.9.5.41
926 function DateSetUTCFullYear(year, month, date) { 669 function DateSetUTCFullYear(year, month, date) {
927 var t = DATE_VALUE(this); 670 CHECK_DATE(this);
928 if (NUMBER_IS_NAN(t)) t = 0; 671 var t = UTC_DATE_VALUE(this);
929 var argc = %_ArgumentsLength();
930 year = ToNumber(year); 672 year = ToNumber(year);
931 month = argc < 2 ? MonthFromTime(t) : ToNumber(month); 673 var argc = %_ArgumentsLength();
932 date = argc < 3 ? DateFromTime(t) : ToNumber(date); 674 var time ;
675 if (NUMBER_IS_NAN(t)) {
676 month = argc < 2 ? 0 : ToNumber(month);
677 date = argc < 3 ? 1 : ToNumber(date);
678 time = 0;
679 } else {
680 month = argc < 2 ? UTC_MONTH(this) : ToNumber(month);
681 date = argc < 3 ? UTC_DAY(this) : ToNumber(date);
682 time = UTC_TIME_IN_DAY(this);
683 }
933 var day = MakeDay(year, month, date); 684 var day = MakeDay(year, month, date);
934 return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t)))); 685 return SET_UTC_DATE_VALUE(this, MakeDate(day, time));
935 } 686 }
936 687
937 688
938 // ECMA 262 - 15.9.5.42 689 // ECMA 262 - 15.9.5.42
939 function DateToUTCString() { 690 function DateToUTCString() {
940 var t = DATE_VALUE(this); 691 CHECK_DATE(this);
692 var t = UTC_DATE_VALUE(this);
941 if (NUMBER_IS_NAN(t)) return kInvalidDate; 693 if (NUMBER_IS_NAN(t)) return kInvalidDate;
942 // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT 694 // Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
943 return WeekDays[WeekDay(t)] + ', ' 695 return WeekDays[UTC_WEEKDAY(this)] + ', '
944 + TwoDigitString(DateFromTime(t)) + ' ' 696 + TwoDigitString(UTC_DAY(this)) + ' '
945 + Months[MonthFromTime(t)] + ' ' 697 + Months[UTC_MONTH(this)] + ' '
946 + YearFromTime(t) + ' ' 698 + UTC_YEAR(this) + ' '
947 + TimeString(t) + ' GMT'; 699 + TimeString(t) + ' GMT';
948 } 700 }
949 701
950 702
951 // ECMA 262 - B.2.4 703 // ECMA 262 - B.2.4
952 function DateGetYear() { 704 function DateGetYear() {
953 var t = DATE_VALUE(this); 705 CHECK_DATE(this);
954 if (NUMBER_IS_NAN(t)) return $NaN; 706 return LOCAL_YEAR(this) - 1900;
955 return YearFromTime(LocalTimeNoCheck(t)) - 1900;
956 } 707 }
957 708
958 709
959 // ECMA 262 - B.2.5 710 // ECMA 262 - B.2.5
960 function DateSetYear(year) { 711 function DateSetYear(year) {
961 var t = LocalTime(DATE_VALUE(this)); 712 CHECK_DATE(this);
962 if (NUMBER_IS_NAN(t)) t = 0;
963 year = ToNumber(year); 713 year = ToNumber(year);
964 if (NUMBER_IS_NAN(year)) return %_SetValueOf(this, $NaN); 714 if (NUMBER_IS_NAN(year)) return SET_UTC_DATE_VALUE(this, $NaN);
965 year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99) 715 year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
966 ? 1900 + TO_INTEGER(year) : year; 716 ? 1900 + TO_INTEGER(year) : year;
967 var day = MakeDay(year, MonthFromTime(t), DateFromTime(t)); 717 var t = LOCAL_DATE_VALUE(this);
968 return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t))))); 718 var month, date, time;
969 } 719 if (NUMBER_IS_NAN(t)) {
970 720 month = 0;
971 721 date = 1;
722 time = 0;
723 } else {
724 month = LOCAL_MONTH(this);
725 date = LOCAL_DAY(this);
726 time = TimeWithinDay(t);
727 }
728 var day = MakeDay(year, month, date);
729 return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
730 }
731
732
972 // ECMA 262 - B.2.6 733 // ECMA 262 - B.2.6
973 // 734 //
974 // Notice that this does not follow ECMA 262 completely. ECMA 262 735 // Notice that this does not follow ECMA 262 completely. ECMA 262
975 // says that toGMTString should be the same Function object as 736 // says that toGMTString should be the same Function object as
976 // toUTCString. JSC does not do this, so for compatibility we do not 737 // toUTCString. JSC does not do this, so for compatibility we do not
977 // do that either. Instead, we create a new function whose name 738 // do that either. Instead, we create a new function whose name
978 // property will return toGMTString. 739 // property will return toGMTString.
979 function DateToGMTString() { 740 function DateToGMTString() {
980 return %_CallFunction(this, DateToUTCString); 741 return %_CallFunction(this, DateToUTCString);
981 } 742 }
982 743
983 744
984 function PadInt(n, digits) { 745 function PadInt(n, digits) {
985 if (digits == 1) return n; 746 if (digits == 1) return n;
986 return n < MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n; 747 return n < MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n;
987 } 748 }
988 749
989 750
990 // ECMA 262 - 15.9.5.43 751 // ECMA 262 - 15.9.5.43
991 function DateToISOString() { 752 function DateToISOString() {
992 var t = DATE_VALUE(this); 753 CHECK_DATE(this);
754 var t = UTC_DATE_VALUE(this);
993 if (NUMBER_IS_NAN(t)) throw MakeRangeError("invalid_time_value", []); 755 if (NUMBER_IS_NAN(t)) throw MakeRangeError("invalid_time_value", []);
994 var year = this.getUTCFullYear(); 756 var year = this.getUTCFullYear();
995 var year_string; 757 var year_string;
996 if (year >= 0 && year <= 9999) { 758 if (year >= 0 && year <= 9999) {
997 year_string = PadInt(year, 4); 759 year_string = PadInt(year, 4);
998 } else { 760 } else {
999 if (year < 0) { 761 if (year < 0) {
1000 year_string = "-" + PadInt(-year, 6); 762 year_string = "-" + PadInt(-year, 6);
1001 } else { 763 } else {
1002 year_string = "+" + PadInt(year, 6); 764 year_string = "+" + PadInt(year, 6);
(...skipping 14 matching lines...) Expand all
1017 var o = ToObject(this); 779 var o = ToObject(this);
1018 var tv = DefaultNumber(o); 780 var tv = DefaultNumber(o);
1019 if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) { 781 if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
1020 return null; 782 return null;
1021 } 783 }
1022 return o.toISOString(); 784 return o.toISOString();
1023 } 785 }
1024 786
1025 787
1026 function ResetDateCache() { 788 function ResetDateCache() {
1027
1028 // Reset the local_time_offset:
1029 local_time_offset = %DateLocalTimeOffset();
1030
1031 // Reset the DST offset cache:
1032 var cache = DST_offset_cache;
1033 cache.offset = 0;
1034 cache.start = 0;
1035 cache.end = -1;
1036 cache.increment = 0;
1037 cache.initial_increment = 19 * msPerDay;
1038
1039 // Reset the timezone cache: 789 // Reset the timezone cache:
1040 timezone_cache_time = $NaN; 790 timezone_cache_time = $NaN;
1041 timezone_cache_timezone = undefined; 791 timezone_cache_timezone = undefined;
1042 792
1043 // Reset the ltcache:
1044 ltcache.key = null;
1045 ltcache.val = null;
1046
1047 // Reset the ymd_from_time_cache:
1048 ymd_from_time_cache = [$NaN, $NaN, $NaN];
1049 ymd_from_time_cached_time = $NaN;
1050
1051 // Reset the date cache: 793 // Reset the date cache:
1052 cache = Date_cache; 794 cache = Date_cache;
1053 cache.time = $NaN; 795 cache.time = $NaN;
1054 cache.year = $NaN;
1055 cache.string = null; 796 cache.string = null;
1056 } 797 }
1057 798
1058 799
1059 // ------------------------------------------------------------------- 800 // -------------------------------------------------------------------
1060 801
1061 function SetUpDate() { 802 function SetUpDate() {
1062 %CheckIsBootstrapping(); 803 %CheckIsBootstrapping();
1063 // Set up non-enumerable properties of the Date object itself. 804 // Set up non-enumerable properties of the Date object itself.
1064 InstallFunctions($Date, DONT_ENUM, $Array( 805 InstallFunctions($Date, DONT_ENUM, $Array(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 "toGMTString", DateToGMTString, 857 "toGMTString", DateToGMTString,
1117 "toUTCString", DateToUTCString, 858 "toUTCString", DateToUTCString,
1118 "getYear", DateGetYear, 859 "getYear", DateGetYear,
1119 "setYear", DateSetYear, 860 "setYear", DateSetYear,
1120 "toISOString", DateToISOString, 861 "toISOString", DateToISOString,
1121 "toJSON", DateToJSON 862 "toJSON", DateToJSON
1122 )); 863 ));
1123 } 864 }
1124 865
1125 SetUpDate(); 866 SetUpDate();
OLDNEW
« src/date.cc ('K') | « src/date.cc ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698