1// Copyright 2008 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28// Test that we can parse dates in all the different formats that we 29// have to support. 30// 31// These formats are all supported by KJS but a lot of them are not 32// supported by Spidermonkey. 33 34function testDateParse(string) { 35 var d = Date.parse(string); 36 assertEquals(946713600000, d, "parse: " + string); 37}; 38 39 40// For local time we just test that parsing returns non-NaN positive 41// number of milliseconds to make it timezone independent. 42function testDateParseLocalTime(string) { 43 var d = Date.parse("parse-local-time:" + string); 44 assertTrue(!isNaN(d), "parse-local-time: " + string + " is NaN."); 45 assertTrue(d > 0, "parse-local-time: " + string + " <= 0."); 46}; 47 48 49function testDateParseMisc(array) { 50 assertEquals(2, array.length, "array [" + array + "] length != 2."); 51 var string = array[0]; 52 var expected = array[1]; 53 var d = Date.parse(string); 54 assertEquals(expected, d, "parse-misc: " + string); 55} 56 57 58// 59// Test all the formats in UT timezone. 60// 61var testCasesUT = [ 62 'Sat, 01-Jan-2000 08:00:00 UT', 63 'Sat, 01 Jan 2000 08:00:00 UT', 64 'Jan 01 2000 08:00:00 UT', 65 'Jan 01 08:00:00 UT 2000', 66 'Saturday, 01-Jan-00 08:00:00 UT', 67 '01 Jan 00 08:00 +0000', 68 // Ignore weekdays. 69 'Mon, 01 Jan 2000 08:00:00 UT', 70 'Tue, 01 Jan 2000 08:00:00 UT', 71 // Ignore prefix that is not part of a date. 72 '[Saturday] Jan 01 08:00:00 UT 2000', 73 'Ignore all of this stuff because it is annoying 01 Jan 2000 08:00:00 UT', 74 '[Saturday] Jan 01 2000 08:00:00 UT', 75 'All of this stuff is really annnoying, so it will be ignored Jan 01 2000 08:00:00 UT', 76 // If the three first letters of the month is a 77 // month name we are happy - ignore the rest. 78 'Sat, 01-Janisamonth-2000 08:00:00 UT', 79 'Sat, 01 Janisamonth 2000 08:00:00 UT', 80 'Janisamonth 01 2000 08:00:00 UT', 81 'Janisamonth 01 08:00:00 UT 2000', 82 'Saturday, 01-Janisamonth-00 08:00:00 UT', 83 '01 Janisamonth 00 08:00 +0000', 84 // Allow missing space between month and day. 85 'Janisamonthandtherestisignored01 2000 08:00:00 UT', 86 'Jan01 2000 08:00:00 UT', 87 // Allow year/month/day format. 88 'Sat, 2000/01/01 08:00:00 UT', 89 // Allow month/day/year format. 90 'Sat, 01/01/2000 08:00:00 UT', 91 // Allow month/day year format. 92 'Sat, 01/01 2000 08:00:00 UT', 93 // Allow comma instead of space after day, month and year. 94 'Sat, 01,Jan,2000,08:00:00 UT', 95 // Seconds are optional. 96 'Sat, 01-Jan-2000 08:00 UT', 97 'Sat, 01 Jan 2000 08:00 UT', 98 'Jan 01 2000 08:00 UT', 99 'Jan 01 08:00 UT 2000', 100 'Saturday, 01-Jan-00 08:00 UT', 101 '01 Jan 00 08:00 +0000', 102 // Allow AM/PM after the time. 103 'Sat, 01-Jan-2000 08:00 AM UT', 104 'Sat, 01 Jan 2000 08:00 AM UT', 105 'Jan 01 2000 08:00 AM UT', 106 'Jan 01 08:00 AM UT 2000', 107 'Saturday, 01-Jan-00 08:00 AM UT', 108 '01 Jan 00 08:00 AM +0000', 109 // White space and stuff in parenthesis is 110 // apparently allowed in most places where white 111 // space is allowed. 112 ' Sat, 01-Jan-2000 08:00:00 UT ', 113 ' Sat, 01 Jan 2000 08:00:00 UT ', 114 ' Saturday, 01-Jan-00 08:00:00 UT ', 115 ' 01 Jan 00 08:00 +0000 ', 116 ' ()(Sat, 01-Jan-2000) Sat, 01-Jan-2000 08:00:00 UT ', 117 ' Sat()(Sat, 01-Jan-2000)01 Jan 2000 08:00:00 UT ', 118 ' Sat,(02)01 Jan 2000 08:00:00 UT ', 119 ' Sat, 01(02)Jan 2000 08:00:00 UT ', 120 ' Sat, 01 Jan 2000 (2001)08:00:00 UT ', 121 ' Sat, 01 Jan 2000 (01)08:00:00 UT ', 122 ' Sat, 01 Jan 2000 (01:00:00)08:00:00 UT ', 123 ' Sat, 01 Jan 2000 08:00:00 (CDT)UT ', 124 ' Sat, 01 Jan 2000 08:00:00 UT((((CDT))))', 125 ' Saturday, 01-Jan-00 ()(((asfd)))(Sat, 01-Jan-2000)08:00:00 UT ', 126 ' 01 Jan 00 08:00 ()(((asdf)))(Sat, 01-Jan-2000)+0000 ', 127 ' 01 Jan 00 08:00 +0000()((asfd)(Sat, 01-Jan-2000)) ']; 128 129// 130// Test that we do the right correction for different time zones. 131// I'll assume that we can handle the same formats as for UT and only 132// test a few formats for each of the timezones. 133// 134 135// GMT = UT 136var testCasesGMT = [ 137 'Sat, 01-Jan-2000 08:00:00 GMT', 138 'Sat, 01-Jan-2000 08:00:00 GMT+0', 139 'Sat, 01-Jan-2000 08:00:00 GMT+00', 140 'Sat, 01-Jan-2000 08:00:00 GMT+000', 141 'Sat, 01-Jan-2000 08:00:00 GMT+0000', 142 'Sat, 01-Jan-2000 08:00:00 GMT+00:00', // Interestingly, KJS cannot handle this. 143 'Sat, 01 Jan 2000 08:00:00 GMT', 144 'Saturday, 01-Jan-00 08:00:00 GMT', 145 '01 Jan 00 08:00 -0000', 146 '01 Jan 00 08:00 +0000']; 147 148// EST = UT minus 5 hours. 149var testCasesEST = [ 150 'Sat, 01-Jan-2000 03:00:00 UTC-0500', 151 'Sat, 01-Jan-2000 03:00:00 UTC-05:00', // Interestingly, KJS cannot handle this. 152 'Sat, 01-Jan-2000 03:00:00 EST', 153 'Sat, 01 Jan 2000 03:00:00 EST', 154 'Saturday, 01-Jan-00 03:00:00 EST', 155 '01 Jan 00 03:00 -0500']; 156 157// EDT = UT minus 4 hours. 158var testCasesEDT = [ 159 'Sat, 01-Jan-2000 04:00:00 EDT', 160 'Sat, 01 Jan 2000 04:00:00 EDT', 161 'Saturday, 01-Jan-00 04:00:00 EDT', 162 '01 Jan 00 04:00 -0400']; 163 164// CST = UT minus 6 hours. 165var testCasesCST = [ 166 'Sat, 01-Jan-2000 02:00:00 CST', 167 'Sat, 01 Jan 2000 02:00:00 CST', 168 'Saturday, 01-Jan-00 02:00:00 CST', 169 '01 Jan 00 02:00 -0600']; 170 171// CDT = UT minus 5 hours. 172var testCasesCDT = [ 173 'Sat, 01-Jan-2000 03:00:00 CDT', 174 'Sat, 01 Jan 2000 03:00:00 CDT', 175 'Saturday, 01-Jan-00 03:00:00 CDT', 176 '01 Jan 00 03:00 -0500']; 177 178// MST = UT minus 7 hours. 179var testCasesMST = [ 180 'Sat, 01-Jan-2000 01:00:00 MST', 181 'Sat, 01 Jan 2000 01:00:00 MST', 182 'Saturday, 01-Jan-00 01:00:00 MST', 183 '01 Jan 00 01:00 -0700']; 184 185// MDT = UT minus 6 hours. 186var testCasesMDT = [ 187 'Sat, 01-Jan-2000 02:00:00 MDT', 188 'Sat, 01 Jan 2000 02:00:00 MDT', 189 'Saturday, 01-Jan-00 02:00:00 MDT', 190 '01 Jan 00 02:00 -0600']; 191 192// PST = UT minus 8 hours. 193var testCasesPST = [ 194 'Sat, 01-Jan-2000 00:00:00 PST', 195 'Sat, 01 Jan 2000 00:00:00 PST', 196 'Saturday, 01-Jan-00 00:00:00 PST', 197 '01 Jan 00 00:00 -0800', 198 // Allow missing time. 199 'Sat, 01-Jan-2000 PST']; 200 201// PDT = UT minus 7 hours. 202var testCasesPDT = [ 203 'Sat, 01-Jan-2000 01:00:00 PDT', 204 'Sat, 01 Jan 2000 01:00:00 PDT', 205 'Saturday, 01-Jan-00 01:00:00 PDT', 206 '01 Jan 00 01:00 -0700']; 207 208// Local time cases. 209var testCasesLocalTime = [ 210 // Allow timezone ommision. 211 'Sat, 01-Jan-2000 08:00:00', 212 'Sat, 01 Jan 2000 08:00:00', 213 'Jan 01 2000 08:00:00', 214 'Jan 01 08:00:00 2000', 215 'Saturday, 01-Jan-00 08:00:00', 216 '01 Jan 00 08:00']; 217 218 219// Misc. test cases that result in a different time value. 220var testCasesMisc = [ 221 // Special handling for years in the [0, 100) range. 222 ['Sat, 01 Jan 0 08:00:00 UT', 946713600000], // year 2000 223 ['Sat, 01 Jan 49 08:00:00 UT', 2493100800000], // year 2049 224 ['Sat, 01 Jan 50 08:00:00 UT', -631123200000], // year 1950 225 ['Sat, 01 Jan 99 08:00:00 UT', 915177600000], // year 1999 226 ['Sat, 01 Jan 100 08:00:00 UT', -59011430400000], // year 100 227 // Test PM after time. 228 ['Sat, 01-Jan-2000 08:00 PM UT', 946756800000], 229 ['Sat, 01 Jan 2000 08:00 PM UT', 946756800000], 230 ['Jan 01 2000 08:00 PM UT', 946756800000], 231 ['Jan 01 08:00 PM UT 2000', 946756800000], 232 ['Saturday, 01-Jan-00 08:00 PM UT', 946756800000], 233 ['01 Jan 00 08:00 PM +0000', 946756800000]]; 234 235// Test different version of the ES5 date time string format. 236var testCasesES5Misc = [ 237 ['2000-01-01T08:00:00.000Z', 946713600000], 238 ['2000-01-01T08:00:00Z', 946713600000], 239 ['2000-01-01T08:00Z', 946713600000], 240 ['2000-01T08:00:00.000Z', 946713600000], 241 ['2000T08:00:00.000Z', 946713600000], 242 ['2000T08:00Z', 946713600000], 243 ['2000-01T00:00:00.000-08:00', 946713600000], 244 ['2000-01T08:00:00.001Z', 946713600001], 245 ['2000-01T08:00:00.099Z', 946713600099], 246 ['2000-01T08:00:00.999Z', 946713600999], 247 ['2000-01T00:00:00.001-08:00', 946713600001]]; 248 249var testCasesES5MiscNegative = [ 250 '2000-01-01TZ', 251 '2000-01-01T60Z', 252 '2000-01-01T60:60Z', 253 '2000-01-0108:00Z', 254 '2000-01-01T08Z']; 255 256 257// Run all the tests. 258testCasesUT.forEach(testDateParse); 259testCasesGMT.forEach(testDateParse); 260testCasesEST.forEach(testDateParse); 261testCasesEDT.forEach(testDateParse); 262testCasesCST.forEach(testDateParse); 263testCasesCDT.forEach(testDateParse); 264testCasesMST.forEach(testDateParse); 265testCasesMDT.forEach(testDateParse); 266testCasesPST.forEach(testDateParse); 267testCasesPDT.forEach(testDateParse); 268testCasesLocalTime.forEach(testDateParseLocalTime); 269testCasesMisc.forEach(testDateParseMisc); 270 271// ES5 date time string format compliance. 272testCasesES5Misc.forEach(testDateParseMisc); 273testCasesES5MiscNegative.forEach(function (s) { 274 assertTrue(isNaN(Date.parse(s)), s + " is not NaN."); 275}); 276 277 278// Test that we can parse our own date format. 279// (Dates from 1970 to ~2070 with 150h steps.) 280for (var i = 0; i < 24 * 365 * 100; i += 150) { 281 var ms = i * (3600 * 1000); 282 var s = (new Date(ms)).toString(); 283 assertEquals(ms, Date.parse(s), "parse own: " + s); 284} 285 286// Negative tests. 287var testCasesNegative = [ 288 'May 25 2008 1:30 (PM)) UTC', // Bad unmatched ')' after number. 289 'May 25 2008 1:30( )AM (PM)', // 290 'May 25 2008 AAA (GMT)']; // Unknown word after number. 291 292testCasesNegative.forEach(function (s) { 293 assertTrue(isNaN(Date.parse(s)), s + " is not NaN."); 294}); 295