Index: sdk/lib/core/date_time.dart |
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart |
index 02f7cdae12a222c8f89e8b9a7e4f8ee70395b2d7..2c9fb9ac5a838e980d42eb3545e96d1c103d88de 100644 |
--- a/sdk/lib/core/date_time.dart |
+++ b/sdk/lib/core/date_time.dart |
@@ -215,7 +215,8 @@ class DateTime implements Comparable { |
* * An optional time-zone offset part, |
* possibly separated from the previous by a space. |
* The time zone is either 'z' or 'Z', or it is a signed two digit hour |
- * part and an optional two digit minute part. |
+ * part and an optional two digit minute part. The sign must be either |
+ * "+" or "-", and can not be omitted. |
* The minutes may be separted from the hours by a ':'. |
* Examples: "Z", "-10", "01:30", "1130". |
* |
@@ -263,7 +264,7 @@ class DateTime implements Comparable { |
*/ |
final RegExp re = new RegExp( |
r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // The day part. |
- r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(.\d{1,6})?)?)?' // The time part |
+ r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d{1,6}))?)?)?' // The time part |
Søren Gjesse
2015/04/20 10:18:43
Long line.
|
r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // The timezone part |
Match match = re.firstMatch(formattedString); |
@@ -273,9 +274,37 @@ class DateTime implements Comparable { |
return int.parse(matched); |
} |
- double parseDoubleOrZero(String matched) { |
- if (matched == null) return 0.0; |
- return double.parse(matched); |
+ // Parses fractional second digits of '.(\d{1,6})' into milliseconds. |
+ // Uses first three digits (assumed to be zero if not there), and |
+ // rounds up if fourth digit is 5 or greater. |
+ // Should be equivalent to `(double.parse(".$matchd")*1000).round()`. |
+ int parseMilliseconds(String matched) { |
+ if (matched == null) return 0; |
+ int length = matched.length; |
+ assert(length >= 1); |
+ assert(length <= 6); |
+ |
+ int result = (matched.codeUnitAt(0) ^ 0x30); |
+ if (length <= 3) { |
+ int i = 1; |
+ while (i < length) { |
+ result *= 10; |
+ result += matched.codeUnitAt(i) ^ 0x30; |
+ i++; |
+ } |
+ while (i < 3) { |
+ result *= 10; |
+ i++; |
+ } |
+ return result; |
+ } |
+ // Parse the prefix from 0..3 without creating a new substring. |
+ result = result * 10 + (matched.codeUnitAt(1) ^ 0x30); |
+ result = result * 10 + (matched.codeUnitAt(2) ^ 0x30); |
+ if (matched.codeUnitAt(3) >= 0x35) { |
+ result += 1; |
+ } |
+ return result; |
} |
int years = int.parse(match[1]); |
@@ -285,7 +314,7 @@ class DateTime implements Comparable { |
int minute = parseIntOrZero(match[5]); |
int second = parseIntOrZero(match[6]); |
bool addOneMillisecond = false; |
- int millisecond = (parseDoubleOrZero(match[7]) * 1000).round(); |
+ int millisecond = parseMilliseconds(match[7]); |
if (millisecond == 1000) { |
addOneMillisecond = true; |
millisecond = 999; |