| 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 * DateFormat is for formatting and parsing dates in a locale-sensitive | 6 * DateFormat is for formatting and parsing dates in a locale-sensitive |
| 7 * manner. | 7 * manner. |
| 8 * It allows the user to choose from a set of standard date time formats as well | 8 * It allows the user to choose from a set of standard date time formats as well |
| 9 * as specify a customized pattern under certain locales. Date elements that | 9 * as specify a customized pattern under certain locales. Date elements that |
| 10 * vary across locales include month name, week name, field order, etc. | 10 * vary across locales include month name, week name, field order, etc. |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 * Given user input, attempt to parse the [inputString] into the anticipated | 244 * Given user input, attempt to parse the [inputString] into the anticipated |
| 245 * format, treating it as being in UTC. | 245 * format, treating it as being in UTC. |
| 246 */ | 246 */ |
| 247 Date parseUTC(String inputString) { | 247 Date parseUTC(String inputString) { |
| 248 return parse(inputString, true); | 248 return parse(inputString, true); |
| 249 } | 249 } |
| 250 | 250 |
| 251 /** | 251 /** |
| 252 * Return the locale code in which we operate, e.g. 'en_US' or 'pt'. | 252 * Return the locale code in which we operate, e.g. 'en_US' or 'pt'. |
| 253 */ | 253 */ |
| 254 String get locale() => _locale; | 254 String get locale => _locale; |
| 255 | 255 |
| 256 /** | 256 /** |
| 257 * Returns a list of all locales for which we have date formatting | 257 * Returns a list of all locales for which we have date formatting |
| 258 * information. | 258 * information. |
| 259 */ | 259 */ |
| 260 static List<String> allLocalesWithSymbols() => dateTimeSymbols.getKeys(); | 260 static List<String> allLocalesWithSymbols() => dateTimeSymbols.getKeys(); |
| 261 | 261 |
| 262 /** | 262 /** |
| 263 * Constructors for a set of predefined formats for which | 263 * Constructors for a set of predefined "skeletons" for which the |
| 264 * internationalized forms are known. These can be specified | 264 * internationalized forms are known. These can also be chained |
| 265 * either as ICU constants, or as skeletons. | 265 * together using the "add_" instance methods below. |
| 266 */ | 266 */ |
| 267 DateFormat.DAY([locale]) : this(DAY, locale); | |
| 268 DateFormat.ABBR_WEEKDAY([locale]) : this(ABBR_WEEKDAY, locale); | |
| 269 DateFormat.WEEKDAY([locale]) : this(WEEKDAY, locale); | |
| 270 DateFormat.ABBR_STANDALONE_MONTH([locale]) : | |
| 271 this(ABBR_STANDALONE_MONTH, locale); | |
| 272 DateFormat.STANDALONE_MONTH([locale]) : this(STANDALONE_MONTH, locale); | |
| 273 DateFormat.NUM_MONTH([locale]) : this(NUM_MONTH, locale); | |
| 274 DateFormat.NUM_MONTH_DAY([locale]) : this(NUM_MONTH_DAY, locale); | |
| 275 DateFormat.NUM_MONTH_WEEKDAY_DAY([locale]) : | |
| 276 this(NUM_MONTH_WEEKDAY_DAY, locale); | |
| 277 DateFormat.ABBR_MONTH([locale]) : this(ABBR_MONTH, locale); | |
| 278 DateFormat.ABBR_MONTH_DAY([locale]) : this(ABBR_MONTH_DAY, locale); | |
| 279 DateFormat.ABBR_MONTH_WEEKDAY_DAY([locale]) : | |
| 280 this(ABBR_MONTH_WEEKDAY_DAY, locale); | |
| 281 DateFormat.MONTH([locale]) : this(MONTH, locale); | |
| 282 DateFormat.MONTH_DAY([locale]) : this(MONTH_DAY, locale); | |
| 283 DateFormat.MONTH_WEEKDAY_DAY([locale]) : this(MONTH_WEEKDAY_DAY, locale); | |
| 284 DateFormat.ABBR_QUARTER([locale]) : this(ABBR_QUARTER, locale); | |
| 285 DateFormat.QUARTER([locale]) : this(QUARTER, locale); | |
| 286 DateFormat.YEAR([locale]) : this(YEAR, locale); | |
| 287 DateFormat.YEAR_NUM_MONTH([locale]) : this(YEAR_NUM_MONTH, locale); | |
| 288 DateFormat.YEAR_NUM_MONTH_DAY([locale]) : this(YEAR_NUM_MONTH_DAY, locale); | |
| 289 DateFormat.YEAR_NUM_MONTH_WEEKDAY_DAY([locale]) : | |
| 290 this(YEAR_NUM_MONTH_WEEKDAY_DAY, locale); | |
| 291 DateFormat.YEAR_ABBR_MONTH([locale]) : this(YEAR_ABBR_MONTH, locale); | |
| 292 DateFormat.YEAR_ABBR_MONTH_DAY([locale]) : this(YEAR_ABBR_MONTH_DAY, locale); | |
| 293 DateFormat.YEAR_ABBR_MONTH_WEEKDAY_DAY([locale]) : | |
| 294 this(YEAR_ABBR_MONTH_WEEKDAY_DAY, locale); | |
| 295 DateFormat.YEAR_MONTH([locale]) : this(YEAR_MONTH, locale); | |
| 296 DateFormat.YEAR_MONTH_DAY([locale]) : this(YEAR_MONTH_DAY, locale); | |
| 297 DateFormat.YEAR_MONTH_WEEKDAY_DAY([locale]) : | |
| 298 this(YEAR_MONTH_WEEKDAY_DAY, locale); | |
| 299 DateFormat.YEAR_ABBR_QUARTER([locale]) : this(YEAR_ABBR_QUARTER, locale); | |
| 300 DateFormat.YEAR_QUARTER([locale]) : this(YEAR_QUARTER, locale); | |
| 301 DateFormat.HOUR24([locale]) : this(HOUR24, locale); | |
| 302 DateFormat.HOUR24_MINUTE([locale]) : this(HOUR24_MINUTE, locale); | |
| 303 DateFormat.HOUR24_MINUTE_SECOND([locale]) : | |
| 304 this(HOUR24_MINUTE_SECOND, locale); | |
| 305 DateFormat.HOUR([locale]) : this(HOUR, locale); | |
| 306 DateFormat.HOUR_MINUTE([locale]) : this(HOUR_MINUTE, locale); | |
| 307 DateFormat.HOUR_MINUTE_SECOND([locale]) : this(HOUR_MINUTE_SECOND, locale); | |
| 308 DateFormat.HOUR_MINUTE_GENERIC_TZ([locale]) : | |
| 309 this(HOUR_MINUTE_GENERIC_TZ, locale); | |
| 310 DateFormat.HOUR_MINUTE_TZ([locale]) : this(HOUR_MINUTE_TZ, locale); | |
| 311 DateFormat.HOUR_GENERIC_TZ([locale]) : this(HOUR_GENERIC_TZ, locale); | |
| 312 DateFormat.HOUR_TZ([locale]) : this(HOUR_TZ, locale); | |
| 313 DateFormat.MINUTE([locale]) : this(MINUTE, locale); | |
| 314 DateFormat.MINUTE_SECOND([locale]) : this(MINUTE_SECOND, locale); | |
| 315 DateFormat.SECOND([locale]) : this(SECOND, locale); | |
| 316 | |
| 317 DateFormat.d([locale]) : this("d", locale); | 267 DateFormat.d([locale]) : this("d", locale); |
| 318 DateFormat.E([locale]) : this("E", locale); | 268 DateFormat.E([locale]) : this("E", locale); |
| 319 DateFormat.EEEE([locale]) : this("EEEE", locale); | 269 DateFormat.EEEE([locale]) : this("EEEE", locale); |
| 320 DateFormat.LLL([locale]) : this("LLL", locale); | 270 DateFormat.LLL([locale]) : this("LLL", locale); |
| 321 DateFormat.LLLL([locale]) : this("LLLL", locale); | 271 DateFormat.LLLL([locale]) : this("LLLL", locale); |
| 322 DateFormat.M([locale]) : this("M", locale); | 272 DateFormat.M([locale]) : this("M", locale); |
| 323 DateFormat.Md([locale]) : this("Md", locale); | 273 DateFormat.Md([locale]) : this("Md", locale); |
| 324 DateFormat.MEd([locale]) : this("MEd", locale); | 274 DateFormat.MEd([locale]) : this("MEd", locale); |
| 325 DateFormat.MMM([locale]) : this("MMM", locale); | 275 DateFormat.MMM([locale]) : this("MMM", locale); |
| 326 DateFormat.MMMd([locale]) : this("MMMd", locale); | 276 DateFormat.MMMd([locale]) : this("MMMd", locale); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 353 DateFormat.jv([locale]) : this("jv", locale); | 303 DateFormat.jv([locale]) : this("jv", locale); |
| 354 DateFormat.jz([locale]) : this("jz", locale); | 304 DateFormat.jz([locale]) : this("jz", locale); |
| 355 DateFormat.m([locale]) : this("m", locale); | 305 DateFormat.m([locale]) : this("m", locale); |
| 356 DateFormat.ms([locale]) : this("ms", locale); | 306 DateFormat.ms([locale]) : this("ms", locale); |
| 357 DateFormat.s([locale]) : this("s", locale); | 307 DateFormat.s([locale]) : this("s", locale); |
| 358 | 308 |
| 359 /** | 309 /** |
| 360 * Methods for appending a particular skeleton to the format, or setting | 310 * Methods for appending a particular skeleton to the format, or setting |
| 361 * it as the only format if none was previously set. These are primarily | 311 * it as the only format if none was previously set. These are primarily |
| 362 * useful for creating compound formats. For example | 312 * useful for creating compound formats. For example |
| 363 * new DateFormat.yMd().hms(); | 313 * new DateFormat.yMd().add_hms(); |
| 364 * would create a date format that prints both the date and the time. | 314 * would create a date format that prints both the date and the time. |
| 365 */ | 315 */ |
| 366 DateFormat d() => addPattern("d"); | 316 DateFormat add_d() => addPattern("d"); |
| 367 DateFormat E() => addPattern("E"); | 317 DateFormat add_E() => addPattern("E"); |
| 368 DateFormat EEEE() => addPattern("EEEE"); | 318 DateFormat add_EEEE() => addPattern("EEEE"); |
| 369 DateFormat LLL() => addPattern("LLL"); | 319 DateFormat add_LLL() => addPattern("LLL"); |
| 370 DateFormat LLLL() => addPattern("LLLL"); | 320 DateFormat add_LLLL() => addPattern("LLLL"); |
| 371 DateFormat M() => addPattern("M"); | 321 DateFormat add_M() => addPattern("M"); |
| 372 DateFormat Md() => addPattern("Md"); | 322 DateFormat add_Md() => addPattern("Md"); |
| 373 DateFormat MEd() => addPattern("MEd"); | 323 DateFormat add_MEd() => addPattern("MEd"); |
| 374 DateFormat MMM() => addPattern("MMM"); | 324 DateFormat add_MMM() => addPattern("MMM"); |
| 375 DateFormat MMMd() => addPattern("MMMd"); | 325 DateFormat add_MMMd() => addPattern("MMMd"); |
| 376 DateFormat MMMEd() => addPattern("MMMEd"); | 326 DateFormat add_MMMEd() => addPattern("MMMEd"); |
| 377 DateFormat MMMM() => addPattern("MMMM"); | 327 DateFormat add_MMMM() => addPattern("MMMM"); |
| 378 DateFormat MMMMd() => addPattern("MMMMd"); | 328 DateFormat add_MMMMd() => addPattern("MMMMd"); |
| 379 DateFormat MMMMEEEEd() => addPattern("MMMMEEEEd"); | 329 DateFormat add_MMMMEEEEd() => addPattern("MMMMEEEEd"); |
| 380 DateFormat QQQ() => addPattern("QQQ"); | 330 DateFormat add_QQQ() => addPattern("QQQ"); |
| 381 DateFormat QQQQ() => addPattern("QQQQ"); | 331 DateFormat add_QQQQ() => addPattern("QQQQ"); |
| 382 DateFormat y() => addPattern("y"); | 332 DateFormat add_y() => addPattern("y"); |
| 383 DateFormat yM() => addPattern("yM"); | 333 DateFormat add_yM() => addPattern("yM"); |
| 384 DateFormat yMd() => addPattern("yMd"); | 334 DateFormat add_yMd() => addPattern("yMd"); |
| 385 DateFormat yMEd() => addPattern("yMEd"); | 335 DateFormat add_yMEd() => addPattern("yMEd"); |
| 386 DateFormat yMMM() => addPattern("yMMM"); | 336 DateFormat add_yMMM() => addPattern("yMMM"); |
| 387 DateFormat yMMMd() => addPattern("yMMMd"); | 337 DateFormat add_yMMMd() => addPattern("yMMMd"); |
| 388 DateFormat yMMMEd() => addPattern("yMMMEd"); | 338 DateFormat add_yMMMEd() => addPattern("yMMMEd"); |
| 389 DateFormat yMMMM() => addPattern("yMMMM"); | 339 DateFormat add_yMMMM() => addPattern("yMMMM"); |
| 390 DateFormat yMMMMd() => addPattern("yMMMMd"); | 340 DateFormat add_yMMMMd() => addPattern("yMMMMd"); |
| 391 DateFormat yMMMMEEEEd() => addPattern("yMMMMEEEEd"); | 341 DateFormat add_yMMMMEEEEd() => addPattern("yMMMMEEEEd"); |
| 392 DateFormat yQQQ() => addPattern("yQQQ"); | 342 DateFormat add_yQQQ() => addPattern("yQQQ"); |
| 393 DateFormat yQQQQ() => addPattern("yQQQQ"); | 343 DateFormat add_yQQQQ() => addPattern("yQQQQ"); |
| 394 DateFormat H() => addPattern("H"); | 344 DateFormat add_H() => addPattern("H"); |
| 395 DateFormat Hm() => addPattern("Hm"); | 345 DateFormat add_Hm() => addPattern("Hm"); |
| 396 DateFormat Hms() => addPattern("Hms"); | 346 DateFormat add_Hms() => addPattern("Hms"); |
| 397 DateFormat j() => addPattern("j"); | 347 DateFormat add_j() => addPattern("j"); |
| 398 DateFormat jm() => addPattern("jm"); | 348 DateFormat add_jm() => addPattern("jm"); |
| 399 DateFormat jms() => addPattern("jms"); | 349 DateFormat add_jms() => addPattern("jms"); |
| 400 DateFormat jmv() => addPattern("jmv"); | 350 DateFormat add_jmv() => addPattern("jmv"); |
| 401 DateFormat jmz() => addPattern("jmz"); | 351 DateFormat add_jmz() => addPattern("jmz"); |
| 402 DateFormat jv() => addPattern("jv"); | 352 DateFormat add_jv() => addPattern("jv"); |
| 403 DateFormat jz() => addPattern("jz"); | 353 DateFormat add_jz() => addPattern("jz"); |
| 404 DateFormat m() => addPattern("m"); | 354 DateFormat add_m() => addPattern("m"); |
| 405 DateFormat ms() => addPattern("ms"); | 355 DateFormat add_ms() => addPattern("ms"); |
| 406 DateFormat s() => addPattern("s"); | 356 DateFormat add_s() => addPattern("s"); |
| 407 | 357 |
| 408 /** | 358 /** |
| 409 * ICU constants for format names, resolving to the corresponding skeletons. | 359 * ICU constants for format names, resolving to the corresponding skeletons. |
| 410 */ | 360 */ |
| 411 static const String DAY = 'd'; | 361 static const String DAY = 'd'; |
| 412 static const String ABBR_WEEKDAY = 'E'; | 362 static const String ABBR_WEEKDAY = 'E'; |
| 413 static const String WEEKDAY = 'EEEE'; | 363 static const String WEEKDAY = 'EEEE'; |
| 414 static const String ABBR_STANDALONE_MONTH = 'LLL'; | 364 static const String ABBR_STANDALONE_MONTH = 'LLL'; |
| 415 static const String STANDALONE_MONTH = 'LLLL'; | 365 static const String STANDALONE_MONTH = 'LLLL'; |
| 416 static const String NUM_MONTH = 'M'; | 366 static const String NUM_MONTH = 'M'; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 /** | 413 /** |
| 464 * We parse the format string into individual [_DateFormatField] objects | 414 * We parse the format string into individual [_DateFormatField] objects |
| 465 * that are used to do the actual formatting and parsing. Do not use | 415 * that are used to do the actual formatting and parsing. Do not use |
| 466 * this variable directly, use the getter [_formatFields]. | 416 * this variable directly, use the getter [_formatFields]. |
| 467 */ | 417 */ |
| 468 List<_DateFormatField> _formatFieldsPrivate; | 418 List<_DateFormatField> _formatFieldsPrivate; |
| 469 | 419 |
| 470 /** | 420 /** |
| 471 * Getter for [_formatFieldsPrivate] that lazily initializes it. | 421 * Getter for [_formatFieldsPrivate] that lazily initializes it. |
| 472 */ | 422 */ |
| 473 get _formatFields() { | 423 get _formatFields { |
| 474 if (_formatFieldsPrivate == null) { | 424 if (_formatFieldsPrivate == null) { |
| 475 _formatFieldsPrivate = parsePattern(_pattern); | 425 _formatFieldsPrivate = parsePattern(_pattern); |
| 476 } | 426 } |
| 477 return _formatFieldsPrivate; | 427 return _formatFieldsPrivate; |
| 478 } | 428 } |
| 479 | 429 |
| 480 /** | 430 /** |
| 481 * A series of regular expressions used to parse a format string into its | 431 * A series of regular expressions used to parse a format string into its |
| 482 * component fields. | 432 * component fields. |
| 483 */ | 433 */ |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 _setPattern(inputPattern, separator); | 473 _setPattern(inputPattern, separator); |
| 524 } else { | 474 } else { |
| 525 _setPattern(_availableSkeletons[inputPattern], separator); | 475 _setPattern(_availableSkeletons[inputPattern], separator); |
| 526 } | 476 } |
| 527 // If we have already parsed the format fields, reset them. | 477 // If we have already parsed the format fields, reset them. |
| 528 _formatFieldsPrivate = null; | 478 _formatFieldsPrivate = null; |
| 529 return this; | 479 return this; |
| 530 } | 480 } |
| 531 | 481 |
| 532 /** Return the pattern that we use to format dates.*/ | 482 /** Return the pattern that we use to format dates.*/ |
| 533 get pattern() => _pattern; | 483 get pattern => _pattern; |
| 534 | 484 |
| 535 /** Return the skeletons for our current locale. */ | 485 /** Return the skeletons for our current locale. */ |
| 536 Map get _availableSkeletons() { | 486 Map get _availableSkeletons { |
| 537 return dateTimePatterns[locale]; | 487 return dateTimePatterns[locale]; |
| 538 } | 488 } |
| 539 | 489 |
| 540 /** | 490 /** |
| 541 * Set the locale. If the locale can't be found, we also look up | 491 * Set the locale. If the locale can't be found, we also look up |
| 542 * based on alternative versions, e.g. if we have no 'en_CA' we will | 492 * based on alternative versions, e.g. if we have no 'en_CA' we will |
| 543 * look for 'en' as a fallback. It will also translate en-ca into en_CA. | 493 * look for 'en' as a fallback. It will also translate en-ca into en_CA. |
| 544 * Null is also considered a valid value for [newLocale], indicating | 494 * Null is also considered a valid value for [newLocale], indicating |
| 545 * to use the default. | 495 * to use the default. |
| 546 */ | 496 */ |
| 547 _setLocale(String newLocale) { | 497 _setLocale(String newLocale) { |
| 548 _locale = Intl.verifiedLocale(newLocale); | 498 _locale = Intl.verifiedLocale(newLocale); |
| 549 } | 499 } |
| 550 | 500 |
| 551 /** | 501 /** |
| 552 * Return true if the locale exists, or if it is null. The null case | 502 * Return true if the locale exists, or if it is null. The null case |
| 553 * is interpreted to mean that we use the default locale. | 503 * is interpreted to mean that we use the default locale. |
| 554 */ | 504 */ |
| 555 static bool localeExists(localeName) { | 505 static bool localeExists(localeName) { |
| 556 if (localeName == null) return false; | 506 if (localeName == null) return false; |
| 557 return dateTimeSymbols.containsKey(localeName); | 507 return dateTimeSymbols.containsKey(localeName); |
| 558 } | 508 } |
| 559 | 509 |
| 560 // TODO(alanknight): This can be a variable once that's permitted. | 510 // TODO(alanknight): This can be a variable once that's permitted. |
| 561 static List get _fieldConstructors() => [ | 511 static List get _fieldConstructors => [ |
| 562 (pattern, parent) => new _DateFormatQuotedField(pattern, parent), | 512 (pattern, parent) => new _DateFormatQuotedField(pattern, parent), |
| 563 (pattern, parent) => new _DateFormatPatternField(pattern, parent), | 513 (pattern, parent) => new _DateFormatPatternField(pattern, parent), |
| 564 (pattern, parent) => new _DateFormatLiteralField(pattern, parent)]; | 514 (pattern, parent) => new _DateFormatLiteralField(pattern, parent)]; |
| 565 | 515 |
| 566 /** Parse the template pattern and return a list of field objects.*/ | 516 /** Parse the template pattern and return a list of field objects.*/ |
| 567 List parsePattern(String pattern) { | 517 List parsePattern(String pattern) { |
| 568 if (pattern == null) return null; | 518 if (pattern == null) return null; |
| 569 return _reverse(_parsePatternHelper(pattern)); | 519 return _reverse(_parsePatternHelper(pattern)); |
| 570 } | 520 } |
| 571 | 521 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 597 List _reverse(List list) { | 547 List _reverse(List list) { |
| 598 // TODO(alanknight): Use standardized list reverse when implemented. | 548 // TODO(alanknight): Use standardized list reverse when implemented. |
| 599 // See Issue 2804. | 549 // See Issue 2804. |
| 600 var result = new List(); | 550 var result = new List(); |
| 601 for (var i = list.length-1; i >= 0; i--) { | 551 for (var i = list.length-1; i >= 0; i--) { |
| 602 result.addLast(list[i]); | 552 result.addLast(list[i]); |
| 603 } | 553 } |
| 604 return result; | 554 return result; |
| 605 } | 555 } |
| 606 } | 556 } |
| OLD | NEW |