Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: sdk/lib/core/date_time.dart

Issue 629943002: Document DateTime.parse accepted format. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add test, fix bug. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/corelib/date_time_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/date_time_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698