test_valueasdate_attribute.html (27407B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=769370 5 --> 6 <head> 7 <title>Test for input.valueAsDate</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 10 </head> 11 <body> 12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=769370">Mozilla Bug 769370</a> 13 <iframe name="testFrame" style="display: none"></iframe> 14 <p id="display"></p> 15 <pre id="test"> 16 <script type="application/javascript"> 17 18 /** Test for Bug 769370*/ 19 20 /** 21 * This test is checking .valueAsDate. 22 */ 23 24 var element = document.createElement("input"); 25 26 var validTypes = 27 [ 28 ["text", false], 29 ["password", false], 30 ["search", false], 31 ["tel", false], 32 ["email", false], 33 ["url", false], 34 ["hidden", false], 35 ["checkbox", false], 36 ["radio", false], 37 ["file", false], 38 ["submit", false], 39 ["image", false], 40 ["reset", false], 41 ["button", false], 42 ["number", false], 43 ["range", false], 44 ["date", true], 45 ["time", true], 46 ["color", false], 47 ["month", true], 48 ["week", true], 49 ["datetime-local", true], 50 ]; 51 52 function checkAvailability() 53 { 54 for (let data of validTypes) { 55 var exceptionCatched = false; 56 element.type = data[0]; 57 try { 58 element.valueAsDate; 59 } catch (e) { 60 exceptionCatched = true; 61 } 62 is(exceptionCatched, false, 63 "valueAsDate shouldn't throw exception on getting"); 64 65 exceptionCatched = false; 66 try { 67 element.valueAsDate = new Date(); 68 } catch (e) { 69 exceptionCatched = true; 70 } 71 is(exceptionCatched, !data[1], "valueAsDate for " + data[0] + 72 " availability is not correct"); 73 } 74 } 75 76 function checkGarbageValues() 77 { 78 for (let type of validTypes) { 79 if (!type[1]) { 80 continue; 81 } 82 type = type[0]; 83 84 var inputElement = document.createElement('input'); 85 inputElement.type = type; 86 87 inputElement.value = "test"; 88 inputElement.valueAsDate = null; 89 is(inputElement.value, "", "valueAsDate should set the value to the empty string"); 90 91 inputElement.value = "test"; 92 inputElement.valueAsDate = undefined; 93 is(inputElement.value, "", "valueAsDate should set the value to the empty string"); 94 95 inputElement.value = "test"; 96 inputElement.valueAsDate = new Date(NaN); 97 is(inputElement.value, "", "valueAsDate should set the value to the empty string"); 98 99 var illegalValues = [ 100 "foobar", 42, {}, function() { return 42; }, function() { return Date(); } 101 ]; 102 103 for (let value of illegalValues) { 104 try { 105 var caught = false; 106 inputElement.valueAsDate = value; 107 } catch(e) { 108 is(e.name, "TypeError", "Exception should be 'TypeError'."); 109 caught = true; 110 } 111 ok(caught, "Assigning " + value + " to .valueAsDate should throw"); 112 } 113 } 114 } 115 116 function checkDateGet() 117 { 118 var validData = 119 [ 120 [ "2012-07-12", 1342051200000 ], 121 [ "1970-01-01", 0 ], 122 [ "1970-01-02", 86400000 ], 123 [ "1969-12-31", -86400000 ], 124 [ "0311-01-31", -52350451200000 ], 125 [ "275760-09-13", 8640000000000000 ], 126 [ "0001-01-01", -62135596800000 ], 127 [ "2012-02-29", 1330473600000 ], 128 [ "2011-02-28", 1298851200000 ], 129 ]; 130 131 var invalidData = 132 [ 133 [ "invaliddate" ], 134 [ "-001-12-31" ], 135 [ "901-12-31" ], 136 [ "1901-13-31" ], 137 [ "1901-12-32" ], 138 [ "1901-00-12" ], 139 [ "1901-01-00" ], 140 [ "1900-02-29" ], 141 [ "0000-01-01" ], 142 [ "" ], 143 // This date is valid for the input element, but is out of 144 // the date object range. In this case, on getting valueAsDate, 145 // a Date object will be created, but it will have a NaN internal value, 146 // and will return the string "Invalid Date". 147 [ "275760-09-14", true ], 148 ]; 149 150 element.type = "date"; 151 for (let data of validData) { 152 element.value = data[0]; 153 is(element.valueAsDate.valueOf(), data[1], 154 "valueAsDate should return the " + 155 "valid date object representing this date"); 156 } 157 158 for (let data of invalidData) { 159 element.value = data[0]; 160 if (data[1]) { 161 is(String(element.valueAsDate), "Invalid Date", 162 "valueAsDate should return an invalid Date object " + 163 "when the element value is not a valid date"); 164 } else { 165 is(element.valueAsDate, null, 166 "valueAsDate should return null " + 167 "when the element value is not a valid date"); 168 } 169 } 170 } 171 172 function checkDateSet() 173 { 174 var testData = 175 [ 176 [ 1342051200000, "2012-07-12" ], 177 [ 0, "1970-01-01" ], 178 // Maximum valid date (limited by the ecma date object range). 179 [ 8640000000000000, "275760-09-13" ], 180 // Minimum valid date (limited by the input element minimum valid value). 181 [ -62135596800000 , "0001-01-01" ], 182 [ 1330473600000, "2012-02-29" ], 183 [ 1298851200000, "2011-02-28" ], 184 // "Values must be truncated to valid dates" 185 [ 42.1234, "1970-01-01" ], 186 [ 123.123456789123, "1970-01-01" ], 187 [ 1e-1, "1970-01-01" ], 188 [ 1298851200010, "2011-02-28" ], 189 [ -1, "1969-12-31" ], 190 [ -86400000, "1969-12-31" ], 191 [ 86400000, "1970-01-02" ], 192 // Negative years, this is out of range for the input element, 193 // the corresponding date string is the empty string 194 [ -62135596800001, "" ], 195 // Invalid dates. 196 ]; 197 198 element.type = "date"; 199 for (let data of testData) { 200 element.valueAsDate = new Date(data[0]); 201 is(element.value, data[1], "valueAsDate should set the value to " 202 + data[1]); 203 element.valueAsDate = new testFrame.Date(data[0]); 204 is(element.value, data[1], "valueAsDate with other-global date should " + 205 "set the value to " + data[1]); 206 } 207 } 208 209 function checkTimeGet() 210 { 211 var tests = [ 212 // Some invalid values to begin. 213 { value: "", result: null }, 214 { value: "foobar", result: null }, 215 { value: "00:", result: null }, 216 { value: "24:00", result: null }, 217 { value: "00:99", result: null }, 218 { value: "00:00:", result: null }, 219 { value: "00:00:99", result: null }, 220 { value: "00:00:00:", result: null }, 221 { value: "00:00:00.", result: null }, 222 { value: "00:00:00.0000", result: null }, 223 // Some simple valid values. 224 { value: "00:00", result: { time: 0, hours: 0, minutes: 0, seconds: 0, ms: 0 } }, 225 { value: "00:01", result: { time: 60000, hours: 0, minutes: 1, seconds: 0, ms: 0 } }, 226 { value: "01:00", result: { time: 3600000, hours: 1, minutes: 0, seconds: 0, ms: 0 } }, 227 { value: "01:01", result: { time: 3660000, hours: 1, minutes: 1, seconds: 0, ms: 0 } }, 228 { value: "13:37", result: { time: 49020000, hours: 13, minutes: 37, seconds: 0, ms: 0 } }, 229 // Valid values including seconds. 230 { value: "00:00:01", result: { time: 1000, hours: 0, minutes: 0, seconds: 1, ms: 0 } }, 231 { value: "13:37:42", result: { time: 49062000, hours: 13, minutes: 37, seconds: 42, ms: 0 } }, 232 // Valid values including seconds fractions. 233 { value: "00:00:00.001", result: { time: 1, hours: 0, minutes: 0, seconds: 0, ms: 1 } }, 234 { value: "00:00:00.123", result: { time: 123, hours: 0, minutes: 0, seconds: 0, ms: 123 } }, 235 { value: "00:00:00.100", result: { time: 100, hours: 0, minutes: 0, seconds: 0, ms: 100 } }, 236 { value: "00:00:00.000", result: { time: 0, hours: 0, minutes: 0, seconds: 0, ms: 0 } }, 237 { value: "20:17:31.142", result: { time: 73051142, hours: 20, minutes: 17, seconds: 31, ms: 142 } }, 238 // Highest possible value. 239 { value: "23:59:59.999", result: { time: 86399999, hours: 23, minutes: 59, seconds: 59, ms: 999 } }, 240 // Some values with one or two digits for the fraction of seconds. 241 { value: "00:00:00.1", result: { time: 100, hours: 0, minutes: 0, seconds: 0, ms: 100 } }, 242 { value: "00:00:00.14", result: { time: 140, hours: 0, minutes: 0, seconds: 0, ms: 140 } }, 243 { value: "13:37:42.7", result: { time: 49062700, hours: 13, minutes: 37, seconds: 42, ms: 700 } }, 244 { value: "23:31:12.23", result: { time: 84672230, hours: 23, minutes: 31, seconds: 12, ms: 230 } }, 245 ]; 246 247 var inputElement = document.createElement('input'); 248 inputElement.type = 'time'; 249 250 for (let test of tests) { 251 inputElement.value = test.value; 252 if (test.result === null) { 253 is(inputElement.valueAsDate, null, "element.valueAsDate should return null"); 254 } else { 255 var date = inputElement.valueAsDate; 256 isnot(date, null, "element.valueAsDate should not be null"); 257 258 is(date.getTime(), test.result.time); 259 is(date.getUTCHours(), test.result.hours); 260 is(date.getUTCMinutes(), test.result.minutes); 261 is(date.getUTCSeconds(), test.result.seconds); 262 is(date.getUTCMilliseconds(), test.result.ms); 263 } 264 } 265 } 266 267 function checkTimeSet() 268 { 269 var tests = [ 270 // Simple tests. 271 { value: 0, result: "00:00" }, 272 { value: 1, result: "00:00:00.001" }, 273 { value: 100, result: "00:00:00.100" }, 274 { value: 1000, result: "00:00:01" }, 275 { value: 60000, result: "00:01" }, 276 { value: 3600000, result: "01:00" }, 277 { value: 83622234, result: "23:13:42.234" }, 278 // Some edge cases. 279 { value: 86400000, result: "00:00" }, 280 { value: 86400001, result: "00:00:00.001" }, 281 { value: 170022234, result: "23:13:42.234" }, 282 { value: 432000000, result: "00:00" }, 283 { value: -1, result: "23:59:59.999" }, 284 { value: -86400000, result: "00:00" }, 285 { value: -86400001, result: "23:59:59.999" }, 286 { value: -56789, result: "23:59:03.211" }, 287 { value: 0.9, result: "00:00" }, 288 ]; 289 290 var inputElement = document.createElement('input'); 291 inputElement.type = 'time'; 292 293 for (let test of tests) { 294 inputElement.valueAsDate = new Date(test.value); 295 is(inputElement.value, test.result, 296 "element.value should have been changed by setting valueAsDate"); 297 } 298 } 299 300 function checkWithBustedPrototype() 301 { 302 for (let type of validTypes) { 303 if (!type[1]) { 304 continue; 305 } 306 307 type = type[0]; 308 309 var inputElement = document.createElement('input'); 310 inputElement.type = type; 311 312 var backupPrototype = {}; 313 backupPrototype.getUTCFullYear = Date.prototype.getUTCFullYear; 314 backupPrototype.getUTCMonth = Date.prototype.getUTCMonth; 315 backupPrototype.getUTCDate = Date.prototype.getUTCDate; 316 backupPrototype.getTime = Date.prototype.getTime; 317 backupPrototype.setUTCFullYear = Date.prototype.setUTCFullYear; 318 319 Date.prototype.getUTCFullYear = function() { return {}; }; 320 Date.prototype.getUTCMonth = function() { return {}; }; 321 Date.prototype.getUTCDate = function() { return {}; }; 322 Date.prototype.getTime = function() { return {}; }; 323 Date.prototype.setUTCFullYear = function(y,m,d) { }; 324 325 inputElement.valueAsDate = new Date(); 326 327 isnot(inputElement.valueAsDate, null, ".valueAsDate should not return null"); 328 // The object returned by element.valueAsDate should return a Date object 329 // with the same prototype: 330 is(inputElement.valueAsDate.getUTCFullYear, Date.prototype.getUTCFullYear, 331 "prototype is the same"); 332 is(inputElement.valueAsDate.getUTCMonth, Date.prototype.getUTCMonth, 333 "prototype is the same"); 334 is(inputElement.valueAsDate.getUTCDate, Date.prototype.getUTCDate, 335 "prototype is the same"); 336 is(inputElement.valueAsDate.getTime, Date.prototype.getTime, 337 "prototype is the same"); 338 is(inputElement.valueAsDate.setUTCFullYear, Date.prototype.setUTCFullYear, 339 "prototype is the same"); 340 341 // However the Date should have the correct information. 342 // Skip type=month for now, since .valueAsNumber returns number of months 343 // and not milliseconds. 344 if (type != "month") { 345 var witnessDate = new Date(inputElement.valueAsNumber); 346 is(inputElement.valueAsDate.valueOf(), witnessDate.valueOf(), "correct Date"); 347 } 348 349 // Same test as above but using NaN instead of {}. 350 351 Date.prototype.getUTCFullYear = function() { return NaN; }; 352 Date.prototype.getUTCMonth = function() { return NaN; }; 353 Date.prototype.getUTCDate = function() { return NaN; }; 354 Date.prototype.getTime = function() { return NaN; }; 355 Date.prototype.setUTCFullYear = function(y,m,d) { }; 356 357 inputElement.valueAsDate = new Date(); 358 359 isnot(inputElement.valueAsDate, null, ".valueAsDate should not return null"); 360 // The object returned by element.valueAsDate should return a Date object 361 // with the same prototype: 362 is(inputElement.valueAsDate.getUTCFullYear, Date.prototype.getUTCFullYear, 363 "prototype is the same"); 364 is(inputElement.valueAsDate.getUTCMonth, Date.prototype.getUTCMonth, 365 "prototype is the same"); 366 is(inputElement.valueAsDate.getUTCDate, Date.prototype.getUTCDate, 367 "prototype is the same"); 368 is(inputElement.valueAsDate.getTime, Date.prototype.getTime, 369 "prototype is the same"); 370 is(inputElement.valueAsDate.setUTCFullYear, Date.prototype.setUTCFullYear, 371 "prototype is the same"); 372 373 // However the Date should have the correct information. 374 // Skip type=month for now, since .valueAsNumber returns number of months 375 // and not milliseconds. 376 if (type != "month") { 377 var witnessDate = new Date(inputElement.valueAsNumber); 378 is(inputElement.valueAsDate.valueOf(), witnessDate.valueOf(), "correct Date"); 379 } 380 381 Date.prototype.getUTCFullYear = backupPrototype.getUTCFullYear; 382 Date.prototype.getUTCMonth = backupPrototype.getUTCMonth; 383 Date.prototype.getUTCDate = backupPrototype.getUTCDate; 384 Date.prototype.getTime = backupPrototype.getTime; 385 Date.prototype.setUTCFullYear = backupPrototype.setUTCFullYear; 386 } 387 } 388 389 function checkMonthGet() 390 { 391 var validData = 392 [ 393 [ "2016-07", 1467331200000 ], 394 [ "1970-01", 0 ], 395 [ "1970-02", 2678400000 ], 396 [ "1969-12", -2678400000 ], 397 [ "0001-01", -62135596800000 ], 398 [ "275760-09", 8639998963200000 ], 399 ]; 400 401 var invalidData = 402 [ 403 [ "invalidmonth" ], 404 [ "0000-01" ], 405 [ "2016-00" ], 406 [ "123-01" ], 407 [ "2017-13" ], 408 [ "" ], 409 // This month is valid for the input element, but is out of 410 // the date object range. In this case, on getting valueAsDate, 411 // a Date object will be created, but it will have a NaN internal value, 412 // and will return the string "Invalid Date". 413 [ "275760-10", true ], 414 ]; 415 416 element.type = "month"; 417 for (let data of validData) { 418 element.value = data[0]; 419 is(element.valueAsDate.valueOf(), data[1], 420 "valueAsDate should return the " + 421 "valid date object representing this month"); 422 } 423 424 for (let data of invalidData) { 425 element.value = data[0]; 426 if (data[1]) { 427 is(String(element.valueAsDate), "Invalid Date", 428 "valueAsDate should return an invalid Date object " + 429 "when the element value is not a valid month"); 430 } else { 431 is(element.valueAsDate, null, 432 "valueAsDate should return null " + 433 "when the element value is not a valid month"); 434 } 435 } 436 } 437 438 function checkMonthSet() 439 { 440 var testData = 441 [ 442 [ 1342051200000, "2012-07" ], 443 [ 0, "1970-01" ], 444 // Maximum valid month (limited by the ecma date object range). 445 [ 8640000000000000, "275760-09" ], 446 // Minimum valid month (limited by the input element minimum valid value). 447 [ -62135596800000 , "0001-01" ], 448 [ 1330473600000, "2012-02" ], 449 [ 1298851200000, "2011-02" ], 450 // "Values must be truncated to valid months" 451 [ 42.1234, "1970-01" ], 452 [ 123.123456789123, "1970-01" ], 453 [ 1e-1, "1970-01" ], 454 [ 1298851200010, "2011-02" ], 455 [ -1, "1969-12" ], 456 [ -86400000, "1969-12" ], 457 [ 86400000, "1970-01" ], 458 // Negative years, this is out of range for the input element, 459 // the corresponding month string is the empty string 460 [ -62135596800001, "" ], 461 ]; 462 463 element.type = "month"; 464 for (let data of testData) { 465 element.valueAsDate = new Date(data[0]); 466 is(element.value, data[1], "valueAsDate should set the value to " 467 + data[1]); 468 element.valueAsDate = new testFrame.Date(data[0]); 469 is(element.value, data[1], "valueAsDate with other-global date should " + 470 "set the value to " + data[1]); 471 } 472 } 473 474 function checkWeekGet() 475 { 476 var validData = 477 [ 478 // Common years starting on different days of week. 479 [ "2007-W01", Date.UTC(2007, 0, 1) ], // Mon 480 [ "2013-W01", Date.UTC(2012, 11, 31) ], // Tue 481 [ "2014-W01", Date.UTC(2013, 11, 30) ], // Wed 482 [ "2015-W01", Date.UTC(2014, 11, 29) ], // Thu 483 [ "2010-W01", Date.UTC(2010, 0, 4) ], // Fri 484 [ "2011-W01", Date.UTC(2011, 0, 3) ], // Sat 485 [ "2017-W01", Date.UTC(2017, 0, 2) ], // Sun 486 // Common years ending on different days of week. 487 [ "2007-W52", Date.UTC(2007, 11, 24) ], // Mon 488 [ "2013-W52", Date.UTC(2013, 11, 23) ], // Tue 489 [ "2014-W52", Date.UTC(2014, 11, 22) ], // Wed 490 [ "2015-W53", Date.UTC(2015, 11, 28) ], // Thu 491 [ "2010-W52", Date.UTC(2010, 11, 27) ], // Fri 492 [ "2011-W52", Date.UTC(2011, 11, 26) ], // Sat 493 [ "2017-W52", Date.UTC(2017, 11, 25) ], // Sun 494 // Leap years starting on different days of week. 495 [ "1996-W01", Date.UTC(1996, 0, 1) ], // Mon 496 [ "2008-W01", Date.UTC(2007, 11, 31) ], // Tue 497 [ "2020-W01", Date.UTC(2019, 11, 30) ], // Wed 498 [ "2004-W01", Date.UTC(2003, 11, 29) ], // Thu 499 [ "2016-W01", Date.UTC(2016, 0, 4) ], // Fri 500 [ "2000-W01", Date.UTC(2000, 0, 3) ], // Sat 501 [ "2012-W01", Date.UTC(2012, 0, 2) ], // Sun 502 // Leap years ending on different days of week. 503 [ "2012-W52", Date.UTC(2012, 11, 24) ], // Mon 504 [ "2024-W52", Date.UTC(2024, 11, 23) ], // Tue 505 [ "1980-W52", Date.UTC(1980, 11, 22) ], // Wed 506 [ "1992-W53", Date.UTC(1992, 11, 28) ], // Thu 507 [ "2004-W53", Date.UTC(2004, 11, 27) ], // Fri 508 [ "1988-W52", Date.UTC(1988, 11, 26) ], // Sat 509 [ "2000-W52", Date.UTC(2000, 11, 25) ], // Sun 510 // Other normal cases. 511 [ "2016-W36", 1473033600000 ], 512 [ "1969-W52", -864000000 ], 513 [ "1970-W01", -259200000 ], 514 [ "275760-W37", 8639999568000000 ], 515 ]; 516 517 var invalidData = 518 [ 519 [ "invalidweek" ], 520 [ "0000-W01" ], 521 [ "2016-W00" ], 522 [ "123-W01" ], 523 [ "2016-W53" ], 524 [ "" ], 525 // This week is valid for the input element, but is out of 526 // the date object range. In this case, on getting valueAsDate, 527 // a Date object will be created, but it will have a NaN internal value, 528 // and will return the string "Invalid Date". 529 [ "275760-W38", true ], 530 ]; 531 532 element.type = "week"; 533 for (let data of validData) { 534 element.value = data[0]; 535 is(element.valueAsDate.valueOf(), data[1], 536 "valueAsDate should return the " + 537 "valid date object representing this week"); 538 } 539 540 for (let data of invalidData) { 541 element.value = data[0]; 542 if (data[1]) { 543 is(String(element.valueAsDate), "Invalid Date", 544 "valueAsDate should return an invalid Date object " + 545 "when the element value is not a valid week"); 546 } else { 547 is(element.valueAsDate, null, 548 "valueAsDate should return null " + 549 "when the element value is not a valid week"); 550 } 551 } 552 } 553 554 function checkWeekSet() 555 { 556 var testData = 557 [ 558 // Common years starting on different days of week. 559 [ Date.UTC(2007, 0, 1), "2007-W01" ], // Mon 560 [ Date.UTC(2013, 0, 1), "2013-W01" ], // Tue 561 [ Date.UTC(2014, 0, 1), "2014-W01" ], // Wed 562 [ Date.UTC(2015, 0, 1), "2015-W01" ], // Thu 563 [ Date.UTC(2010, 0, 1), "2009-W53" ], // Fri 564 [ Date.UTC(2011, 0, 1), "2010-W52" ], // Sat 565 [ Date.UTC(2017, 0, 1), "2016-W52" ], // Sun 566 // Common years ending on different days of week. 567 [ Date.UTC(2007, 11, 31), "2008-W01" ], // Mon 568 [ Date.UTC(2013, 11, 31), "2014-W01" ], // Tue 569 [ Date.UTC(2014, 11, 31), "2015-W01" ], // Wed 570 [ Date.UTC(2015, 11, 31), "2015-W53" ], // Thu 571 [ Date.UTC(2010, 11, 31), "2010-W52" ], // Fri 572 [ Date.UTC(2011, 11, 31), "2011-W52" ], // Sat 573 [ Date.UTC(2017, 11, 31), "2017-W52" ], // Sun 574 // Leap years starting on different days of week. 575 [ Date.UTC(1996, 0, 1), "1996-W01" ], // Mon 576 [ Date.UTC(2008, 0, 1), "2008-W01" ], // Tue 577 [ Date.UTC(2020, 0, 1), "2020-W01" ], // Wed 578 [ Date.UTC(2004, 0, 1), "2004-W01" ], // Thu 579 [ Date.UTC(2016, 0, 1), "2015-W53" ], // Fri 580 [ Date.UTC(2000, 0, 1), "1999-W52" ], // Sat 581 [ Date.UTC(2012, 0, 1), "2011-W52" ], // Sun 582 // Leap years ending on different days of week. 583 [ Date.UTC(2012, 11, 31), "2013-W01" ], // Mon 584 [ Date.UTC(2024, 11, 31), "2025-W01" ], // Tue 585 [ Date.UTC(1980, 11, 31), "1981-W01" ], // Wed 586 [ Date.UTC(1992, 11, 31), "1992-W53" ], // Thu 587 [ Date.UTC(2004, 11, 31), "2004-W53" ], // Fri 588 [ Date.UTC(1988, 11, 31), "1988-W52" ], // Sat 589 [ Date.UTC(2000, 11, 31), "2000-W52" ], // Sun 590 // Other normal cases. 591 [ Date.UTC(2016, 8, 9), "2016-W36" ], 592 [ Date.UTC(2010, 0, 3), "2009-W53" ], 593 [ Date.UTC(2010, 0, 4), "2010-W01" ], 594 [ Date.UTC(2010, 0, 10), "2010-W01" ], 595 [ Date.UTC(2010, 0, 11), "2010-W02" ], 596 [ 0, "1970-W01" ], 597 // Maximum valid month (limited by the ecma date object range). 598 [ 8640000000000000, "275760-W37" ], 599 // Minimum valid month (limited by the input element minimum valid value). 600 [ -62135596800000 , "0001-W01" ], 601 // "Values must be truncated to valid week" 602 [ 42.1234, "1970-W01" ], 603 [ 123.123456789123, "1970-W01" ], 604 [ 1e-1, "1970-W01" ], 605 [ -1.1, "1970-W01" ], 606 [ -345600000, "1969-W52" ], 607 // Negative years, this is out of range for the input element, 608 // the corresponding week string is the empty string 609 [ -62135596800001, "" ], 610 ]; 611 612 element.type = "week"; 613 for (let data of testData) { 614 element.valueAsDate = new Date(data[0]); 615 is(element.value, data[1], "valueAsDate should set the value to " 616 + data[1]); 617 element.valueAsDate = new testFrame.Date(data[0]); 618 is(element.value, data[1], "valueAsDate with other-global date should " + 619 "set the value to " + data[1]); 620 } 621 } 622 623 function checkDatetimeLocalGet() 624 { 625 var validData = 626 [ 627 // Simple cases. 628 [ "2016-12-27T10:30", Date.UTC(2016, 11, 27, 10, 30, 0) ], 629 [ "2016-12-27T10:30:40", Date.UTC(2016, 11, 27, 10, 30, 40) ], 630 [ "2016-12-27T10:30:40.567", Date.UTC(2016, 11, 27, 10, 30, 40, 567) ], 631 [ "1969-12-31T12:00:00", Date.UTC(1969, 11, 31, 12, 0, 0) ], 632 [ "1970-01-01T00:00", 0 ], 633 // Leap years. 634 [ "1804-02-29 12:34", Date.UTC(1804, 1, 29, 12, 34, 0) ], 635 [ "2016-02-29T12:34", Date.UTC(2016, 1, 29, 12, 34, 0) ], 636 [ "2016-12-31T12:34:56", Date.UTC(2016, 11, 31, 12, 34, 56) ], 637 [ "2016-01-01T12:34:56.789", Date.UTC(2016, 0, 1, 12, 34, 56, 789) ], 638 [ "2017-01-01 12:34:56.789", Date.UTC(2017, 0, 1, 12, 34, 56, 789) ], 639 // Maximum valid datetime-local (limited by the ecma date object range). 640 [ "275760-09-13T00:00", 8640000000000000 ], 641 // Minimum valid datetime-local (limited by the input element minimum valid value). 642 [ "0001-01-01T00:00", -62135596800000 ], 643 ]; 644 645 var invalidData = 646 [ 647 [ "invaliddateime-local" ], 648 [ "0000-01-01T00:00" ], 649 [ "2016-12-25T00:00Z" ], 650 [ "2015-02-29T12:34" ], 651 [ "1-1-1T12:00" ], 652 [ "" ], 653 // This datetime-local is valid for the input element, but is out of the 654 // date object range. In this case, on getting valueAsDate, a Date object 655 // will be created, but it will have a NaN internal value, and will return 656 // the string "Invalid Date". 657 [ "275760-09-13T12:00", true ], 658 ]; 659 660 element.type = "datetime-local"; 661 for (let data of validData) { 662 element.value = data[0]; 663 is(element.valueAsDate.valueOf(), data[1], 664 "valueAsDate should return the " + 665 "valid date object representing this datetime-local"); 666 } 667 668 for (let data of invalidData) { 669 element.value = data[0]; 670 if (data[1]) { 671 is(String(element.valueAsDate), "Invalid Date", 672 "valueAsDate should return an invalid Date object " + 673 "when the element value is not a valid datetime-local"); 674 } else { 675 is(element.valueAsDate, null, 676 "valueAsDate should return null " + 677 "when the element value is not a valid datetime-local"); 678 } 679 } 680 } 681 682 function checkDatetimeLocalSet() 683 { 684 var testData = 685 [ 686 // Simple cases. 687 [ Date.UTC(2016, 11, 27, 10, 30, 0), "2016-12-27T10:30" ], 688 [ Date.UTC(2016, 11, 27, 10, 30, 30), "2016-12-27T10:30:30" ], 689 [ Date.UTC(1999, 11, 31, 23, 59, 59), "1999-12-31T23:59:59" ], 690 [ Date.UTC(1999, 11, 31, 23, 59, 59, 999), "1999-12-31T23:59:59.999" ], 691 [ Date.UTC(123456, 7, 8, 9, 10), "123456-08-08T09:10" ], 692 [ 0, "1970-01-01T00:00" ], 693 // Maximum valid datetime-local (limited by the ecma date object range). 694 [ 8640000000000000, "275760-09-13T00:00" ], 695 // Minimum valid datetime-local (limited by the input element minimum valid value). 696 [ -62135596800000, "0001-01-01T00:00" ], 697 // Leap years. 698 [ Date.UTC(1804, 1, 29, 12, 34, 0), "1804-02-29T12:34" ], 699 [ Date.UTC(2016, 1, 29, 12, 34, 0), "2016-02-29T12:34" ], 700 [ Date.UTC(2016, 11, 31, 12, 34, 56), "2016-12-31T12:34:56" ], 701 [ Date.UTC(2016, 0, 1, 12, 34, 56, 789), "2016-01-01T12:34:56.789" ], 702 [ Date.UTC(2017, 0, 1, 12, 34, 56, 789), "2017-01-01T12:34:56.789" ], 703 // "Values must be truncated to valid datetime-local" 704 [ 123.123456789123, "1970-01-01T00:00:00.123" ], 705 [ 1e-1, "1970-01-01T00:00" ], 706 [ -1.1, "1969-12-31T23:59:59.999" ], 707 [ -345600000, "1969-12-28T00:00" ], 708 // Negative years, this is out of range for the input element, 709 // the corresponding datetime-local string is the empty string 710 [ -62135596800001, "" ], 711 ]; 712 713 element.type = "datetime-local"; 714 for (let data of testData) { 715 element.valueAsDate = new Date(data[0]); 716 is(element.value, data[1], "valueAsDate should set the value to " + 717 data[1]); 718 element.valueAsDate = new testFrame.Date(data[0]); 719 is(element.value, data[1], "valueAsDate with other-global date should " + 720 "set the value to " + data[1]); 721 } 722 } 723 724 checkAvailability(); 725 checkGarbageValues(); 726 checkWithBustedPrototype(); 727 728 // Test <input type='date'>. 729 checkDateGet(); 730 checkDateSet(); 731 732 // Test <input type='time'>. 733 checkTimeGet(); 734 checkTimeSet(); 735 736 // Test <input type='month'>. 737 checkMonthGet(); 738 checkMonthSet(); 739 740 // Test <input type='week'>. 741 checkWeekGet(); 742 checkWeekSet(); 743 744 // Test <input type='datetime-local'>. 745 checkDatetimeLocalGet(); 746 checkDatetimeLocalSet(); 747 748 </script> 749 </pre> 750 </body> 751 </html>