Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /** | 1 /** |
| 2 * Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 * Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 3 * for details. All rights reserved. Use of this source code is governed by a | 3 * for details. All rights reserved. Use of this source code is governed by a |
| 4 * BSD-style license that can be found in the LICENSE file. | 4 * BSD-style license that can be found in the LICENSE file. |
| 5 * | 5 * |
| 6 * DateFormat is for formatting and parsing dates in a locale-sensitive | 6 * DateTimeFormat is for formatting and parsing dates in a locale-sensitive |
|
Alan Knight
2012/06/04 19:58:37
I'd called it DateFormat because the objects it op
Emily Fortuna
2012/06/04 22:25:57
You're right. I'll fix it right now.
| |
| 7 * manner. | 7 * manner. |
| 8 * It allows the user to use any customized pattern to parse or format | 8 * It allows the user to choose from a set of standard date time formats as well |
| 9 * as specify a customized pattern under certain locales. Date elements that | |
| 10 * vary across locales include month name, weekname, field, order, etc. | |
| 11 * //TODO(efortuna): Customized pattern system -- suggested by i18n needs | |
| 12 * // feedback on appropriateness. | |
| 13 * We also allow the user to use any customized pattern to parse or format | |
| 9 * date-time strings under certain locales. Date elements that vary across | 14 * date-time strings under certain locales. Date elements that vary across |
| 10 * locales include month name, weekname, field, order, etc. | 15 * locales include month name, weekname, field, order, etc. |
| 11 * | 16 * |
| 12 * This library uses the ICU/JDK date/time pattern specification as described | 17 * This library uses the ICU/JDK date/time pattern specification as described |
| 13 * below. | 18 * below. |
| 14 * | 19 * |
| 15 * Time Format Syntax: To specify the time format use a time pattern string. | 20 * Time Format Syntax: To specify the time format use a time pattern string. |
| 16 * In this pattern, following letters are reserved as pattern letters, which | 21 * In this pattern, following letters are reserved as pattern letters, which |
| 17 * are defined in the following manner: | 22 * are defined in the following manner: |
| 18 * | 23 * |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 * instance, characters like ':', '.', ' ', '#' and '@' will appear in the | 63 * instance, characters like ':', '.', ' ', '#' and '@' will appear in the |
| 59 * resulting time text even they are not embraced within single quotes. In our | 64 * resulting time text even they are not embraced within single quotes. In our |
| 60 * current pattern usage, we didn't use up all letters. But those unused | 65 * current pattern usage, we didn't use up all letters. But those unused |
| 61 * letters are strongly discouraged to be used as quoted text without quote. | 66 * letters are strongly discouraged to be used as quoted text without quote. |
| 62 * That's because we may use other letter for pattern in future. | 67 * That's because we may use other letter for pattern in future. |
| 63 * | 68 * |
| 64 * Examples Using the US Locale: | 69 * Examples Using the US Locale: |
| 65 * | 70 * |
| 66 * Format Pattern Result | 71 * Format Pattern Result |
| 67 * -------------- ------- | 72 * -------------- ------- |
| 68 * "yyyy.MM.dd G 'at' HH:mm:ss vvvv"->> 1996.07.10 AD at 15:08:56 Pacific Ti me | 73 * "yyyy.MM.dd G 'at' HH:mm:ss vvvv"->1996.07.10 AD at 15:08:56 Pacific Time |
| 69 * "EEE, MMM d, ''yy" ->> Wed, July 10, '96 | 74 * "EEE, MMM d, ''yy" ->Wed, July 10, '96 |
| 70 * "h:mm a" ->> 12:08 PM | 75 * "h:mm a" ->12:08 PM |
| 71 * "hh 'o''clock' a, zzzz" ->> 12 o'clock PM, Pacific Daylight Time | 76 * "hh 'o''clock' a, zzzz" ->12 o'clock PM, Pacific Daylight Time |
| 72 * "K:mm a, vvv" ->> 0:00 PM, PT | 77 * "K:mm a, vvv" ->0:00 PM, PT |
| 73 * "yyyyy.MMMMM.dd GGG hh:mm aaa" ->> 01996.July.10 AD 12:08 PM | 78 * "yyyyy.MMMMM.dd GGG hh:mm aaa" ->01996.July.10 AD 12:08 PM |
| 74 * | 79 * |
| 75 * When parsing a date string using the abbreviated year pattern ("yy"), | 80 * When parsing a date string using the abbreviated year pattern ("yy"), |
| 76 * DateTimeParse must interpret the abbreviated year relative to some | 81 * DateTimeParse must interpret the abbreviated year relative to some |
| 77 * century. It does this by adjusting dates to be within 80 years before and 20 | 82 * century. It does this by adjusting dates to be within 80 years before and 20 |
| 78 * years after the time the parse function is called. For example, using a | 83 * years after the time the parse function is called. For example, using a |
| 79 * pattern of "MM/dd/yy" and a DateTimeParse instance created on Jan 1, 1997, | 84 * pattern of "MM/dd/yy" and a DateTimeParse instance created on Jan 1, 1997, |
| 80 * the string "01/11/12" would be interpreted as Jan 11, 2012 while the string | 85 * the string "01/11/12" would be interpreted as Jan 11, 2012 while the string |
| 81 * "05/04/64" would be interpreted as May 4, 1964. During parsing, only | 86 * "05/04/64" would be interpreted as May 4, 1964. During parsing, only |
| 82 * strings consisting of exactly two digits, as defined by {@link | 87 * strings consisting of exactly two digits, as defined by {@link |
| 83 * java.lang.Character#isDigit(char)}, will be parsed into the default | 88 * java.lang.Character#isDigit(char)}, will be parsed into the default |
| 84 * century. Any other numeric string, such as a one digit string, a three or | 89 * century. Any other numeric string, such as a one digit string, a three or |
| 85 * more digit string will be interpreted as its face value. | 90 * more digit string will be interpreted as its face value. |
| 86 * | 91 * |
| 87 * If the year pattern does not have exactly two 'y' characters, the year is | 92 * If the year pattern does not have exactly two 'y' characters, the year is |
| 88 * interpreted literally, regardless of the number of digits. So using the | 93 * interpreted literally, regardless of the number of digits. So using the |
| 89 * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D. | 94 * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D. |
| 90 * | 95 * |
| 91 * When numeric fields abut one another directly, with no intervening | 96 * When numeric fields abut one another directly, with no intervening |
| 92 * delimiter characters, they constitute a run of abutting numeric fields. Such | 97 * delimiter characters, they constitute a run of abutting numeric fields. Such |
| 93 * runs are parsed specially. For example, the format "HHmmss" parses the input | 98 * runs are parsed specially. For example, the format "HHmmss" parses the input |
| 94 * text "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and | 99 * text "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and |
| 95 * fails to parse "1234". In other words, the leftmost field of the run is | 100 * fails to parse "1234". In other words, the leftmost field of the run is |
| 96 * flexible, while the others keep a fixed width. If the parse fails anywhere in | 101 * flexible, while the others keep a fixed width. If the parse fails anywhere in |
| 97 * the run, then the leftmost field is shortened by one character, and the | 102 * the run, then the leftmost field is shortened by one character, and the |
| 98 * entire run is parsed again. This is repeated until either the parse succeeds | 103 * entire run is parsed again. This is repeated until either the parse succeeds |
| 99 * or the leftmost field is one character in length. If the parse still fails at | 104 * or the leftmost field is one character in length. If the parse still fails at |
| 100 * that point, the parse of the run fails. | 105 * that point, the parse of the run fails. |
| 101 */ | 106 */ |
| 102 | 107 |
| 103 #library('DateFormat'); | 108 #library('DateTimeFormat'); |
| 104 | 109 |
| 105 class DateFormat { | 110 class DateTimeFormat { |
| 106 | 111 |
| 107 /** Definition of this object formats dates. */ | 112 /** Definition of this object formats dates. */ |
| 108 var formatDefinition; | 113 var formatDefinition; |
| 109 | 114 |
| 110 /** Date/Time format patterns. */ | 115 /** |
| 111 // TODO(alanknight): There's a style question of whether to use fullDate or | 116 * String indicating a language code with which the message is to be |
|
Alan Knight
2012/06/04 19:58:37
Strictly I think language would be just the "en" p
Emily Fortuna
2012/06/04 22:25:57
Done.
| |
| 112 // FULL_DATE naming conventions. | 117 * formatted (such as en-US). |
| 113 static final int _fullDate = 0; | 118 */ |
| 114 static final int _longDate = 1; | 119 String _locale; |
| 115 static final int _mediumDate = 2; | 120 |
| 116 static final int _shortDate = 3; | 121 /** |
| 117 static final int _fullTime = 4; | 122 * Date/Time format "skeleton" patterns. Also specifiable by String, but |
| 118 static final int _longTime = 5; | 123 * written this way so that they can be discoverable via autocomplete. |
|
Alan Knight
2012/06/04 19:58:37
We should probably say where these come from and/o
Emily Fortuna
2012/06/04 22:25:57
Done.
| |
| 119 static final int _mediumTime = 6; | 124 */ |
| 120 static final int _shortTime = 7; | 125 static final String Hm = 'Hm'; // HH:mm |
|
Alan Knight
2012/06/04 19:58:37
So usage on these is, e.g.
new DateTimeFormat(D
Emily Fortuna
2012/06/04 22:25:57
Realistically, no, people are not going to want to
| |
| 121 static final int _fullDateTime = 8; | 126 static final String Hms = 'Hms'; // HH:mm:ss |
| 122 static final int _longDateTime = 9; | 127 static final String M = 'M'; // L |
| 123 static final int _mediumDateTime = 10; | 128 static final String MEd = 'MEd'; // E, M/d |
| 124 static final int _shortDateTime = 11; | 129 static final String MMM = 'MMM'; // LLL |
| 130 static final String MMMEd = 'MMMEd'; // E, MMM d | |
| 131 static final String MMMMEd = 'MMMMEd'; // E, MMMM d | |
| 132 static final String MMMMd = 'MMMMd'; // MMMM d | |
| 133 static final String MMMd = 'MMMd'; // MMM d | |
| 134 static final String Md = 'Md'; // M/d | |
| 135 static final String d = 'd'; // d | |
| 136 static final String hm = 'hm'; // h:mm a | |
| 137 static final String ms = 'ms'; // mm:ss | |
| 138 static final String y = 'y'; // yyyy | |
| 139 static final String yM = 'yM'; // M/yyyy | |
| 140 static final String yMEd = 'yMEd'; // EEE, M/d/yyyy | |
| 141 static final String yMMM = 'yMMM'; // MMM yyyy | |
| 142 static final String yMMMEd = 'yMMMEd'; // EEE, MM d, yyyy | |
| 143 static final String yMMMM = 'yMMMM'; // MMMM yyyy | |
| 144 static final String yQ = 'yQ'; // Q yyyy | |
| 145 static final String yQQQ = 'yQQQ'; // QQQ yyyy | |
| 146 | |
| 147 /** Date/Time format patterns. */ | |
|
Alan Knight
2012/06/04 19:58:37
We should probably make this mechanism more consis
Emily Fortuna
2012/06/04 22:25:57
Fixing...
| |
| 148 // TODO(alanknight): There's a style question of whether to use fullDate or | |
| 149 // FULL_DATE naming conventions. | |
| 150 static final int _fullDate = 0; | |
| 151 static final int _longDate = 1; | |
| 152 static final int _mediumDate = 2; | |
| 153 static final int _shortDate = 3; | |
| 154 static final int _fullTime = 4; | |
| 155 static final int _longTime = 5; | |
| 156 static final int _mediumTime = 6; | |
| 157 static final int _shortTime = 7; | |
| 158 static final int _fullDateTime = 8; | |
| 159 static final int _longDateTime = 9; | |
| 160 static final int _mediumDateTime = 10; | |
| 161 static final int _shortDateTime = 11; | |
| 125 | 162 |
| 126 /** | 163 /** |
| 127 * Named constructors for each of the above values. | 164 * Named constructors for each of the above values. |
| 128 * These could probably be made shorter if we just set the format to the | 165 * These could probably be made shorter if we just set the format to the |
| 129 * constant and the parsing was lazy. | 166 * constant and the parsing was lazy. |
| 130 */ | 167 */ |
| 131 DateFormat.fullDate() : this.formatDefinition = _fullDate; | 168 DateTimeFormat.fullDate() : this.formatDefinition = _fullDate; |
| 132 DateFormat.longDate() : this.formatDefinition = _longDate; | 169 DateTimeFormat.longDate() : this.formatDefinition = _longDate; |
| 133 DateFormat.mediumDate() : this.formatDefinition = _mediumDate; | 170 DateTimeFormat.mediumDate() : this.formatDefinition = _mediumDate; |
| 134 DateFormat.shortDate() : this.formatDefinition = _shortDate; | 171 DateTimeFormat.shortDate() : this.formatDefinition = _shortDate; |
| 135 DateFormat.fullTime() : this.formatDefinition = _fullTime; | 172 DateTimeFormat.fullTime() : this.formatDefinition = _fullTime; |
| 136 DateFormat.longTime() : this.formatDefinition = _longTime; | 173 DateTimeFormat.longTime() : this.formatDefinition = _longTime; |
| 137 DateFormat.mediumTime() : this.formatDefinition = _mediumTime; | 174 DateTimeFormat.mediumTime() : this.formatDefinition = _mediumTime; |
| 138 DateFormat.shortTime() : this.formatDefinition = _shortTime; | 175 DateTimeFormat.shortTime() : this.formatDefinition = _shortTime; |
| 139 DateFormat.fullDateTime() : this.formatDefinition = _fullDateTime; | 176 DateTimeFormat.fullDateTime() : this.formatDefinition = _fullDateTime; |
| 140 DateFormat.longDateTime() : this.formatDefinition = _longDateTime; | 177 DateTimeFormat.longDateTime() : this.formatDefinition = _longDateTime; |
| 141 DateFormat.mediumDateTime() : this.formatDefinition = _mediumDateTime; | 178 DateTimeFormat.mediumDateTime() : this.formatDefinition = _mediumDateTime; |
| 142 DateFormat.shortDateTime() : this.formatDefinition = _shortDateTime; | 179 DateTimeFormat.shortDateTime() : this.formatDefinition = _shortDateTime; |
| 143 | 180 |
| 144 DateFormat(this.formatDefinition); | 181 /** |
| 182 * Constructor accepts a [formatDefinition], which can be a String, one of the | |
| 183 * predefined static forms, or a custom date format using the syntax described | |
| 184 * above. An optional [_locale] can be provided for specifics of the language | |
| 185 * locale to be used, otherwise, we will attempt to infer it (acceptable if | |
| 186 * Dart is running on the client, we can infer from the browser). | |
| 187 */ | |
| 188 DateTimeFormat(this.formatDefinition, [this._locale]); | |
| 145 | 189 |
| 146 /** | 190 /** |
| 147 * | 191 * Given user input, attempt to parse the [inputString] into the anticipated |
| 192 * format. | |
| 148 */ | 193 */ |
| 149 String parse(String inputString) { | 194 String parse(String inputString) { |
| 150 return inputString; | 195 return inputString; |
| 151 } | 196 } |
| 152 | 197 |
| 153 /** | 198 /** |
| 154 * Format the given [date] object according to preset pattern and current | 199 * Format the given [date] object according to preset pattern and current |
| 155 * locale and return a formated string for the given date. | 200 * locale and return a formated string for the given date. |
| 156 */ | 201 */ |
| 157 String format(Date date, [TimeZone timeZone]) { | 202 String format(Date date, [TimeZone timeZone]) { |
| 158 // TODO(efortuna): optional TimeZone argument? TimeZone is deprecated... | 203 // TODO(efortuna): optional TimeZone argument? TimeZone is deprecated... |
| 159 return date.toString(); | 204 return date.toString(); |
| 160 } | 205 } |
| 161 } | 206 } |
| OLD | NEW |