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

Side by Side Diff: packages/intl/lib/src/intl/date_format_helpers.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 years, 4 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 intl; 5 part of intl;
6 6
7 /** 7 /// A class for holding onto the data for a date so that it can be built
8 * A class for holding onto the data for a date so that it can be built 8 /// up incrementally.
9 * up incrementally.
10 */
11 class _DateBuilder { 9 class _DateBuilder {
12 // Default the date values to the EPOCH so that there's a valid date 10 // Default the date values to the EPOCH so that there's a valid date
13 // in case the format doesn't set them. 11 // in case the format doesn't set them.
14 int year = 1970, 12 int year = 1970,
15 month = 1, 13 month = 1,
16 day = 1, 14 day = 1,
17 hour = 0, 15 hour = 0,
18 minute = 0, 16 minute = 0,
19 second = 0, 17 second = 0,
20 fractionalSecond = 0; 18 fractionalSecond = 0;
21 bool pm = false; 19 bool pm = false;
22 bool utc = false; 20 bool utc = false;
23 21
24 // Functions that exist just to be closurized so we can pass them to a general 22 // Functions that exist just to be closurized so we can pass them to a general
25 // method. 23 // method.
26 void setYear(x) { 24 void setYear(x) {
27 year = x; 25 year = x;
28 } 26 }
27
29 void setMonth(x) { 28 void setMonth(x) {
30 month = x; 29 month = x;
31 } 30 }
31
32 void setDay(x) { 32 void setDay(x) {
33 day = x; 33 day = x;
34 } 34 }
35
35 void setHour(x) { 36 void setHour(x) {
36 hour = x; 37 hour = x;
37 } 38 }
39
38 void setMinute(x) { 40 void setMinute(x) {
39 minute = x; 41 minute = x;
40 } 42 }
43
41 void setSecond(x) { 44 void setSecond(x) {
42 second = x; 45 second = x;
43 } 46 }
47
44 void setFractionalSecond(x) { 48 void setFractionalSecond(x) {
45 fractionalSecond = x; 49 fractionalSecond = x;
46 } 50 }
47 51
48 get hour24 => pm ? hour + 12 : hour; 52 get hour24 => pm ? hour + 12 : hour;
49 53
50 /** 54 /// Verify that we correspond to a valid date. This will reject out of
51 * Verify that we correspond to a valid date. This will reject out of 55 /// range values, even if the DateTime constructor would accept them. An
52 * range values, even if the DateTime constructor would accept them. An 56 /// invalid message will result in throwing a [FormatException].
53 * invalid message will result in throwing a [FormatException].
54 */
55 verify(String s) { 57 verify(String s) {
56 _verify(month, 1, 12, "month", s); 58 _verify(month, 1, 12, "month", s);
57 _verify(hour24, 0, 23, "hour", s); 59 _verify(hour24, 0, 23, "hour", s);
58 _verify(minute, 0, 59, "minute", s); 60 _verify(minute, 0, 59, "minute", s);
59 _verify(second, 0, 59, "second", s); 61 _verify(second, 0, 59, "second", s);
60 _verify(fractionalSecond, 0, 999, "fractional second", s); 62 _verify(fractionalSecond, 0, 999, "fractional second", s);
61 // Verifying the day is tricky, because it depends on the month. Create 63 // Verifying the day is tricky, because it depends on the month. Create
62 // our resulting date and then verify that our values agree with it 64 // our resulting date and then verify that our values agree with it
63 // as an additional verification. And since we're doing that, also 65 // as an additional verification. And since we're doing that, also
64 // check the year, which we otherwise can't verify, and the hours, 66 // check the year, which we otherwise can't verify, and the hours,
65 // which will catch cases like "14:00:00 PM". 67 // which will catch cases like "14:00:00 PM".
66 var date = asDate(); 68 var date = asDate();
67 _verify(hour24, date.hour, date.hour, "hour", s); 69 _verify(hour24, date.hour, date.hour, "hour", s, date);
68 _verify(day, date.day, date.day, "day", s); 70 _verify(day, date.day, date.day, "day", s, date);
69 _verify(year, date.year, date.year, "year", s); 71 _verify(year, date.year, date.year, "year", s, date);
70 } 72 }
71 73
72 _verify(int value, int min, int max, String desc, String originalInput) { 74 _verify(int value, int min, int max, String desc, String originalInput,
75 [DateTime parsed]) {
73 if (value < min || value > max) { 76 if (value < min || value > max) {
77 var parsedDescription = parsed == null ? "" : " Date parsed as $parsed.";
74 throw new FormatException( 78 throw new FormatException(
75 "Error parsing $originalInput, invalid $desc value: $value"); 79 "Error parsing $originalInput, invalid $desc value: $value."
80 " Expected value between $min and $max.$parsedDescription");
76 } 81 }
77 } 82 }
78 83
79 /** 84 /// Return a date built using our values. If no date portion is set,
80 * Return a date built using our values. If no date portion is set, 85 /// use the "Epoch" of January 1, 1970.
81 * use the "Epoch" of January 1, 1970. 86 DateTime asDate({int retries: 10}) {
82 */
83 DateTime asDate({retry: true}) {
84 // TODO(alanknight): Validate the date, especially for things which 87 // TODO(alanknight): Validate the date, especially for things which
85 // can crash the VM, e.g. large month values. 88 // can crash the VM, e.g. large month values.
86 var result; 89 var result;
87 if (utc) { 90 if (utc) {
88 result = new DateTime.utc( 91 result = new DateTime.utc(
89 year, month, day, hour24, minute, second, fractionalSecond); 92 year, month, day, hour24, minute, second, fractionalSecond);
90 } else { 93 } else {
91 result = new DateTime( 94 result = new DateTime(
92 year, month, day, hour24, minute, second, fractionalSecond); 95 year, month, day, hour24, minute, second, fractionalSecond);
93 // TODO(alanknight): Issue 15560 means non-UTC dates occasionally come 96 // TODO(alanknight): Issue 15560 means non-UTC dates occasionally come out
94 // out in UTC. If that happens, retry once. This will always happen if 97 // in UTC, or, alternatively, are constructed as if in UTC and then have
95 // the local time zone is UTC, but that's ok. 98 // the offset subtracted. If that happens, retry, several times if
96 if (result.toUtc() == result) { 99 // necessary.
97 result = asDate(retry: false); 100 if (retries > 0 && (result.hour != hour24 || result.day != day)) {
101 result = asDate(retries: retries - 1);
98 } 102 }
99 } 103 }
100 return result; 104 return result;
101 } 105 }
102 } 106 }
103 107
104 /** 108 /// A simple and not particularly general stream class to make parsing
105 * A simple and not particularly general stream class to make parsing 109 /// dates from strings simpler. It is general enough to operate on either
106 * dates from strings simpler. It is general enough to operate on either 110 /// lists or strings.
107 * lists or strings.
108 */
109 // TODO(alanknight): With the improvements to the collection libraries 111 // TODO(alanknight): With the improvements to the collection libraries
110 // since this was written we might be able to get rid of it entirely 112 // since this was written we might be able to get rid of it entirely
111 // in favor of e.g. aString.split('') giving us an iterable of one-character 113 // in favor of e.g. aString.split('') giving us an iterable of one-character
112 // strings, or else make the implementation trivial. And consider renaming, 114 // strings, or else make the implementation trivial. And consider renaming,
113 // as _Stream is now just confusing with the system Streams. 115 // as _Stream is now just confusing with the system Streams.
114 class _Stream { 116 class _Stream {
115 var contents; 117 var contents;
116 int index = 0; 118 int index = 0;
117 119
118 _Stream(this.contents); 120 _Stream(this.contents);
119 121
120 bool atEnd() => index >= contents.length; 122 bool atEnd() => index >= contents.length;
121 123
122 next() => contents[index++]; 124 next() => contents[index++];
123 125
124 /** 126 /// Return the next [howMany] items, or as many as there are remaining.
125 * Return the next [howMany] items, or as many as there are remaining. 127 /// Advance the stream by that many positions.
126 * Advance the stream by that many positions.
127 */
128 read([int howMany = 1]) { 128 read([int howMany = 1]) {
129 var result = peek(howMany); 129 var result = peek(howMany);
130 index += howMany; 130 index += howMany;
131 return result; 131 return result;
132 } 132 }
133 133
134 /** 134 /// Does the input start with the given string, if we start from the
135 * Does the input start with the given string, if we start from the 135 /// current position.
136 * current position.
137 */
138 bool startsWith(String pattern) { 136 bool startsWith(String pattern) {
139 if (contents is String) return contents.startsWith(pattern, index); 137 if (contents is String) return contents.startsWith(pattern, index);
140 return pattern == peek(pattern.length); 138 return pattern == peek(pattern.length);
141 } 139 }
142 140
143 /** 141 /// Return the next [howMany] items, or as many as there are remaining.
144 * Return the next [howMany] items, or as many as there are remaining. 142 /// Does not modify the stream position.
145 * Does not modify the stream position.
146 */
147 peek([int howMany = 1]) { 143 peek([int howMany = 1]) {
148 var result; 144 var result;
149 if (contents is String) { 145 if (contents is String) {
150 result = contents.substring(index, min(index + howMany, contents.length)); 146 String stringContents = contents;
147 result = stringContents.substring(
148 index, min(index + howMany, stringContents.length));
151 } else { 149 } else {
152 // Assume List 150 // Assume List
153 result = contents.sublist(index, index + howMany); 151 result = contents.sublist(index, index + howMany);
154 } 152 }
155 return result; 153 return result;
156 } 154 }
157 155
158 /** Return the remaining contents of the stream */ 156 /// Return the remaining contents of the stream
159 rest() => peek(contents.length - index); 157 rest() => peek(contents.length - index);
160 158
161 /** 159 /// Find the index of the first element for which [f] returns true.
162 * Find the index of the first element for which [f] returns true. 160 /// Advances the stream to that position.
163 * Advances the stream to that position.
164 */
165 int findIndex(Function f) { 161 int findIndex(Function f) {
166 while (!atEnd()) { 162 while (!atEnd()) {
167 if (f(next())) return index - 1; 163 if (f(next())) return index - 1;
168 } 164 }
169 return null; 165 return null;
170 } 166 }
171 167
172 /** 168 /// Find the indexes of all the elements for which [f] returns true.
173 * Find the indexes of all the elements for which [f] returns true. 169 /// Leaves the stream positioned at the end.
174 * Leaves the stream positioned at the end.
175 */
176 List findIndexes(Function f) { 170 List findIndexes(Function f) {
177 var results = []; 171 var results = [];
178 while (!atEnd()) { 172 while (!atEnd()) {
179 if (f(next())) results.add(index - 1); 173 if (f(next())) results.add(index - 1);
180 } 174 }
181 return results; 175 return results;
182 } 176 }
183 177
184 /** 178 /// Assuming that the contents are characters, read as many digits as we
185 * Assuming that the contents are characters, read as many digits as we 179 /// can see and then return the corresponding integer. Advance the stream.
186 * can see and then return the corresponding integer. Advance the stream. 180 var digitMatcher = new RegExp(r'^\d+');
187 */
188 var digitMatcher = new RegExp(r'\d+');
189 int nextInteger() { 181 int nextInteger() {
190 var string = digitMatcher.stringMatch(rest()); 182 var string = digitMatcher.stringMatch(rest());
191 if (string == null || string.isEmpty) return null; 183 if (string == null || string.isEmpty) return null;
192 read(string.length); 184 read(string.length);
193 return int.parse(string); 185 return int.parse(string);
194 } 186 }
195 } 187 }
OLDNEW
« no previous file with comments | « packages/intl/lib/src/intl/date_format_field.dart ('k') | packages/intl/lib/src/intl/number_format.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698