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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 * * An optional time part, separated from the date by either `T` or a space. | 208 * * An optional time part, separated from the date by either `T` or a space. |
209 * The time part is a two digit hour, | 209 * The time part is a two digit hour, |
210 * then optionally a two digit minutes value, | 210 * then optionally a two digit minutes value, |
211 * then optionally a two digit seconds value, and | 211 * then optionally a two digit seconds value, and |
212 * then optionally a '.' followed by a one-to-six digit second fraction. | 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 ':'. | 213 * The minuts and seconds may be separated from the previous parts by a ':'. |
214 * Examples: "12", "12:30:24.124", "123010.50". | 214 * Examples: "12", "12:30:24.124", "123010.50". |
215 * * An optional time-zone offset part, | 215 * * An optional time-zone offset part, |
216 * possibly separated from the previous by a space. | 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 | 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. | 218 * part and an optional two digit minute part. The sign must be either |
| 219 * "+" or "-", and can not be omitted. |
219 * The minutes may be separted from the hours by a ':'. | 220 * The minutes may be separted from the hours by a ':'. |
220 * Examples: "Z", "-10", "01:30", "1130". | 221 * Examples: "Z", "-10", "01:30", "1130". |
221 * | 222 * |
222 * This includes the output of both [toString] and [toIso8601String], which | 223 * 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 * will be parsed back into a `DateTime` object with the same time as the |
224 * original. | 225 * original. |
225 * | 226 * |
226 * The result is always in either local time or UTC. | 227 * The result is always in either local time or UTC. |
227 * If a time zone offset other than UTC is specified, | 228 * If a time zone offset other than UTC is specified, |
228 * the time is converted to the equivalent UTC time. | 229 * the time is converted to the equivalent UTC time. |
(...skipping 26 matching lines...) Expand all Loading... |
255 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt | 256 * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt |
256 * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt | 257 * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt |
257 * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt | 258 * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt |
258 * millis_opt ::= <empty> | '.' digit{1,6} | 259 * millis_opt ::= <empty> | '.' digit{1,6} |
259 * timezone_opt ::= <empty> | space_opt timezone | 260 * timezone_opt ::= <empty> | space_opt timezone |
260 * space_opt :: ' ' | <empty> | 261 * space_opt :: ' ' | <empty> |
261 * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt | 262 * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt |
262 * timezonemins_opt ::= <empty> | colon_opt digit{2} | 263 * timezonemins_opt ::= <empty> | colon_opt digit{2} |
263 */ | 264 */ |
264 final RegExp re = new RegExp( | 265 final RegExp re = new RegExp( |
265 r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // The day part. | 266 r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part. |
266 r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(.\d{1,6})?)?)?' // The time part | 267 r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d{1,6}))?)?)?' // Time part. |
267 r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // The timezone part | 268 r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part. |
268 | 269 |
269 Match match = re.firstMatch(formattedString); | 270 Match match = re.firstMatch(formattedString); |
270 if (match != null) { | 271 if (match != null) { |
271 int parseIntOrZero(String matched) { | 272 int parseIntOrZero(String matched) { |
272 if (matched == null) return 0; | 273 if (matched == null) return 0; |
273 return int.parse(matched); | 274 return int.parse(matched); |
274 } | 275 } |
275 | 276 |
276 double parseDoubleOrZero(String matched) { | 277 // Parses fractional second digits of '.(\d{1,6})' into milliseconds. |
277 if (matched == null) return 0.0; | 278 // Uses first three digits (assumed to be zero if not there), and |
278 return double.parse(matched); | 279 // rounds up if fourth digit is 5 or greater. |
| 280 // Should be equivalent to `(double.parse(".$matchd")*1000).round()`. |
| 281 int parseMilliseconds(String matched) { |
| 282 if (matched == null) return 0; |
| 283 int length = matched.length; |
| 284 assert(length >= 1); |
| 285 assert(length <= 6); |
| 286 |
| 287 int result = (matched.codeUnitAt(0) ^ 0x30); |
| 288 if (length <= 3) { |
| 289 int i = 1; |
| 290 while (i < length) { |
| 291 result *= 10; |
| 292 result += matched.codeUnitAt(i) ^ 0x30; |
| 293 i++; |
| 294 } |
| 295 while (i < 3) { |
| 296 result *= 10; |
| 297 i++; |
| 298 } |
| 299 return result; |
| 300 } |
| 301 // Parse the prefix from 0..3 without creating a new substring. |
| 302 result = result * 10 + (matched.codeUnitAt(1) ^ 0x30); |
| 303 result = result * 10 + (matched.codeUnitAt(2) ^ 0x30); |
| 304 if (matched.codeUnitAt(3) >= 0x35) { |
| 305 result += 1; |
| 306 } |
| 307 return result; |
279 } | 308 } |
280 | 309 |
281 int years = int.parse(match[1]); | 310 int years = int.parse(match[1]); |
282 int month = int.parse(match[2]); | 311 int month = int.parse(match[2]); |
283 int day = int.parse(match[3]); | 312 int day = int.parse(match[3]); |
284 int hour = parseIntOrZero(match[4]); | 313 int hour = parseIntOrZero(match[4]); |
285 int minute = parseIntOrZero(match[5]); | 314 int minute = parseIntOrZero(match[5]); |
286 int second = parseIntOrZero(match[6]); | 315 int second = parseIntOrZero(match[6]); |
287 bool addOneMillisecond = false; | 316 bool addOneMillisecond = false; |
288 int millisecond = (parseDoubleOrZero(match[7]) * 1000).round(); | 317 int millisecond = parseMilliseconds(match[7]); |
289 if (millisecond == 1000) { | 318 if (millisecond == 1000) { |
290 addOneMillisecond = true; | 319 addOneMillisecond = true; |
291 millisecond = 999; | 320 millisecond = 999; |
292 } | 321 } |
293 bool isUtc = false; | 322 bool isUtc = false; |
294 if (match[8] != null) { // timezone part | 323 if (match[8] != null) { // timezone part |
295 isUtc = true; | 324 isUtc = true; |
296 if (match[9] != null) { | 325 if (match[9] != null) { |
297 // timezone other than 'Z' and 'z'. | 326 // timezone other than 'Z' and 'z'. |
298 int sign = (match[9] == '-') ? -1 : 1; | 327 int sign = (match[9] == '-') ? -1 : 1; |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 * In accordance with ISO 8601 | 700 * In accordance with ISO 8601 |
672 * a week starts with Monday, which has the value 1. | 701 * a week starts with Monday, which has the value 1. |
673 * | 702 * |
674 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); | 703 * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00"); |
675 * assert(moonLanding.weekday == 7); | 704 * assert(moonLanding.weekday == 7); |
676 * assert(moonLanding.weekday == DateTime.SUNDAY); | 705 * assert(moonLanding.weekday == DateTime.SUNDAY); |
677 * | 706 * |
678 */ | 707 */ |
679 external int get weekday; | 708 external int get weekday; |
680 } | 709 } |
OLD | NEW |