|
1 /// Copyright (c) 2012 Ecma International. All rights reserved. |
|
2 /// Ecma International makes this code available under the terms and conditions set |
|
3 /// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the |
|
4 /// "Use Terms"). Any redistribution of this code must retain the above |
|
5 /// copyright and this notice and otherwise comply with the Use Terms. |
|
6 |
|
7 //----------------------------------------------------------------------------- |
|
8 function compareArray(aExpected, aActual) { |
|
9 if (aActual.length != aExpected.length) { |
|
10 return false; |
|
11 } |
|
12 |
|
13 aExpected.sort(); |
|
14 aActual.sort(); |
|
15 |
|
16 var s; |
|
17 for (var i = 0; i < aExpected.length; i++) { |
|
18 if (aActual[i] !== aExpected[i]) { |
|
19 return false; |
|
20 } |
|
21 } |
|
22 return true; |
|
23 } |
|
24 |
|
25 //----------------------------------------------------------------------------- |
|
26 function arrayContains(arr, expected) { |
|
27 var found; |
|
28 for (var i = 0; i < expected.length; i++) { |
|
29 found = false; |
|
30 for (var j = 0; j < arr.length; j++) { |
|
31 if (expected[i] === arr[j]) { |
|
32 found = true; |
|
33 break; |
|
34 } |
|
35 } |
|
36 if (!found) { |
|
37 return false; |
|
38 } |
|
39 } |
|
40 return true; |
|
41 } |
|
42 |
|
43 //----------------------------------------------------------------------------- |
|
44 var supportsArrayIndexGettersOnArrays = undefined; |
|
45 function fnSupportsArrayIndexGettersOnArrays() { |
|
46 if (typeof supportsArrayIndexGettersOnArrays !== "undefined") { |
|
47 return supportsArrayIndexGettersOnArrays; |
|
48 } |
|
49 |
|
50 supportsArrayIndexGettersOnArrays = false; |
|
51 |
|
52 if (fnExists(Object.defineProperty)) { |
|
53 var arr = []; |
|
54 Object.defineProperty(arr, "0", { |
|
55 get: function() { |
|
56 supportsArrayIndexGettersOnArrays = true; |
|
57 return 0; |
|
58 } |
|
59 }); |
|
60 var res = arr[0]; |
|
61 } |
|
62 |
|
63 return supportsArrayIndexGettersOnArrays; |
|
64 } |
|
65 |
|
66 //----------------------------------------------------------------------------- |
|
67 var supportsArrayIndexGettersOnObjects = undefined; |
|
68 function fnSupportsArrayIndexGettersOnObjects() { |
|
69 if (typeof supportsArrayIndexGettersOnObjects !== "undefined") |
|
70 return supportsArrayIndexGettersOnObjects; |
|
71 |
|
72 supportsArrayIndexGettersOnObjects = false; |
|
73 |
|
74 if (fnExists(Object.defineProperty)) { |
|
75 var obj = {}; |
|
76 Object.defineProperty(obj, "0", { |
|
77 get: function() { |
|
78 supportsArrayIndexGettersOnObjects = true; |
|
79 return 0; |
|
80 } |
|
81 }); |
|
82 var res = obj[0]; |
|
83 } |
|
84 |
|
85 return supportsArrayIndexGettersOnObjects; |
|
86 } |
|
87 |
|
88 //----------------------------------------------------------------------------- |
|
89 function ConvertToFileUrl(pathStr) { |
|
90 return "file:" + pathStr.replace(/\\/g, "/"); |
|
91 } |
|
92 |
|
93 //----------------------------------------------------------------------------- |
|
94 function fnExists(/*arguments*/) { |
|
95 for (var i = 0; i < arguments.length; i++) { |
|
96 if (typeof (arguments[i]) !== "function") return false; |
|
97 } |
|
98 return true; |
|
99 } |
|
100 |
|
101 //----------------------------------------------------------------------------- |
|
102 var __globalObject = Function("return this;")(); |
|
103 function fnGlobalObject() { |
|
104 return __globalObject; |
|
105 } |
|
106 |
|
107 //----------------------------------------------------------------------------- |
|
108 function fnSupportsStrict() { |
|
109 "use strict"; |
|
110 try { |
|
111 eval('with ({}) {}'); |
|
112 return false; |
|
113 } catch (e) { |
|
114 return true; |
|
115 } |
|
116 } |
|
117 |
|
118 //----------------------------------------------------------------------------- |
|
119 //Verify all attributes specified data property of given object: |
|
120 //value, writable, enumerable, configurable |
|
121 //If all attribute values are expected, return true, otherwise, return false |
|
122 function dataPropertyAttributesAreCorrect(obj, |
|
123 name, |
|
124 value, |
|
125 writable, |
|
126 enumerable, |
|
127 configurable) { |
|
128 var attributesCorrect = true; |
|
129 |
|
130 if (obj[name] !== value) { |
|
131 if (typeof obj[name] === "number" && |
|
132 isNaN(obj[name]) && |
|
133 typeof value === "number" && |
|
134 isNaN(value)) { |
|
135 // keep empty |
|
136 } else { |
|
137 attributesCorrect = false; |
|
138 } |
|
139 } |
|
140 |
|
141 try { |
|
142 if (obj[name] === "oldValue") { |
|
143 obj[name] = "newValue"; |
|
144 } else { |
|
145 obj[name] = "OldValue"; |
|
146 } |
|
147 } catch (we) { |
|
148 } |
|
149 |
|
150 var overwrited = false; |
|
151 if (obj[name] !== value) { |
|
152 if (typeof obj[name] === "number" && |
|
153 isNaN(obj[name]) && |
|
154 typeof value === "number" && |
|
155 isNaN(value)) { |
|
156 // keep empty |
|
157 } else { |
|
158 overwrited = true; |
|
159 } |
|
160 } |
|
161 if (overwrited !== writable) { |
|
162 attributesCorrect = false; |
|
163 } |
|
164 |
|
165 var enumerated = false; |
|
166 for (var prop in obj) { |
|
167 if (obj.hasOwnProperty(prop) && prop === name) { |
|
168 enumerated = true; |
|
169 } |
|
170 } |
|
171 |
|
172 if (enumerated !== enumerable) { |
|
173 attributesCorrect = false; |
|
174 } |
|
175 |
|
176 |
|
177 var deleted = false; |
|
178 |
|
179 try { |
|
180 delete obj[name]; |
|
181 } catch (de) { |
|
182 } |
|
183 if (!obj.hasOwnProperty(name)) { |
|
184 deleted = true; |
|
185 } |
|
186 if (deleted !== configurable) { |
|
187 attributesCorrect = false; |
|
188 } |
|
189 |
|
190 return attributesCorrect; |
|
191 } |
|
192 |
|
193 //----------------------------------------------------------------------------- |
|
194 //Verify all attributes specified accessor property of given object: |
|
195 //get, set, enumerable, configurable |
|
196 //If all attribute values are expected, return true, otherwise, return false |
|
197 function accessorPropertyAttributesAreCorrect(obj, |
|
198 name, |
|
199 get, |
|
200 set, |
|
201 setVerifyHelpProp, |
|
202 enumerable, |
|
203 configurable) { |
|
204 var attributesCorrect = true; |
|
205 |
|
206 if (get !== undefined) { |
|
207 if (obj[name] !== get()) { |
|
208 if (typeof obj[name] === "number" && |
|
209 isNaN(obj[name]) && |
|
210 typeof get() === "number" && |
|
211 isNaN(get())) { |
|
212 // keep empty |
|
213 } else { |
|
214 attributesCorrect = false; |
|
215 } |
|
216 } |
|
217 } else { |
|
218 if (obj[name] !== undefined) { |
|
219 attributesCorrect = false; |
|
220 } |
|
221 } |
|
222 |
|
223 try { |
|
224 var desc = Object.getOwnPropertyDescriptor(obj, name); |
|
225 if (typeof desc.set === "undefined") { |
|
226 if (typeof set !== "undefined") { |
|
227 attributesCorrect = false; |
|
228 } |
|
229 } else { |
|
230 obj[name] = "toBeSetValue"; |
|
231 if (obj[setVerifyHelpProp] !== "toBeSetValue") { |
|
232 attributesCorrect = false; |
|
233 } |
|
234 } |
|
235 } catch (se) { |
|
236 throw se; |
|
237 } |
|
238 |
|
239 |
|
240 var enumerated = false; |
|
241 for (var prop in obj) { |
|
242 if (obj.hasOwnProperty(prop) && prop === name) { |
|
243 enumerated = true; |
|
244 } |
|
245 } |
|
246 |
|
247 if (enumerated !== enumerable) { |
|
248 attributesCorrect = false; |
|
249 } |
|
250 |
|
251 |
|
252 var deleted = false; |
|
253 try { |
|
254 delete obj[name]; |
|
255 } catch (de) { |
|
256 throw de; |
|
257 } |
|
258 if (!obj.hasOwnProperty(name)) { |
|
259 deleted = true; |
|
260 } |
|
261 if (deleted !== configurable) { |
|
262 attributesCorrect = false; |
|
263 } |
|
264 |
|
265 return attributesCorrect; |
|
266 } |
|
267 |
|
268 //----------------------------------------------------------------------------- |
|
269 var NotEarlyErrorString = "NotEarlyError"; |
|
270 var EarlyErrorRePat = "^((?!" + NotEarlyErrorString + ").)*$"; |
|
271 var NotEarlyError = new Error(NotEarlyErrorString); |
|
272 |
|
273 //----------------------------------------------------------------------------- |
|
274 // Copyright 2009 the Sputnik authors. All rights reserved. |
|
275 // This code is governed by the BSD license found in the LICENSE file. |
|
276 |
|
277 function Test262Error(message) { |
|
278 if (message) this.message = message; |
|
279 } |
|
280 |
|
281 Test262Error.prototype.toString = function () { |
|
282 return "Test262 Error: " + this.message; |
|
283 }; |
|
284 |
|
285 function testFailed(message) { |
|
286 throw new Test262Error(message); |
|
287 } |
|
288 |
|
289 |
|
290 function testPrint(message) { |
|
291 |
|
292 } |
|
293 |
|
294 |
|
295 //adaptors for Test262 framework |
|
296 function $PRINT(message) { |
|
297 |
|
298 } |
|
299 |
|
300 function $INCLUDE(message) { } |
|
301 function $ERROR(message) { |
|
302 testFailed(message); |
|
303 } |
|
304 |
|
305 function $FAIL(message) { |
|
306 testFailed(message); |
|
307 } |
|
308 |
|
309 |
|
310 |
|
311 //Sputnik library definitions |
|
312 //Ultimately these should be namespaced some how and only made |
|
313 //available to tests that explicitly include them. |
|
314 //For now, we just define the globally |
|
315 |
|
316 //math_precision.js |
|
317 // Copyright 2009 the Sputnik authors. All rights reserved. |
|
318 // This code is governed by the BSD license found in the LICENSE file. |
|
319 |
|
320 function getPrecision(num) { |
|
321 //TODO: Create a table of prec's, |
|
322 // because using Math for testing Math isn't that correct. |
|
323 |
|
324 var log2num = Math.log(Math.abs(num)) / Math.LN2; |
|
325 var pernum = Math.ceil(log2num); |
|
326 return (2 * Math.pow(2, -52 + pernum)); |
|
327 //return(0); |
|
328 } |
|
329 |
|
330 |
|
331 //math_isequal.js |
|
332 // Copyright 2009 the Sputnik authors. All rights reserved. |
|
333 // This code is governed by the BSD license found in the LICENSE file. |
|
334 |
|
335 var prec; |
|
336 function isEqual(num1, num2) { |
|
337 if ((num1 === Infinity) && (num2 === Infinity)) { |
|
338 return (true); |
|
339 } |
|
340 if ((num1 === -Infinity) && (num2 === -Infinity)) { |
|
341 return (true); |
|
342 } |
|
343 prec = getPrecision(Math.min(Math.abs(num1), Math.abs(num2))); |
|
344 return (Math.abs(num1 - num2) <= prec); |
|
345 //return(num1 === num2); |
|
346 } |
|
347 |
|
348 //numeric_conversion.js |
|
349 // Copyright 2009 the Sputnik authors. All rights reserved. |
|
350 // This code is governed by the BSD license found in the LICENSE file. |
|
351 |
|
352 function ToInteger(p) { |
|
353 var x = Number(p); |
|
354 |
|
355 if (isNaN(x)) { |
|
356 return +0; |
|
357 } |
|
358 |
|
359 if ((x === +0) |
|
360 || (x === -0) |
|
361 || (x === Number.POSITIVE_INFINITY) |
|
362 || (x === Number.NEGATIVE_INFINITY)) { |
|
363 return x; |
|
364 } |
|
365 |
|
366 var sign = (x < 0) ? -1 : 1; |
|
367 |
|
368 return (sign * Math.floor(Math.abs(x))); |
|
369 } |
|
370 |
|
371 //Date_constants.js |
|
372 // Copyright 2009 the Sputnik authors. All rights reserved. |
|
373 // This code is governed by the BSD license found in the LICENSE file. |
|
374 |
|
375 var HoursPerDay = 24; |
|
376 var MinutesPerHour = 60; |
|
377 var SecondsPerMinute = 60; |
|
378 |
|
379 var msPerDay = 86400000; |
|
380 var msPerSecond = 1000; |
|
381 var msPerMinute = 60000; |
|
382 var msPerHour = 3600000; |
|
383 |
|
384 var date_1899_end = -2208988800001; |
|
385 var date_1900_start = -2208988800000; |
|
386 var date_1969_end = -1; |
|
387 var date_1970_start = 0; |
|
388 var date_1999_end = 946684799999; |
|
389 var date_2000_start = 946684800000; |
|
390 var date_2099_end = 4102444799999; |
|
391 var date_2100_start = 4102444800000; |
|
392 |
|
393 // Copyright 2009 the Sputnik authors. All rights reserved. |
|
394 // This code is governed by the BSD license found in the LICENSE file. |
|
395 |
|
396 //the following values are normally generated by the sputnik.py driver |
|
397 var $LocalTZ, |
|
398 $DST_start_month, |
|
399 $DST_start_sunday, |
|
400 $DST_start_hour, |
|
401 $DST_start_minutes, |
|
402 $DST_end_month, |
|
403 $DST_end_sunday, |
|
404 $DST_end_hour, |
|
405 $DST_end_minutes; |
|
406 |
|
407 (function () { |
|
408 /** |
|
409 * Finds the first date, starting from |start|, where |predicate| |
|
410 * holds. |
|
411 */ |
|
412 var findNearestDateBefore = function(start, predicate) { |
|
413 var current = start; |
|
414 var month = 1000 * 60 * 60 * 24 * 30; |
|
415 for (var step = month; step > 0; step = Math.floor(step / 3)) { |
|
416 if (!predicate(current)) { |
|
417 while (!predicate(current)) |
|
418 current = new Date(current.getTime() + step); |
|
419 current = new Date(current.getTime() - step); |
|
420 } |
|
421 } |
|
422 while (!predicate(current)) { |
|
423 current = new Date(current.getTime() + 1); |
|
424 } |
|
425 return current; |
|
426 }; |
|
427 |
|
428 var juneDate = new Date(2000, 5, 20, 0, 0, 0, 0); |
|
429 var decemberDate = new Date(2000, 11, 20, 0, 0, 0, 0); |
|
430 var juneOffset = juneDate.getTimezoneOffset(); |
|
431 var decemberOffset = decemberDate.getTimezoneOffset(); |
|
432 var isSouthernHemisphere = (juneOffset > decemberOffset); |
|
433 var winterTime = isSouthernHemisphere ? juneDate : decemberDate; |
|
434 var summerTime = isSouthernHemisphere ? decemberDate : juneDate; |
|
435 |
|
436 var dstStart = findNearestDateBefore(winterTime, function (date) { |
|
437 return date.getTimezoneOffset() == summerTime.getTimezoneOffset(); |
|
438 }); |
|
439 $DST_start_month = dstStart.getMonth(); |
|
440 $DST_start_sunday = dstStart.getDate() > 15 ? '"last"' : '"first"'; |
|
441 $DST_start_hour = dstStart.getHours(); |
|
442 $DST_start_minutes = dstStart.getMinutes(); |
|
443 |
|
444 var dstEnd = findNearestDateBefore(summerTime, function (date) { |
|
445 return date.getTimezoneOffset() == winterTime.getTimezoneOffset(); |
|
446 }); |
|
447 $DST_end_month = dstEnd.getMonth(); |
|
448 $DST_end_sunday = dstEnd.getDate() > 15 ? '"last"' : '"first"'; |
|
449 $DST_end_hour = dstEnd.getHours(); |
|
450 $DST_end_minutes = dstEnd.getMinutes(); |
|
451 |
|
452 return; |
|
453 })(); |
|
454 |
|
455 |
|
456 //Date.library.js |
|
457 // Copyright 2009 the Sputnik authors. All rights reserved. |
|
458 // This code is governed by the BSD license found in the LICENSE file. |
|
459 |
|
460 //15.9.1.2 Day Number and Time within Day |
|
461 function Day(t) { |
|
462 return Math.floor(t/msPerDay); |
|
463 } |
|
464 |
|
465 function TimeWithinDay(t) { |
|
466 return t%msPerDay; |
|
467 } |
|
468 |
|
469 //15.9.1.3 Year Number |
|
470 function DaysInYear(y){ |
|
471 if(y%4 != 0) return 365; |
|
472 if(y%4 == 0 && y%100 != 0) return 366; |
|
473 if(y%100 == 0 && y%400 != 0) return 365; |
|
474 if(y%400 == 0) return 366; |
|
475 } |
|
476 |
|
477 function DayFromYear(y) { |
|
478 return (365*(y-1970) |
|
479 + Math.floor((y-1969)/4) |
|
480 - Math.floor((y-1901)/100) |
|
481 + Math.floor((y-1601)/400)); |
|
482 } |
|
483 |
|
484 function TimeFromYear(y){ |
|
485 return msPerDay*DayFromYear(y); |
|
486 } |
|
487 |
|
488 function YearFromTime(t) { |
|
489 t = Number(t); |
|
490 var sign = ( t < 0 ) ? -1 : 1; |
|
491 var year = ( sign < 0 ) ? 1969 : 1970; |
|
492 |
|
493 for(var time = 0;;year += sign){ |
|
494 time = TimeFromYear(year); |
|
495 |
|
496 if(sign > 0 && time > t){ |
|
497 year -= sign; |
|
498 break; |
|
499 } |
|
500 else if(sign < 0 && time <= t){ |
|
501 break; |
|
502 } |
|
503 }; |
|
504 return year; |
|
505 } |
|
506 |
|
507 function InLeapYear(t){ |
|
508 if(DaysInYear(YearFromTime(t)) == 365) |
|
509 return 0; |
|
510 |
|
511 if(DaysInYear(YearFromTime(t)) == 366) |
|
512 return 1; |
|
513 } |
|
514 |
|
515 function DayWithinYear(t) { |
|
516 return Day(t)-DayFromYear(YearFromTime(t)); |
|
517 } |
|
518 |
|
519 //15.9.1.4 Month Number |
|
520 function MonthFromTime(t){ |
|
521 var day = DayWithinYear(t); |
|
522 var leap = InLeapYear(t); |
|
523 |
|
524 if((0 <= day) && (day < 31)) return 0; |
|
525 if((31 <= day) && (day < (59+leap))) return 1; |
|
526 if(((59+leap) <= day) && (day < (90+leap))) return 2; |
|
527 if(((90+leap) <= day) && (day < (120+leap))) return 3; |
|
528 if(((120+leap) <= day) && (day < (151+leap))) return 4; |
|
529 if(((151+leap) <= day) && (day < (181+leap))) return 5; |
|
530 if(((181+leap) <= day) && (day < (212+leap))) return 6; |
|
531 if(((212+leap) <= day) && (day < (243+leap))) return 7; |
|
532 if(((243+leap) <= day) && (day < (273+leap))) return 8; |
|
533 if(((273+leap) <= day) && (day < (304+leap))) return 9; |
|
534 if(((304+leap) <= day) && (day < (334+leap))) return 10; |
|
535 if(((334+leap) <= day) && (day < (365+leap))) return 11; |
|
536 } |
|
537 |
|
538 //15.9.1.5 Date Number |
|
539 function DateFromTime(t) { |
|
540 var day = DayWithinYear(t); |
|
541 var month = MonthFromTime(t); |
|
542 var leap = InLeapYear(t); |
|
543 |
|
544 if(month == 0) return day+1; |
|
545 if(month == 1) return day-30; |
|
546 if(month == 2) return day-58-leap; |
|
547 if(month == 3) return day-89-leap; |
|
548 if(month == 4) return day-119-leap; |
|
549 if(month == 5) return day-150-leap; |
|
550 if(month == 6) return day-180-leap; |
|
551 if(month == 7) return day-211-leap; |
|
552 if(month == 8) return day-242-leap; |
|
553 if(month == 9) return day-272-leap; |
|
554 if(month == 10) return day-303-leap; |
|
555 if(month == 11) return day-333-leap; |
|
556 } |
|
557 |
|
558 //15.9.1.6 Week Day |
|
559 function WeekDay(t) { |
|
560 var weekday = (Day(t)+4)%7; |
|
561 return (weekday < 0 ? 7+weekday : weekday); |
|
562 } |
|
563 |
|
564 //15.9.1.9 Daylight Saving Time Adjustment |
|
565 $LocalTZ = (new Date()).getTimezoneOffset() / -60; |
|
566 if (DaylightSavingTA((new Date()).valueOf()) !== 0) { |
|
567 $LocalTZ -= 1; |
|
568 } |
|
569 var LocalTZA = $LocalTZ*msPerHour; |
|
570 |
|
571 function DaysInMonth(m, leap) { |
|
572 m = m%12; |
|
573 |
|
574 //April, June, Sept, Nov |
|
575 if(m == 3 || m == 5 || m == 8 || m == 10 ) { |
|
576 return 30; |
|
577 } |
|
578 |
|
579 //Jan, March, May, July, Aug, Oct, Dec |
|
580 if(m == 0 || m == 2 || m == 4 || m == 6 || m == 7 || m == 9 || m == 11){ |
|
581 return 31; |
|
582 } |
|
583 |
|
584 //Feb |
|
585 return 28+leap; |
|
586 } |
|
587 |
|
588 function GetSundayInMonth(t, m, count){ |
|
589 var year = YearFromTime(t); |
|
590 var tempDate; |
|
591 |
|
592 if (count==='"first"') { |
|
593 for (var d=1; d <= DaysInMonth(m, InLeapYear(t)); d++) { |
|
594 tempDate = new Date(year, m, d); |
|
595 if (tempDate.getDay()===0) { |
|
596 return tempDate.valueOf(); |
|
597 } |
|
598 } |
|
599 } else if(count==='"last"') { |
|
600 for (var d=DaysInMonth(m, InLeapYear(t)); d>0; d--) { |
|
601 tempDate = new Date(year, m, d); |
|
602 if (tempDate.getDay()===0) { |
|
603 return tempDate.valueOf(); |
|
604 } |
|
605 } |
|
606 } |
|
607 throw new Error("Unsupported 'count' arg:" + count); |
|
608 } |
|
609 /* |
|
610 function GetSundayInMonth(t, m, count){ |
|
611 var year = YearFromTime(t); |
|
612 var leap = InLeapYear(t); |
|
613 var day = 0; |
|
614 |
|
615 if(m >= 1) day += DaysInMonth(0, leap); |
|
616 if(m >= 2) day += DaysInMonth(1, leap); |
|
617 if(m >= 3) day += DaysInMonth(2, leap); |
|
618 if(m >= 4) day += DaysInMonth(3, leap); |
|
619 if(m >= 5) day += DaysInMonth(4, leap); |
|
620 if(m >= 6) day += DaysInMonth(5, leap); |
|
621 if(m >= 7) day += DaysInMonth(6, leap); |
|
622 if(m >= 8) day += DaysInMonth(7, leap); |
|
623 if(m >= 9) day += DaysInMonth(8, leap); |
|
624 if(m >= 10) day += DaysInMonth(9, leap); |
|
625 if(m >= 11) day += DaysInMonth(10, leap); |
|
626 |
|
627 var month_start = TimeFromYear(year)+day*msPerDay; |
|
628 var sunday = 0; |
|
629 |
|
630 if(count === "last"){ |
|
631 for(var last_sunday = month_start+DaysInMonth(m, leap)*msPerDay; |
|
632 WeekDay(last_sunday)>0; |
|
633 last_sunday -= msPerDay |
|
634 ){}; |
|
635 sunday = last_sunday; |
|
636 } |
|
637 else { |
|
638 for(var first_sunday = month_start; |
|
639 WeekDay(first_sunday)>0; |
|
640 first_sunday += msPerDay |
|
641 ){}; |
|
642 sunday = first_sunday+7*msPerDay*(count-1); |
|
643 } |
|
644 |
|
645 return sunday; |
|
646 }*/ |
|
647 |
|
648 function DaylightSavingTA(t) { |
|
649 // t = t-LocalTZA; |
|
650 |
|
651 var DST_start = GetSundayInMonth(t, $DST_start_month, $DST_start_sunday) + |
|
652 $DST_start_hour*msPerHour + |
|
653 $DST_start_minutes*msPerMinute; |
|
654 |
|
655 var k = new Date(DST_start); |
|
656 |
|
657 var DST_end = GetSundayInMonth(t, $DST_end_month, $DST_end_sunday) + |
|
658 $DST_end_hour*msPerHour + |
|
659 $DST_end_minutes*msPerMinute; |
|
660 |
|
661 if ( t >= DST_start && t < DST_end ) { |
|
662 return msPerHour; |
|
663 } else { |
|
664 return 0; |
|
665 } |
|
666 } |
|
667 |
|
668 //15.9.1.9 Local Time |
|
669 function LocalTime(t){ |
|
670 return t+LocalTZA+DaylightSavingTA(t); |
|
671 } |
|
672 |
|
673 function UTC(t) { |
|
674 return t-LocalTZA-DaylightSavingTA(t-LocalTZA); |
|
675 } |
|
676 |
|
677 //15.9.1.10 Hours, Minutes, Second, and Milliseconds |
|
678 function HourFromTime(t){ |
|
679 return Math.floor(t/msPerHour)%HoursPerDay; |
|
680 } |
|
681 |
|
682 function MinFromTime(t){ |
|
683 return Math.floor(t/msPerMinute)%MinutesPerHour; |
|
684 } |
|
685 |
|
686 function SecFromTime(t){ |
|
687 return Math.floor(t/msPerSecond)%SecondsPerMinute; |
|
688 } |
|
689 |
|
690 function msFromTime(t){ |
|
691 return t%msPerSecond; |
|
692 } |
|
693 |
|
694 //15.9.1.11 MakeTime (hour, min, sec, ms) |
|
695 function MakeTime(hour, min, sec, ms){ |
|
696 if ( !isFinite(hour) || !isFinite(min) || !isFinite(sec) || !isFinite(ms)) { |
|
697 return Number.NaN; |
|
698 } |
|
699 |
|
700 hour = ToInteger(hour); |
|
701 min = ToInteger(min); |
|
702 sec = ToInteger(sec); |
|
703 ms = ToInteger(ms); |
|
704 |
|
705 return ((hour*msPerHour) + (min*msPerMinute) + (sec*msPerSecond) + ms); |
|
706 } |
|
707 |
|
708 //15.9.1.12 MakeDay (year, month, date) |
|
709 function MakeDay(year, month, date) { |
|
710 if ( !isFinite(year) || !isFinite(month) || !isFinite(date)) { |
|
711 return Number.NaN; |
|
712 } |
|
713 |
|
714 year = ToInteger(year); |
|
715 month = ToInteger(month); |
|
716 date = ToInteger(date ); |
|
717 |
|
718 var result5 = year + Math.floor(month/12); |
|
719 var result6 = month%12; |
|
720 |
|
721 var sign = ( year < 1970 ) ? -1 : 1; |
|
722 var t = ( year < 1970 ) ? 1 : 0; |
|
723 var y = ( year < 1970 ) ? 1969 : 1970; |
|
724 |
|
725 if( sign == -1 ){ |
|
726 for ( y = 1969; y >= year; y += sign ) { |
|
727 t += sign * DaysInYear(y)*msPerDay; |
|
728 } |
|
729 } else { |
|
730 for ( y = 1970 ; y < year; y += sign ) { |
|
731 t += sign * DaysInYear(y)*msPerDay; |
|
732 } |
|
733 } |
|
734 |
|
735 var leap = 0; |
|
736 for ( var m = 0; m < month; m++ ) { |
|
737 //if year is changed, than we need to recalculate leep |
|
738 leap = InLeapYear(t); |
|
739 t += DaysInMonth(m, leap)*msPerDay; |
|
740 } |
|
741 |
|
742 if ( YearFromTime(t) != result5 ) { |
|
743 return Number.NaN; |
|
744 } |
|
745 if ( MonthFromTime(t) != result6 ) { |
|
746 return Number.NaN; |
|
747 } |
|
748 if ( DateFromTime(t) != 1 ) { |
|
749 return Number.NaN; |
|
750 } |
|
751 |
|
752 return Day(t)+date-1; |
|
753 } |
|
754 |
|
755 //15.9.1.13 MakeDate (day, time) |
|
756 function MakeDate( day, time ) { |
|
757 if(!isFinite(day) || !isFinite(time)) { |
|
758 return Number.NaN; |
|
759 } |
|
760 |
|
761 return day*msPerDay+time; |
|
762 } |
|
763 |
|
764 //15.9.1.14 TimeClip (time) |
|
765 function TimeClip(time) { |
|
766 if(!isFinite(time) || Math.abs(time) > 8.64e15){ |
|
767 return Number.NaN; |
|
768 } |
|
769 |
|
770 return ToInteger(time); |
|
771 } |
|
772 |
|
773 //Test Functions |
|
774 //ConstructDate is considered deprecated, and should not be used directly from |
|
775 //test262 tests as it's incredibly sensitive to DST start/end dates that |
|
776 //vary with geographic location. |
|
777 function ConstructDate(year, month, date, hours, minutes, seconds, ms){ |
|
778 /* |
|
779 * 1. Call ToNumber(year) |
|
780 * 2. Call ToNumber(month) |
|
781 * 3. If date is supplied use ToNumber(date); else use 1 |
|
782 * 4. If hours is supplied use ToNumber(hours); else use 0 |
|
783 * 5. If minutes is supplied use ToNumber(minutes); else use 0 |
|
784 * 6. If seconds is supplied use ToNumber(seconds); else use 0 |
|
785 * 7. If ms is supplied use ToNumber(ms); else use 0 |
|
786 * 8. If Result(1) is not NaN and 0 <= ToInteger(Result(1)) <= 99, Result(8) is |
|
787 * 1900+ToInteger(Result(1)); otherwise, Result(8) is Result(1) |
|
788 * 9. Compute MakeDay(Result(8), Result(2), Result(3)) |
|
789 * 10. Compute MakeTime(Result(4), Result(5), Result(6), Result(7)) |
|
790 * 11. Compute MakeDate(Result(9), Result(10)) |
|
791 * 12. Set the [[Value]] property of the newly constructed object to TimeClip(UTC(Result(11))) |
|
792 */ |
|
793 var r1 = Number(year); |
|
794 var r2 = Number(month); |
|
795 var r3 = ((date && arguments.length > 2) ? Number(date) : 1); |
|
796 var r4 = ((hours && arguments.length > 3) ? Number(hours) : 0); |
|
797 var r5 = ((minutes && arguments.length > 4) ? Number(minutes) : 0); |
|
798 var r6 = ((seconds && arguments.length > 5) ? Number(seconds) : 0); |
|
799 var r7 = ((ms && arguments.length > 6) ? Number(ms) : 0); |
|
800 |
|
801 var r8 = r1; |
|
802 |
|
803 if(!isNaN(r1) && (0 <= ToInteger(r1)) && (ToInteger(r1) <= 99)) |
|
804 r8 = 1900+r1; |
|
805 |
|
806 var r9 = MakeDay(r8, r2, r3); |
|
807 var r10 = MakeTime(r4, r5, r6, r7); |
|
808 var r11 = MakeDate(r9, r10); |
|
809 |
|
810 var retVal = TimeClip(UTC(r11)); |
|
811 return retVal; |
|
812 } |
|
813 |
|
814 |
|
815 |
|
816 /**** Python code for initialize the above constants |
|
817 // We may want to replicate the following in JavaScript. |
|
818 // However, using JS date operations to generate parameters that are then used to |
|
819 // test those some date operations seems unsound. However, it isn't clear if there |
|
820 //is a good interoperable alternative. |
|
821 |
|
822 # Copyright 2009 the Sputnik authors. All rights reserved. |
|
823 # This code is governed by the BSD license found in the LICENSE file. |
|
824 |
|
825 def GetDaylightSavingsTimes(): |
|
826 # Is the given floating-point time in DST? |
|
827 def IsDst(t): |
|
828 return time.localtime(t)[-1] |
|
829 # Binary search to find an interval between the two times no greater than |
|
830 # delta where DST switches, returning the midpoint. |
|
831 def FindBetween(start, end, delta): |
|
832 while end - start > delta: |
|
833 middle = (end + start) / 2 |
|
834 if IsDst(middle) == IsDst(start): |
|
835 start = middle |
|
836 else: |
|
837 end = middle |
|
838 return (start + end) / 2 |
|
839 now = time.time() |
|
840 one_month = (30 * 24 * 60 * 60) |
|
841 # First find a date with different daylight savings. To avoid corner cases |
|
842 # we try four months before and after today. |
|
843 after = now + 4 * one_month |
|
844 before = now - 4 * one_month |
|
845 if IsDst(now) == IsDst(before) and IsDst(now) == IsDst(after): |
|
846 logger.warning("Was unable to determine DST info.") |
|
847 return None |
|
848 # Determine when the change occurs between now and the date we just found |
|
849 # in a different DST. |
|
850 if IsDst(now) != IsDst(before): |
|
851 first = FindBetween(before, now, 1) |
|
852 else: |
|
853 first = FindBetween(now, after, 1) |
|
854 # Determine when the change occurs between three and nine months from the |
|
855 # first. |
|
856 second = FindBetween(first + 3 * one_month, first + 9 * one_month, 1) |
|
857 # Find out which switch is into and which if out of DST |
|
858 if IsDst(first - 1) and not IsDst(first + 1): |
|
859 start = second |
|
860 end = first |
|
861 else: |
|
862 start = first |
|
863 end = second |
|
864 return (start, end) |
|
865 |
|
866 |
|
867 def GetDaylightSavingsAttribs(): |
|
868 times = GetDaylightSavingsTimes() |
|
869 if not times: |
|
870 return None |
|
871 (start, end) = times |
|
872 def DstMonth(t): |
|
873 return time.localtime(t)[1] - 1 |
|
874 def DstHour(t): |
|
875 return time.localtime(t - 1)[3] + 1 |
|
876 def DstSunday(t): |
|
877 if time.localtime(t)[2] > 15: |
|
878 return "'last'" |
|
879 else: |
|
880 return "'first'" |
|
881 def DstMinutes(t): |
|
882 return (time.localtime(t - 1)[4] + 1) % 60 |
|
883 attribs = { } |
|
884 attribs['start_month'] = DstMonth(start) |
|
885 attribs['end_month'] = DstMonth(end) |
|
886 attribs['start_sunday'] = DstSunday(start) |
|
887 attribs['end_sunday'] = DstSunday(end) |
|
888 attribs['start_hour'] = DstHour(start) |
|
889 attribs['end_hour'] = DstHour(end) |
|
890 attribs['start_minutes'] = DstMinutes(start) |
|
891 attribs['end_minutes'] = DstMinutes(end) |
|
892 return attribs |
|
893 |
|
894 *********/ |
|
895 |
|
896 //--Test case registration----------------------------------------------------- |
|
897 function runTestCase(testcase) { |
|
898 if (testcase() !== true) { |
|
899 $ERROR("Test case returned non-true value!"); |
|
900 } |
|
901 } |