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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 * | 75 * |
| 76 * DateTime today = new DateTime.now(); | 76 * DateTime today = new DateTime.now(); |
| 77 * DateTime sixtyDaysFromNow = today.add(new Duration(days: 60)); | 77 * DateTime sixtyDaysFromNow = today.add(new Duration(days: 60)); |
| 78 * | 78 * |
| 79 * To find out how much time is between two DateTime objects use | 79 * To find out how much time is between two DateTime objects use |
| 80 * [difference], which returns a [Duration] object: | 80 * [difference], which returns a [Duration] object: |
| 81 * | 81 * |
| 82 * Duration difference = berlinWallFell.difference(moonLanding) | 82 * Duration difference = berlinWallFell.difference(moonLanding) |
| 83 * assert(difference.inDays == 7416); | 83 * assert(difference.inDays == 7416); |
| 84 * | 84 * |
| 85 * The difference between two dates in different time zones | |
| 86 * is just the number of nanoseconds between the two points in time. | |
| 87 * It doesn't take calendar days into account. | |
| 88 * That means that the difference between two midnights in local time may be | |
| 89 * less than 24 hours times the number of days between them, | |
| 90 * if there is a daylight saving change in between. | |
| 91 * If the difference above is calculated using Australian local time, the | |
| 92 * difference is 7415 days and 23 hours, which is only 7415 whole days as | |
| 93 * reported by `inDays`. | |
| 94 * | |
| 85 * ## Other resources | 95 * ## Other resources |
| 86 * | 96 * |
| 87 * See [Duration] to represent a span of time. | 97 * See [Duration] to represent a span of time. |
| 88 * See [Stopwatch] to measure timespans. | 98 * See [Stopwatch] to measure timespans. |
| 89 * | 99 * |
| 90 * The DateTime class does not provide internationalization. | 100 * The DateTime class does not provide internationalization. |
| 91 * To internationalize your code, use | 101 * To internationalize your code, use |
| 92 * the [intl](http://pub.dartlang.org/packages/intl) package. | 102 * the [intl](http://pub.dartlang.org/packages/intl) package. |
| 93 * | 103 * |
| 94 */ | 104 */ |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 final bool isUtc; | 151 final bool isUtc; |
| 142 | 152 |
| 143 /** | 153 /** |
| 144 * Constructs a [DateTime] instance specified in the local time zone. | 154 * Constructs a [DateTime] instance specified in the local time zone. |
| 145 * | 155 * |
| 146 * For example, | 156 * For example, |
| 147 * to create a new DateTime object representing April 29, 2014, 6:04am: | 157 * to create a new DateTime object representing April 29, 2014, 6:04am: |
| 148 * | 158 * |
| 149 * DateTime annularEclipse = new DateTime(2014, DateTime.APRIL, 29, 6, 4); | 159 * DateTime annularEclipse = new DateTime(2014, DateTime.APRIL, 29, 6, 4); |
| 150 */ | 160 */ |
| 151 // TODO(8042): This should be a redirecting constructor and not a factory. | 161 DateTime(int year, |
| 152 factory DateTime(int year, | |
| 153 [int month = 1, | 162 [int month = 1, |
| 154 int day = 1, | 163 int day = 1, |
| 155 int hour = 0, | 164 int hour = 0, |
| 156 int minute = 0, | 165 int minute = 0, |
| 157 int second = 0, | 166 int second = 0, |
| 158 int millisecond = 0]) { | 167 int millisecond = 0]) |
| 159 return new DateTime._internal( | 168 : this._internal( |
|
Lasse Reichstein Nielsen
2014/02/17 11:24:10
Reverting this change since 8042 isn't fixed yet.
Lasse Reichstein Nielsen
2014/02/19 13:11:28
It's fixed now. Thank you Johnni.
| |
| 160 year, month, day, hour, minute, second, millisecond, false); | 169 year, month, day, hour, minute, second, millisecond, false); |
| 161 } | |
| 162 | 170 |
| 163 /** | 171 /** |
| 164 * Constructs a [DateTime] instance specified in the UTC time zone. | 172 * Constructs a [DateTime] instance specified in the UTC time zone. |
| 165 * | 173 * |
| 166 * DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6); | 174 * DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6); |
| 167 */ | 175 */ |
| 168 // TODO(8042): This should be a redirecting constructor and not a factory. | 176 DateTime.utc(int year, |
| 169 factory DateTime.utc(int year, | 177 [int month = 1, |
| 170 [int month = 1, | 178 int day = 1, |
| 171 int day = 1, | 179 int hour = 0, |
| 172 int hour = 0, | 180 int minute = 0, |
| 173 int minute = 0, | 181 int second = 0, |
| 174 int second = 0, | 182 int millisecond = 0]) |
| 175 int millisecond = 0]) { | 183 : this._internal( |
| 176 return new DateTime._internal( | |
| 177 year, month, day, hour, minute, second, millisecond, true); | 184 year, month, day, hour, minute, second, millisecond, true); |
| 178 } | |
| 179 | 185 |
| 180 /** | 186 /** |
| 181 * Constructs a [DateTime] instance with current date and time in the | 187 * Constructs a [DateTime] instance with current date and time in the |
| 182 * local time zone. | 188 * local time zone. |
| 183 * | 189 * |
| 184 * DateTime thisInstant = new DateTime.now(); | 190 * DateTime thisInstant = new DateTime.now(); |
| 185 * | 191 * |
| 186 */ | 192 */ |
| 187 // TODO(8042): This should be a redirecting constructor and not a factory. | 193 DateTime.now() : this._now(); |
| 188 factory DateTime.now() { return new DateTime._now(); } | |
| 189 | 194 |
| 190 /** | 195 /** |
| 191 * Constructs a new [DateTime] instance based on [formattedString]. | 196 * Constructs a new [DateTime] instance based on [formattedString]. |
| 192 * | 197 * |
| 193 * Throws a [FormatException] if the input cannot be parsed. | 198 * Throws a [FormatException] if the input cannot be parsed. |
| 194 * | 199 * |
| 195 * The function parses a subset of ISO 8601. Examples of accepted strings: | 200 * The function parses a subset of ISO 8601 |
| 201 * which includes the subset accepted by RFC 3339. | |
| 202 * | |
| 203 * The result is always in either local time or UTC. | |
| 204 * If a time zone offset other than UTC is specified, | |
| 205 * the time is converted to the equivalent UTC time. | |
| 206 * | |
| 207 * Examples of accepted strings: | |
| 196 * | 208 * |
| 197 * * `"2012-02-27 13:27:00"` | 209 * * `"2012-02-27 13:27:00"` |
| 198 * * `"2012-02-27 13:27:00.123456z"` | 210 * * `"2012-02-27 13:27:00.123456z"` |
| 199 * * `"20120227 13:27:00"` | 211 * * `"20120227 13:27:00"` |
| 200 * * `"20120227T132700"` | 212 * * `"20120227T132700"` |
| 201 * * `"20120227"` | 213 * * `"20120227"` |
| 202 * * `"+20120227"` | 214 * * `"+20120227"` |
| 203 * * `"2012-02-27T14Z"` | 215 * * `"2012-02-27T14Z"` |
| 204 * * `"2012-02-27T14+00:00"` | 216 * * `"2012-02-27T14+00:00"` |
| 205 * * `"-123450101 00:00:00 Z"`: in the year -12345. | 217 * * `"-123450101 00:00:00 Z"`: in the year -12345. |
| 218 * * `"2002-02-27T14:00:00-0500"`: Same as `"2002-02-27T19:00:00Z"` | |
| 206 */ | 219 */ |
| 207 // TODO(floitsch): specify grammar. | 220 // TODO(floitsch): specify grammar. |
| 221 // TODO(lrn): restrict incorrect values like 2003-02-29T50:70:80. | |
| 208 static DateTime parse(String formattedString) { | 222 static DateTime parse(String formattedString) { |
| 209 /* | 223 /* |
| 210 * date ::= yeardate time_opt timezone_opt | 224 * date ::= yeardate time_opt timezone_opt |
| 211 * yeardate ::= year colon_opt month colon_opt day | 225 * yeardate ::= year colon_opt month colon_opt day |
| 212 * year ::= sign_opt digit{4,5} | 226 * year ::= sign_opt digit{4,5} |
| 213 * colon_opt :: <empty> | ':' | 227 * colon_opt :: <empty> | ':' |
| 214 * sign_opt ::= <empty> | '+' | '-' | 228 * sign ::= '+' | '-' |
| 229 * sign_opt ::= <empty> | sign | |
| 215 * month ::= digit{2} | 230 * month ::= digit{2} |
| 216 * day ::= digit{2} | 231 * day ::= digit{2} |
| 217 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt | 232 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt |
| 218 * minutes_opt ::= <empty> | ':' digit{2} seconds_opt | 233 * minutes_opt ::= <empty> | ':' digit{2} seconds_opt |
| 219 * seconds_opt ::= <empty> | ':' digit{2} millis_opt | 234 * seconds_opt ::= <empty> | ':' digit{2} millis_opt |
| 220 * millis_opt ::= <empty> | '.' digit{1,6} | 235 * millis_opt ::= <empty> | '.' digit{1,6} |
| 221 * timezone_opt ::= <empty> | space_opt timezone | 236 * timezone_opt ::= <empty> | space_opt timezone |
| 222 * space_opt :: ' ' | <empty> | 237 * space_opt :: ' ' | <empty> |
| 223 * timezone ::= 'z' | 'Z' | '+' '0' '0' timezonemins_opt | 238 * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt |
| 224 * timezonemins_opt ::= <empty> | colon_opt '0' '0' | 239 * timezonemins_opt ::= <empty> | colon_opt digit{2} |
| 225 */ | 240 */ |
| 226 final RegExp re = new RegExp( | 241 final RegExp re = new RegExp( |
| 227 r'^([+-]?\d?\d\d\d\d)-?(\d\d)-?(\d\d)' // The day part. | 242 r'^([+-]?\d{4,5})-?(\d\d)-?(\d\d)' // The day part. |
| 228 r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(.\d{1,6})?)?)?' // The time part | 243 r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(.\d{1,6})?)?)?' // The time part |
| 229 r'( ?[zZ]| ?\+00(?::?00)?)?)?$'); // The timezone part | 244 r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // The timezone part |
| 230 | 245 |
| 231 Match match = re.firstMatch(formattedString); | 246 Match match = re.firstMatch(formattedString); |
| 232 if (match != null) { | 247 if (match != null) { |
| 233 int parseIntOrZero(String matched) { | 248 int parseIntOrZero(String matched) { |
| 234 if (matched == null) return 0; | 249 if (matched == null) return 0; |
| 235 return int.parse(matched); | 250 return int.parse(matched); |
| 236 } | 251 } |
| 237 | 252 |
| 238 double parseDoubleOrZero(String matched) { | 253 double parseDoubleOrZero(String matched) { |
| 239 if (matched == null) return 0.0; | 254 if (matched == null) return 0.0; |
| 240 return double.parse(matched); | 255 return double.parse(matched); |
| 241 } | 256 } |
| 242 | 257 |
| 243 int years = int.parse(match[1]); | 258 int years = int.parse(match[1]); |
| 244 int month = int.parse(match[2]); | 259 int month = int.parse(match[2]); |
| 245 int day = int.parse(match[3]); | 260 int day = int.parse(match[3]); |
| 246 int hour = parseIntOrZero(match[4]); | 261 int hour = parseIntOrZero(match[4]); |
| 247 int minute = parseIntOrZero(match[5]); | 262 int minute = parseIntOrZero(match[5]); |
| 248 int second = parseIntOrZero(match[6]); | 263 int second = parseIntOrZero(match[6]); |
| 249 bool addOneMillisecond = false; | 264 bool addOneMillisecond = false; |
| 250 int millisecond = (parseDoubleOrZero(match[7]) * 1000).round(); | 265 int millisecond = (parseDoubleOrZero(match[7]) * 1000).round(); |
| 251 if (millisecond == 1000) { | 266 if (millisecond == 1000) { |
| 252 addOneMillisecond = true; | 267 addOneMillisecond = true; |
| 253 millisecond = 999; | 268 millisecond = 999; |
| 254 } | 269 } |
| 255 bool isUtc = (match[8] != null); | 270 bool isUtc = false; |
| 271 if (match[8] != null) { // timezone part | |
| 272 isUtc = true; | |
| 273 if (match[9] != null) { | |
| 274 // timezone other than 'Z' and 'z'. | |
| 275 int sign = (match[9] == '-') ? -1 : 1; | |
| 276 int hourDifference = int.parse(match[10]); | |
| 277 int minuteDifference = parseIntOrZero(match[11]); | |
| 278 minuteDifference += 60 * hourDifference; | |
| 279 minute -= sign * minuteDifference; | |
| 280 } | |
| 281 } | |
| 256 int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch( | 282 int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch( |
| 257 years, month, day, hour, minute, second, millisecond, isUtc); | 283 years, month, day, hour, minute, second, millisecond, isUtc); |
| 258 if (millisecondsSinceEpoch == null) { | 284 if (millisecondsSinceEpoch == null) { |
| 259 throw new FormatException(formattedString); | 285 throw new FormatException(formattedString); |
| 260 } | 286 } |
| 261 if (addOneMillisecond) millisecondsSinceEpoch++; | 287 if (addOneMillisecond) millisecondsSinceEpoch++; |
| 262 return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, | 288 return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch, |
| 263 isUtc: isUtc); | 289 isUtc: isUtc); |
| 264 } else { | 290 } else { |
| 265 throw new FormatException(formattedString); | 291 throw new FormatException(formattedString); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 /** | 524 /** |
| 499 * The abbreviated time zone name—for example, | 525 * The abbreviated time zone name—for example, |
| 500 * [:"CET":] or [:"CEST":]. | 526 * [:"CET":] or [:"CEST":]. |
| 501 */ | 527 */ |
| 502 external String get timeZoneName; | 528 external String get timeZoneName; |
| 503 | 529 |
| 504 /** | 530 /** |
| 505 * The time zone offset, which | 531 * The time zone offset, which |
| 506 * is the difference between local time and UTC. | 532 * is the difference between local time and UTC. |
| 507 * | 533 * |
| 508 * The offset is positive for time zones west of UTC. | 534 * The offset is positive for time zones east of UTC. |
|
floitsch
2014/02/17 10:37:38
oops.
| |
| 509 * | 535 * |
| 510 * Note, that JavaScript, Python and C return the difference between UTC and | 536 * Note, that JavaScript, Python and C return the difference between UTC and |
| 511 * local time. Java, C# and Ruby return the difference between local time and | 537 * local time. Java, C# and Ruby return the difference between local time and |
| 512 * UTC. | 538 * UTC. |
| 513 */ | 539 */ |
| 514 external Duration get timeZoneOffset; | 540 external Duration get timeZoneOffset; |
| 515 | 541 |
| 516 /** | 542 /** |
| 517 * The year. | 543 * The year. |
| 518 * | 544 * |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 * In accordance with ISO 8601 | 602 * In accordance with ISO 8601 |
| 577 * a week starts with Monday, which has the value 1. | 603 * a week starts with Monday, which has the value 1. |
| 578 * | 604 * |
| 579 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | 605 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); |
| 580 * assert(moonLanding.weekday == 7); | 606 * assert(moonLanding.weekday == 7); |
| 581 * assert(moonLanding.weekday == DateTime.SUNDAY); | 607 * assert(moonLanding.weekday == DateTime.SUNDAY); |
| 582 * | 608 * |
| 583 */ | 609 */ |
| 584 external int get weekday; | 610 external int get weekday; |
| 585 } | 611 } |
| OLD | NEW |