Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 part of dart.core; | 5 part of dart.core; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * An instant in time, such as July 20, 1969, 8:18pm GMT. | 8 * An instant in time, such as July 20, 1969, 8:18pm GMT. |
| 9 * | 9 * |
| 10 * Create a DateTime object by using one of the constructors | 10 * Create a DateTime object by using one of the constructors |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 193 DateTime.now() : this._now(); | 193 DateTime.now() : this._now(); |
| 194 | 194 |
| 195 /** | 195 /** |
| 196 * Constructs a new [DateTime] instance based on [formattedString]. | 196 * Constructs a new [DateTime] instance based on [formattedString]. |
| 197 * | 197 * |
| 198 * Throws a [FormatException] if the input cannot be parsed. | 198 * Throws a [FormatException] if the input cannot be parsed. |
| 199 * | 199 * |
| 200 * The function parses a subset of ISO 8601 | 200 * The function parses a subset of ISO 8601 |
| 201 * which includes the subset accepted by RFC 3339. | 201 * which includes the subset accepted by RFC 3339. |
| 202 * | 202 * |
| 203 * The accepted inputs are currently: | |
| 204 * | |
| 205 * * A date: A signed four-to-six digit year, two digit month and | |
| 206 * two digit day, optionally separated by `-` characters. | |
| 207 * Examples: "19700101", "-0004-12-24", "81030-04-01". | |
| 208 * * An optional time part, separated from the date by either `T` or a space. | |
| 209 * The time part is a two digit hour, | |
| 210 * then optionally a two digit minutes value, | |
| 211 * then optionally a two digit seconds value, and | |
| 212 * then optionally a '.' followed by a one-to-six digit second fraction. | |
| 213 * The minuts and seconds may be separated from the previous parts by a ':'. | |
| 214 * Examples: "12", "12:30:24.124", "123010.50". | |
| 215 * * An optional time-zone offset part, | |
| 216 * possibly separated from the previous by a space. | |
| 217 * The time zone is either 'z' or 'Z', or it is a signed two digit hour | |
| 218 * part and an optional two digit minute part. | |
| 219 * The minutes may be separted from the hours by a ':'. | |
| 220 * Examples: "Z", "-10", "01:30", "1130". | |
| 221 * | |
| 222 * This includes the output of both [toString] and [toIso8601String], which | |
| 223 * will be parsed back into a `DateTime` object with the same time as the | |
| 224 * original. | |
| 225 * | |
| 203 * The result is always in either local time or UTC. | 226 * The result is always in either local time or UTC. |
| 204 * If a time zone offset other than UTC is specified, | 227 * If a time zone offset other than UTC is specified, |
| 205 * the time is converted to the equivalent UTC time. | 228 * the time is converted to the equivalent UTC time. |
| 206 * | 229 * |
| 207 * Examples of accepted strings: | 230 * Examples of accepted strings: |
| 208 * | 231 * |
| 209 * * `"2012-02-27 13:27:00"` | 232 * * `"2012-02-27 13:27:00"` |
| 210 * * `"2012-02-27 13:27:00.123456z"` | 233 * * `"2012-02-27 13:27:00.123456z"` |
| 211 * * `"20120227 13:27:00"` | 234 * * `"20120227 13:27:00"` |
| 212 * * `"20120227T132700"` | 235 * * `"20120227T132700"` |
| 213 * * `"20120227"` | 236 * * `"20120227"` |
| 214 * * `"+20120227"` | 237 * * `"+20120227"` |
| 215 * * `"2012-02-27T14Z"` | 238 * * `"2012-02-27T14Z"` |
| 216 * * `"2012-02-27T14+00:00"` | 239 * * `"2012-02-27T14+00:00"` |
| 217 * * `"-123450101 00:00:00 Z"`: in the year -12345. | 240 * * `"-123450101 00:00:00 Z"`: in the year -12345. |
| 218 * * `"2002-02-27T14:00:00-0500"`: Same as `"2002-02-27T19:00:00Z"` | 241 * * `"2002-02-27T14:00:00-0500"`: Same as `"2002-02-27T19:00:00Z"` |
| 219 */ | 242 */ |
| 220 // TODO(floitsch): specify grammar. | |
| 221 // TODO(lrn): restrict incorrect values like 2003-02-29T50:70:80. | 243 // TODO(lrn): restrict incorrect values like 2003-02-29T50:70:80. |
| 244 // Or not, that may be a breaking change. | |
| 222 static DateTime parse(String formattedString) { | 245 static DateTime parse(String formattedString) { |
| 223 /* | 246 /* |
| 224 * date ::= yeardate time_opt timezone_opt | 247 * date ::= yeardate time_opt timezone_opt |
| 225 * yeardate ::= year colon_opt month colon_opt day | 248 * yeardate ::= year colon_opt month colon_opt day |
| 226 * year ::= sign_opt digit{4,5} | 249 * year ::= sign_opt digit{4,6} |
| 227 * colon_opt :: <empty> | ':' | 250 * colon_opt :: <empty> | ':' |
| 228 * sign ::= '+' | '-' | 251 * sign ::= '+' | '-' |
| 229 * sign_opt ::= <empty> | sign | 252 * sign_opt ::= <empty> | sign |
| 230 * month ::= digit{2} | 253 * month ::= digit{2} |
| 231 * day ::= digit{2} | 254 * day ::= digit{2} |
| 232 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt | 255 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt |
| 233 * minutes_opt ::= <empty> | ':' digit{2} seconds_opt | 256 * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt |
| 234 * seconds_opt ::= <empty> | ':' digit{2} millis_opt | 257 * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt |
| 235 * millis_opt ::= <empty> | '.' digit{1,6} | 258 * millis_opt ::= <empty> | '.' digit{1,6} |
| 236 * timezone_opt ::= <empty> | space_opt timezone | 259 * timezone_opt ::= <empty> | space_opt timezone |
| 237 * space_opt :: ' ' | <empty> | 260 * space_opt :: ' ' | <empty> |
| 238 * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt | 261 * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt |
| 239 * timezonemins_opt ::= <empty> | colon_opt digit{2} | 262 * timezonemins_opt ::= <empty> | colon_opt digit{2} |
| 240 */ | 263 */ |
| 241 final RegExp re = new RegExp( | 264 final RegExp re = new RegExp( |
| 242 r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // The day part. | 265 r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // The day part. |
| 243 r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(.\d{1,6})?)?)?' // The time part | 266 r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(.\d{1,6})?)?)?' // The time part |
| 244 r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // The timezone part | 267 r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // The timezone part |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 * | 439 * |
| 417 * new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, | 440 * new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, |
| 418 * isUtc: true) | 441 * isUtc: true) |
| 419 */ | 442 */ |
| 420 DateTime toUtc() { | 443 DateTime toUtc() { |
| 421 if (isUtc) return this; | 444 if (isUtc) return this; |
| 422 return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, | 445 return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, |
| 423 isUtc: true); | 446 isUtc: true); |
| 424 } | 447 } |
| 425 | 448 |
| 426 static String _fourDigits(int n) { | 449 static String _fourDigits(int n) { |
|
Søren Gjesse
2014/10/06 10:12:47
assert [-9999, 9999] here (like in the six digit c
Lasse Reichstein Nielsen
2014/10/06 10:13:41
Can't, we are using it from the plain toString too
| |
| 427 int absN = n.abs(); | 450 int absN = n.abs(); |
| 428 String sign = n < 0 ? "-" : ""; | 451 String sign = n < 0 ? "-" : ""; |
| 429 if (absN >= 1000) return "$n"; | 452 if (absN >= 1000) return "$n"; |
| 430 if (absN >= 100) return "${sign}0$absN"; | 453 if (absN >= 100) return "${sign}0$absN"; |
| 431 if (absN >= 10) return "${sign}00$absN"; | 454 if (absN >= 10) return "${sign}00$absN"; |
| 432 return "${sign}000$absN"; | 455 return "${sign}000$absN"; |
| 433 } | 456 } |
| 434 | 457 |
| 458 static String _sixDigits(int n) { | |
| 459 assert(n < -9999 || n > 9999); | |
| 460 int absN = n.abs(); | |
| 461 String sign = n < 0 ? "-" : "+"; | |
| 462 if (absN >= 100000) return "$sign$absN"; | |
| 463 return "${sign}0$absN"; | |
| 464 } | |
| 465 | |
| 435 static String _threeDigits(int n) { | 466 static String _threeDigits(int n) { |
| 436 if (n >= 100) return "${n}"; | 467 if (n >= 100) return "${n}"; |
| 437 if (n >= 10) return "0${n}"; | 468 if (n >= 10) return "0${n}"; |
| 438 return "00${n}"; | 469 return "00${n}"; |
| 439 } | 470 } |
| 440 | 471 |
| 441 static String _twoDigits(int n) { | 472 static String _twoDigits(int n) { |
| 442 if (n >= 10) return "${n}"; | 473 if (n >= 10) return "${n}"; |
| 443 return "0${n}"; | 474 return "0${n}"; |
| 444 } | 475 } |
| 445 | 476 |
| 446 /** | 477 /** |
| 447 * Returns a human-readable string for this instance. | 478 * Returns a human-readable string for this instance. |
| 448 * | 479 * |
| 449 * The returned string is constructed for the time zone of this instance. | 480 * The returned string is constructed for the time zone of this instance. |
| 450 * The `toString()` method provides a simply formatted string. | 481 * The `toString()` method provides a simply formatted string. |
| 451 * It does not support internationalized strings. | 482 * It does not support internationalized strings. |
| 452 * Use the [intl](http://pub.dartlang.org/packages/intl) package | 483 * Use the [intl](http://pub.dartlang.org/packages/intl) package |
| 453 * at the pub shared packages repo. | 484 * at the pub shared packages repo. |
| 485 * | |
| 486 * The resulting string can be parsed back using [parse]. | |
| 454 */ | 487 */ |
| 455 String toString() { | 488 String toString() { |
| 456 String y = _fourDigits(year); | 489 String y = _fourDigits(year); |
| 457 String m = _twoDigits(month); | 490 String m = _twoDigits(month); |
| 458 String d = _twoDigits(day); | 491 String d = _twoDigits(day); |
| 459 String h = _twoDigits(hour); | 492 String h = _twoDigits(hour); |
| 460 String min = _twoDigits(minute); | 493 String min = _twoDigits(minute); |
| 461 String sec = _twoDigits(second); | 494 String sec = _twoDigits(second); |
| 462 String ms = _threeDigits(millisecond); | 495 String ms = _threeDigits(millisecond); |
| 463 if (isUtc) { | 496 if (isUtc) { |
| 464 return "$y-$m-$d $h:$min:$sec.${ms}Z"; | 497 return "$y-$m-$d $h:$min:$sec.${ms}Z"; |
| 465 } else { | 498 } else { |
| 466 return "$y-$m-$d $h:$min:$sec.$ms"; | 499 return "$y-$m-$d $h:$min:$sec.$ms"; |
| 467 } | 500 } |
| 468 } | 501 } |
| 469 | 502 |
| 470 /** | 503 /** |
| 471 * Returns an ISO-8601 full-precision extended format representation. | 504 * Returns an ISO-8601 full-precision extended format representation. |
| 472 * | 505 * |
| 473 * The format is "YYYY-MM-DDTHH:mm:ss.sssZ" for UTC time, and | 506 * The format is `yyyy-MM-ddTHH:mm:ss.sssZ` for UTC time, and |
| 474 * "YYYY-MM-DDTHH:mm:ss.sss" (no trailing "Z") for local/non-UTC time. | 507 * `yyyy-MM-ddTHH:mm:ss.sss` (no trailing "Z") for local/non-UTC time, |
| 508 * where: | |
| 509 * | |
| 510 * * `yyyy` is a, possibly negative, four digit representation of the year, | |
| 511 * if the year is in the range -9999 to 9999, | |
| 512 * otherwise it is a signed six digit representation of the year. | |
| 513 * * `MM` is the month in the range 01 to 12, | |
| 514 * * `dd` is the day of the month in the range 01 to 31, | |
| 515 * * `HH` are hours in the range 00 to 23, | |
| 516 * * `mm` are minutes in the range 00 to 59, | |
| 517 * * `ss` are seconds in the range 00 to 59 (no leap seconds), and | |
| 518 * * `sss` are milliseconds in the range 000 to 999. | |
| 519 * | |
| 520 * The resulting string can be parsed back using [parse]. | |
| 475 */ | 521 */ |
| 476 String toIso8601String() { | 522 String toIso8601String() { |
| 477 String y = _fourDigits(year); | 523 String y = (year >= -9999 && year <= 9999) ? _fourDigits(year) |
| 524 : _sixDigits(year); | |
| 478 String m = _twoDigits(month); | 525 String m = _twoDigits(month); |
| 479 String d = _twoDigits(day); | 526 String d = _twoDigits(day); |
| 480 String h = _twoDigits(hour); | 527 String h = _twoDigits(hour); |
| 481 String min = _twoDigits(minute); | 528 String min = _twoDigits(minute); |
| 482 String sec = _twoDigits(second); | 529 String sec = _twoDigits(second); |
| 483 String ms = _threeDigits(millisecond); | 530 String ms = _threeDigits(millisecond); |
| 484 if (isUtc) { | 531 if (isUtc) { |
| 485 return "$y-$m-${d}T$h:$min:$sec.${ms}Z"; | 532 return "$y-$m-${d}T$h:$min:$sec.${ms}Z"; |
| 486 } else { | 533 } else { |
| 487 return "$y-$m-${d}T$h:$min:$sec.$ms"; | 534 return "$y-$m-${d}T$h:$min:$sec.$ms"; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 * In accordance with ISO 8601 | 671 * In accordance with ISO 8601 |
| 625 * a week starts with Monday, which has the value 1. | 672 * a week starts with Monday, which has the value 1. |
| 626 * | 673 * |
| 627 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | 674 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); |
| 628 * assert(moonLanding.weekday == 7); | 675 * assert(moonLanding.weekday == 7); |
| 629 * assert(moonLanding.weekday == DateTime.SUNDAY); | 676 * assert(moonLanding.weekday == DateTime.SUNDAY); |
| 630 * | 677 * |
| 631 */ | 678 */ |
| 632 external int get weekday; | 679 external int get weekday; |
| 633 } | 680 } |
| OLD | NEW |