| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Tests the DateFormat library in dart. This file contains core tests that | 6 * Tests the DateFormat library in dart. This file contains core tests that |
| 7 * are run regardless of where the locale data is found, so it doesn't expect to | 7 * are run regardless of where the locale data is found, so it doesn't expect to |
| 8 * be run on its own, but rather to be imported and run from another test file. | 8 * be run on its own, but rather to be imported and run from another test file. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 // SPECIFIC_TZ, | 119 // SPECIFIC_TZ, |
| 120 // ABBR_UTC_TZ | 120 // ABBR_UTC_TZ |
| 121 ]; | 121 ]; |
| 122 | 122 |
| 123 /** | 123 /** |
| 124 * Exercise all of the formats we have explicitly defined on a particular | 124 * Exercise all of the formats we have explicitly defined on a particular |
| 125 * locale. [expectedResults] is a map from ICU format names to the | 125 * locale. [expectedResults] is a map from ICU format names to the |
| 126 * expected result of formatting [date] according to that format in | 126 * expected result of formatting [date] according to that format in |
| 127 * [locale]. | 127 * [locale]. |
| 128 */ | 128 */ |
| 129 testLocale(String localeName, Map expectedResults, Date date) { | 129 testLocale(String localeName, Map expectedResults, DateTime date) { |
| 130 var intl = new Intl(localeName); | 130 var intl = new Intl(localeName); |
| 131 for(int i=0; i<formatsToTest.length; i++) { | 131 for(int i=0; i<formatsToTest.length; i++) { |
| 132 var skeleton = formatsToTest[i]; | 132 var skeleton = formatsToTest[i]; |
| 133 var format = intl.date(skeleton); | 133 var format = intl.date(skeleton); |
| 134 var icuName = icuFormatNamesToTest[i]; | 134 var icuName = icuFormatNamesToTest[i]; |
| 135 var actualResult = format.format(date); | 135 var actualResult = format.format(date); |
| 136 expect(expectedResults[icuName], equals(actualResult)); | 136 expect(expectedResults[icuName], equals(actualResult)); |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 | 139 |
| 140 testRoundTripParsing(String localeName, Date date) { | 140 testRoundTripParsing(String localeName, DateTime date) { |
| 141 // In order to test parsing, we can't just read back the date, because | 141 // In order to test parsing, we can't just read back the date, because |
| 142 // printing in most formats loses information. But we can test that | 142 // printing in most formats loses information. But we can test that |
| 143 // what we parsed back prints the same as what we originally printed. | 143 // what we parsed back prints the same as what we originally printed. |
| 144 // At least in most cases. In some cases, we can't even do that. e.g. | 144 // At least in most cases. In some cases, we can't even do that. e.g. |
| 145 // the skeleton WEEKDAY can't be reconstructed at all, and YEAR_MONTH | 145 // the skeleton WEEKDAY can't be reconstructed at all, and YEAR_MONTH |
| 146 // formats don't give us enough information to construct a valid date. | 146 // formats don't give us enough information to construct a valid date. |
| 147 var badSkeletons = [ | 147 var badSkeletons = [ |
| 148 DateFormat.ABBR_WEEKDAY, | 148 DateFormat.ABBR_WEEKDAY, |
| 149 DateFormat.WEEKDAY, | 149 DateFormat.WEEKDAY, |
| 150 DateFormat.QUARTER, | 150 DateFormat.QUARTER, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 List evenLocales() { | 194 List evenLocales() { |
| 195 int i = 1; | 195 int i = 1; |
| 196 return allLocales().where((x) => !((i++).isOdd)).toList(); | 196 return allLocales().where((x) => !((i++).isOdd)).toList(); |
| 197 } | 197 } |
| 198 | 198 |
| 199 // TODO(alanknight): Run specific tests for the en_ISO locale which isn't | 199 // TODO(alanknight): Run specific tests for the en_ISO locale which isn't |
| 200 // included in CLDR, and check that our patterns for it are correct (they | 200 // included in CLDR, and check that our patterns for it are correct (they |
| 201 // very likely aren't). | 201 // very likely aren't). |
| 202 runDateTests([List<String> subset]) { | 202 runDateTests([List<String> subset]) { |
| 203 test('Multiple patterns', () { | 203 test('Multiple patterns', () { |
| 204 var date = new Date.now(); | 204 var date = new DateTime.now(); |
| 205 var multiple1 = new DateFormat.yMd().add_jms(); | 205 var multiple1 = new DateFormat.yMd().add_jms(); |
| 206 var multiple2 = new DateFormat("yMd").add_jms(); | 206 var multiple2 = new DateFormat("yMd").add_jms(); |
| 207 var separate1 = new DateFormat.yMd(); | 207 var separate1 = new DateFormat.yMd(); |
| 208 var separate2 = new DateFormat.jms(); | 208 var separate2 = new DateFormat.jms(); |
| 209 var separateFormat = "${separate1.format(date)} ${separate2.format(date)}"; | 209 var separateFormat = "${separate1.format(date)} ${separate2.format(date)}"; |
| 210 expect(multiple1.format(date), equals(multiple2.format(date))); | 210 expect(multiple1.format(date), equals(multiple2.format(date))); |
| 211 expect(multiple1.format(date), equals(separateFormat)); | 211 expect(multiple1.format(date), equals(separateFormat)); |
| 212 var customPunctuation = new DateFormat("yMd").addPattern("jms",":::"); | 212 var customPunctuation = new DateFormat("yMd").addPattern("jms",":::"); |
| 213 var custom = "${separate1.format(date)}:::${separate2.format(date)}"; | 213 var custom = "${separate1.format(date)}:::${separate2.format(date)}"; |
| 214 expect(customPunctuation.format(date), equals(custom)); | 214 expect(customPunctuation.format(date), equals(custom)); |
| 215 }); | 215 }); |
| 216 | 216 |
| 217 test('Basic date format parsing', () { | 217 test('Basic date format parsing', () { |
| 218 var date_format = new DateFormat("d"); | 218 var date_format = new DateFormat("d"); |
| 219 expect( | 219 expect( |
| 220 date_format.parsePattern("hh:mm:ss") | 220 date_format.parsePattern("hh:mm:ss") |
| 221 .mappedBy((x) => x.pattern) | 221 .mappedBy((x) => x.pattern) |
| 222 .toList(), | 222 .toList(), |
| 223 orderedEquals(["hh",":", "mm",":","ss"])); | 223 orderedEquals(["hh",":", "mm",":","ss"])); |
| 224 expect( | 224 expect( |
| 225 date_format.parsePattern("hh:mm:ss") | 225 date_format.parsePattern("hh:mm:ss") |
| 226 .mappedBy((x) => x.pattern) | 226 .mappedBy((x) => x.pattern) |
| 227 .toList(), | 227 .toList(), |
| 228 orderedEquals(["hh",":", "mm",":","ss"])); | 228 orderedEquals(["hh",":", "mm",":","ss"])); |
| 229 }); | 229 }); |
| 230 | 230 |
| 231 test('Test ALL the supported formats on representative locales', () { | 231 test('Test ALL the supported formats on representative locales', () { |
| 232 var aDate = new Date(2012, 1, 27, 20, 58, 59, 0); | 232 var aDate = new DateTime(2012, 1, 27, 20, 58, 59, 0); |
| 233 testLocale("en_US", English, aDate); | 233 testLocale("en_US", English, aDate); |
| 234 if (subset.length > 1) { | 234 if (subset.length > 1) { |
| 235 // Don't run if we have just one locale, so some of these won't be there. | 235 // Don't run if we have just one locale, so some of these won't be there. |
| 236 testLocale("de_DE", German, aDate); | 236 testLocale("de_DE", German, aDate); |
| 237 testLocale("fr_FR", French, aDate); | 237 testLocale("fr_FR", French, aDate); |
| 238 testLocale("ja_JP", Japanese, aDate); | 238 testLocale("ja_JP", Japanese, aDate); |
| 239 testLocale("el_GR", Greek, aDate); | 239 testLocale("el_GR", Greek, aDate); |
| 240 testLocale("de_AT", Austrian, aDate); | 240 testLocale("de_AT", Austrian, aDate); |
| 241 } | 241 } |
| 242 }); | 242 }); |
| 243 | 243 |
| 244 test('Test round-trip parsing of dates', () { | 244 test('Test round-trip parsing of dates', () { |
| 245 var hours = [0, 1, 11, 12, 13, 23]; | 245 var hours = [0, 1, 11, 12, 13, 23]; |
| 246 var months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; | 246 var months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; |
| 247 var locales = subset == null ? allLocales() : subset; | 247 var locales = subset == null ? allLocales() : subset; |
| 248 for (var locale in locales) { | 248 for (var locale in locales) { |
| 249 for (var month in months) { | 249 for (var month in months) { |
| 250 var aDate = new Date(2012, month, 27, 13, 58, 59, 012); | 250 var aDate = new DateTime(2012, month, 27, 13, 58, 59, 012); |
| 251 testRoundTripParsing(locale, aDate); | 251 testRoundTripParsing(locale, aDate); |
| 252 } | 252 } |
| 253 for (var hour in hours) { | 253 for (var hour in hours) { |
| 254 var aDate = new Date(2012, 1, 27, hour, 58, 59, 123); | 254 var aDate = new DateTime(2012, 1, 27, hour, 58, 59, 123); |
| 255 testRoundTripParsing(locale, aDate); | 255 testRoundTripParsing(locale, aDate); |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 }); | 258 }); |
| 259 | 259 |
| 260 test('Patterns and symbols have the same coverage',() { | 260 test('Patterns and symbols have the same coverage',() { |
| 261 // Don't run if we have just one locale, so checking coverage isn't | 261 // Don't run if we have just one locale, so checking coverage isn't |
| 262 // very meaningful. | 262 // very meaningful. |
| 263 if (subset.length <= 1) return; | 263 if (subset.length <= 1) return; |
| 264 var patterns = new List.from(dateTimePatterns.keys); | 264 var patterns = new List.from(dateTimePatterns.keys); |
| 265 var compare = (a, b) => a.compareTo(b); | 265 var compare = (a, b) => a.compareTo(b); |
| 266 patterns.sort(compare); | 266 patterns.sort(compare); |
| 267 var symbols = allLocales(); | 267 var symbols = allLocales(); |
| 268 // Workaround for a dartj2 issue that treats the keys as immutable | 268 // Workaround for a dartj2 issue that treats the keys as immutable |
| 269 symbols = new List.from(symbols); | 269 symbols = new List.from(symbols); |
| 270 symbols.sort(compare); | 270 symbols.sort(compare); |
| 271 for (var i = 0; i < patterns.length; i++) { | 271 for (var i = 0; i < patterns.length; i++) { |
| 272 expect(patterns[i], equals(symbols[i])); | 272 expect(patterns[i], equals(symbols[i])); |
| 273 } | 273 } |
| 274 expect(patterns.length, equals(symbols.length)); | 274 expect(patterns.length, equals(symbols.length)); |
| 275 }); | 275 }); |
| 276 | 276 |
| 277 test('Test malformed locales', () { | 277 test('Test malformed locales', () { |
| 278 // Don't run if we have just one locale, which may not include these. | 278 // Don't run if we have just one locale, which may not include these. |
| 279 if (subset.length <= 1) return; | 279 if (subset.length <= 1) return; |
| 280 var aDate = new Date(2012, 1, 27, 20, 58, 59, 0); | 280 var aDate = new DateTime(2012, 1, 27, 20, 58, 59, 0); |
| 281 // Austrian is a useful test locale here because it differs slightly | 281 // Austrian is a useful test locale here because it differs slightly |
| 282 // from the generic "de" locale so we can tell the difference between | 282 // from the generic "de" locale so we can tell the difference between |
| 283 // correcting to "de_AT" and falling back to just "de". | 283 // correcting to "de_AT" and falling back to just "de". |
| 284 testLocale('de-AT', Austrian, aDate); | 284 testLocale('de-AT', Austrian, aDate); |
| 285 testLocale('de_at', Austrian, aDate); | 285 testLocale('de_at', Austrian, aDate); |
| 286 testLocale('de-at', Austrian, aDate); | 286 testLocale('de-at', Austrian, aDate); |
| 287 }); | 287 }); |
| 288 | 288 |
| 289 test('Test format creation via Intl', () { | 289 test('Test format creation via Intl', () { |
| 290 // Don't run if we have just one locale, which may not include these. | 290 // Don't run if we have just one locale, which may not include these. |
| 291 if (subset.length <= 1) return; | 291 if (subset.length <= 1) return; |
| 292 var intl = new Intl('ja_JP'); | 292 var intl = new Intl('ja_JP'); |
| 293 var instanceJP = intl.date('jms'); | 293 var instanceJP = intl.date('jms'); |
| 294 var instanceUS = intl.date('jms', 'en_US'); | 294 var instanceUS = intl.date('jms', 'en_US'); |
| 295 var blank = intl.date('jms'); | 295 var blank = intl.date('jms'); |
| 296 var date = new Date(2012, 1, 27, 20, 58, 59, 0); | 296 var date = new DateTime(2012, 1, 27, 20, 58, 59, 0); |
| 297 expect(instanceJP.format(date), equals("20:58:59")); | 297 expect(instanceJP.format(date), equals("20:58:59")); |
| 298 expect(instanceUS.format(date), equals("8:58:59 PM")); | 298 expect(instanceUS.format(date), equals("8:58:59 PM")); |
| 299 expect(blank.format(date), equals("20:58:59")); | 299 expect(blank.format(date), equals("20:58:59")); |
| 300 }); | 300 }); |
| 301 | 301 |
| 302 test('Test explicit format string', () { | 302 test('Test explicit format string', () { |
| 303 // Don't run if we have just one locale, which may not include these. | 303 // Don't run if we have just one locale, which may not include these. |
| 304 if (subset.length <= 1) return; | 304 if (subset.length <= 1) return; |
| 305 var aDate = new Date(2012, 1, 27, 20, 58, 59, 0); | 305 var aDate = new DateTime(2012, 1, 27, 20, 58, 59, 0); |
| 306 // An explicit format that doesn't conform to any skeleton | 306 // An explicit format that doesn't conform to any skeleton |
| 307 var us = new DateFormat(r'yy //// :D \\\\ dd:ss ^&@ M'); | 307 var us = new DateFormat(r'yy //// :D \\\\ dd:ss ^&@ M'); |
| 308 expect(us.format(aDate), equals(r"12 //// :D \\\\ 27:59 ^&@ 1")); | 308 expect(us.format(aDate), equals(r"12 //// :D \\\\ 27:59 ^&@ 1")); |
| 309 // The result won't change with locale unless we use fields that are words. | 309 // The result won't change with locale unless we use fields that are words. |
| 310 var greek = new DateFormat(r'yy //// :D \\\\ dd:ss ^&@ M', 'el_GR'); | 310 var greek = new DateFormat(r'yy //// :D \\\\ dd:ss ^&@ M', 'el_GR'); |
| 311 expect(greek.format(aDate), equals(r"12 //// :D \\\\ 27:59 ^&@ 1")); | 311 expect(greek.format(aDate), equals(r"12 //// :D \\\\ 27:59 ^&@ 1")); |
| 312 var usWithWords = new DateFormat('yy / :D \\ dd:ss ^&@ MMM', 'en_US'); | 312 var usWithWords = new DateFormat('yy / :D \\ dd:ss ^&@ MMM', 'en_US'); |
| 313 var greekWithWords = new DateFormat('yy / :D \\ dd:ss ^&@ MMM', 'el_GR'); | 313 var greekWithWords = new DateFormat('yy / :D \\ dd:ss ^&@ MMM', 'el_GR'); |
| 314 expect( | 314 expect( |
| 315 usWithWords.format(aDate), | 315 usWithWords.format(aDate), |
| 316 equals(r"12 / :D \ 27:59 ^&@ Jan")); | 316 equals(r"12 / :D \ 27:59 ^&@ Jan")); |
| 317 expect( | 317 expect( |
| 318 greekWithWords.format(aDate), | 318 greekWithWords.format(aDate), |
| 319 equals(r"12 / :D \ 27:59 ^&@ Ιαν")); | 319 equals(r"12 / :D \ 27:59 ^&@ Ιαν")); |
| 320 var escaped = new DateFormat(r"hh 'o''clock'"); | 320 var escaped = new DateFormat(r"hh 'o''clock'"); |
| 321 expect(escaped.format(aDate), equals(r"08 o'clock")); | 321 expect(escaped.format(aDate), equals(r"08 o'clock")); |
| 322 var reParsed = escaped.parse(escaped.format(aDate)); | 322 var reParsed = escaped.parse(escaped.format(aDate)); |
| 323 expect(escaped.format(reParsed), equals(escaped.format(aDate))); | 323 expect(escaped.format(reParsed), equals(escaped.format(aDate))); |
| 324 var noSeparators = new DateFormat('HHmmss'); | 324 var noSeparators = new DateFormat('HHmmss'); |
| 325 expect(noSeparators.format(aDate), equals("205859")); | 325 expect(noSeparators.format(aDate), equals("205859")); |
| 326 }); | 326 }); |
| 327 | 327 |
| 328 test('Test fractional seconds padding', () { | 328 test('Test fractional seconds padding', () { |
| 329 var one = new Date(2012, 1, 27, 20, 58, 59, 1); | 329 var one = new DateTime(2012, 1, 27, 20, 58, 59, 1); |
| 330 var oneHundred = new Date(2012, 1, 27, 20, 58, 59, 100); | 330 var oneHundred = new DateTime(2012, 1, 27, 20, 58, 59, 100); |
| 331 var fractional = new DateFormat('hh:mm:ss.SSS', 'en_US'); | 331 var fractional = new DateFormat('hh:mm:ss.SSS', 'en_US'); |
| 332 expect(fractional.format(one), equals('08:58:59.001')); | 332 expect(fractional.format(one), equals('08:58:59.001')); |
| 333 expect(fractional.format(oneHundred), equals('08:58:59.100')); | 333 expect(fractional.format(oneHundred), equals('08:58:59.100')); |
| 334 var long = new DateFormat('ss.SSSSSSSS', 'en_US'); | 334 var long = new DateFormat('ss.SSSSSSSS', 'en_US'); |
| 335 expect(long.format(oneHundred), equals('59.10000000')); | 335 expect(long.format(oneHundred), equals('59.10000000')); |
| 336 expect(long.format(one), equals('59.00100000')); | 336 expect(long.format(one), equals('59.00100000')); |
| 337 }); | 337 }); |
| 338 | 338 |
| 339 test('Test parseUTC', () { | 339 test('Test parseUTC', () { |
| 340 var local = new Date(2012, 1, 27, 20, 58, 59, 1); | 340 var local = new DateTime(2012, 1, 27, 20, 58, 59, 1); |
| 341 var utc = new Date.utc(2012, 1, 27, 20, 58, 59, 1); | 341 var utc = new DateTime.utc(2012, 1, 27, 20, 58, 59, 1); |
| 342 // Getting the offset as a duration via difference() would be simpler, | 342 // Getting the offset as a duration via difference() would be simpler, |
| 343 // but doesn't work on dart2js in checked mode. See issue 4437. | 343 // but doesn't work on dart2js in checked mode. See issue 4437. |
| 344 var offset = utc.millisecondsSinceEpoch - local.millisecondsSinceEpoch; | 344 var offset = utc.millisecondsSinceEpoch - local.millisecondsSinceEpoch; |
| 345 var format = new DateFormat('yyyy-MM-dd HH:mm:ss'); | 345 var format = new DateFormat('yyyy-MM-dd HH:mm:ss'); |
| 346 var localPrinted = format.format(local); | 346 var localPrinted = format.format(local); |
| 347 var parsed = format.parse(localPrinted); | 347 var parsed = format.parse(localPrinted); |
| 348 var parsedUTC = format.parseUTC(format.format(utc)); | 348 var parsedUTC = format.parseUTC(format.format(utc)); |
| 349 var parsedOffset = parsedUTC.millisecondsSinceEpoch | 349 var parsedOffset = parsedUTC.millisecondsSinceEpoch |
| 350 - parsed.millisecondsSinceEpoch; | 350 - parsed.millisecondsSinceEpoch; |
| 351 expect(parsedOffset, equals(offset)); | 351 expect(parsedOffset, equals(offset)); |
| 352 expect(utc.hour, equals(parsedUTC.hour)); | 352 expect(utc.hour, equals(parsedUTC.hour)); |
| 353 expect(local.hour, equals(parsed.hour)); | 353 expect(local.hour, equals(parsed.hour)); |
| 354 }); | 354 }); |
| 355 | 355 |
| 356 test('Test default format', () { | 356 test('Test default format', () { |
| 357 var someDate = new Date(2012, 1, 27, 20, 58, 59, 1); | 357 var someDate = new DateTime(2012, 1, 27, 20, 58, 59, 1); |
| 358 var emptyFormat = new DateFormat(null, "en_US"); | 358 var emptyFormat = new DateFormat(null, "en_US"); |
| 359 var knownDefault = new DateFormat.yMMMMd("en_US").add_jms(); | 359 var knownDefault = new DateFormat.yMMMMd("en_US").add_jms(); |
| 360 var result = emptyFormat.format(someDate); | 360 var result = emptyFormat.format(someDate); |
| 361 var knownResult = knownDefault.format(someDate); | 361 var knownResult = knownDefault.format(someDate); |
| 362 expect(result, knownResult); | 362 expect(result, knownResult); |
| 363 }); | 363 }); |
| 364 } | 364 } |
| OLD | NEW |