OLD | NEW |
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 dart.io; | 5 part of dart.io; |
6 | 6 |
7 /** | 7 /** |
8 * Utility functions for working with dates with HTTP specific date | 8 * Utility functions for working with dates with HTTP specific date |
9 * formats. | 9 * formats. |
10 */ | 10 */ |
(...skipping 21 matching lines...) Expand all Loading... |
32 // | "May" | "Jun" | "Jul" | "Aug" | 32 // | "May" | "Jun" | "Jul" | "Aug" |
33 // | "Sep" | "Oct" | "Nov" | "Dec" | 33 // | "Sep" | "Oct" | "Nov" | "Dec" |
34 | 34 |
35 /** | 35 /** |
36 * Format a date according to | 36 * Format a date according to |
37 * [RFC-1123](http://tools.ietf.org/html/rfc1123 "RFC-1123"), | 37 * [RFC-1123](http://tools.ietf.org/html/rfc1123 "RFC-1123"), |
38 * e.g. `Thu, 1 Jan 1970 00:00:00 GMT`. | 38 * e.g. `Thu, 1 Jan 1970 00:00:00 GMT`. |
39 */ | 39 */ |
40 static String format(DateTime date) { | 40 static String format(DateTime date) { |
41 const List wkday = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; | 41 const List wkday = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; |
42 const List month = const ["Jan", "Feb", "Mar", "Apr", "May", "Jun", | 42 const List month = const [ |
43 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | 43 "Jan", |
| 44 "Feb", |
| 45 "Mar", |
| 46 "Apr", |
| 47 "May", |
| 48 "Jun", |
| 49 "Jul", |
| 50 "Aug", |
| 51 "Sep", |
| 52 "Oct", |
| 53 "Nov", |
| 54 "Dec" |
| 55 ]; |
44 | 56 |
45 DateTime d = date.toUtc(); | 57 DateTime d = date.toUtc(); |
46 StringBuffer sb = new StringBuffer() | 58 StringBuffer sb = new StringBuffer() |
47 ..write(wkday[d.weekday - 1]) | 59 ..write(wkday[d.weekday - 1]) |
48 ..write(", ") | 60 ..write(", ") |
49 ..write(d.day <= 9 ? "0" : "") | 61 ..write(d.day <= 9 ? "0" : "") |
50 ..write(d.day.toString()) | 62 ..write(d.day.toString()) |
51 ..write(" ") | 63 ..write(" ") |
52 ..write(month[d.month - 1]) | 64 ..write(month[d.month - 1]) |
53 ..write(" ") | 65 ..write(" ") |
54 ..write(d.year.toString()) | 66 ..write(d.year.toString()) |
55 ..write(d.hour <= 9 ? " 0" : " ") | 67 ..write(d.hour <= 9 ? " 0" : " ") |
56 ..write(d.hour.toString()) | 68 ..write(d.hour.toString()) |
57 ..write(d.minute <= 9 ? ":0" : ":") | 69 ..write(d.minute <= 9 ? ":0" : ":") |
58 ..write(d.minute.toString()) | 70 ..write(d.minute.toString()) |
59 ..write(d.second <= 9 ? ":0" : ":") | 71 ..write(d.second <= 9 ? ":0" : ":") |
60 ..write(d.second.toString()) | 72 ..write(d.second.toString()) |
61 ..write(" GMT"); | 73 ..write(" GMT"); |
62 return sb.toString(); | 74 return sb.toString(); |
63 } | 75 } |
64 | 76 |
65 /** | 77 /** |
66 * Parse a date string in either of the formats | 78 * Parse a date string in either of the formats |
67 * [RFC-1123](http://tools.ietf.org/html/rfc1123 "RFC-1123"), | 79 * [RFC-1123](http://tools.ietf.org/html/rfc1123 "RFC-1123"), |
68 * [RFC-850](http://tools.ietf.org/html/rfc850 "RFC-850") or | 80 * [RFC-850](http://tools.ietf.org/html/rfc850 "RFC-850") or |
69 * ANSI C's asctime() format. These formats are listed here. | 81 * ANSI C's asctime() format. These formats are listed here. |
70 * | 82 * |
71 * Thu, 1 Jan 1970 00:00:00 GMT | 83 * Thu, 1 Jan 1970 00:00:00 GMT |
72 * Thursday, 1-Jan-1970 00:00:00 GMT | 84 * Thursday, 1-Jan-1970 00:00:00 GMT |
73 * Thu Jan 1 00:00:00 1970 | 85 * Thu Jan 1 00:00:00 1970 |
74 * | 86 * |
75 * For more information see [RFC-2616 section | 87 * For more information see [RFC-2616 section |
76 * 3.1.1](http://tools.ietf.org/html/rfc2616#section-3.3.1 | 88 * 3.1.1](http://tools.ietf.org/html/rfc2616#section-3.3.1 |
77 * "RFC-2616 section 3.1.1"). | 89 * "RFC-2616 section 3.1.1"). |
78 */ | 90 */ |
79 static DateTime parse(String date) { | 91 static DateTime parse(String date) { |
80 final int SP = 32; | 92 final int SP = 32; |
81 const List wkdays = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; | 93 const List wkdays = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; |
82 const List weekdays = const ["Monday", "Tuesday", "Wednesday", "Thursday", | 94 const List weekdays = const [ |
83 "Friday", "Saturday", "Sunday"]; | 95 "Monday", |
84 const List months = const ["Jan", "Feb", "Mar", "Apr", "May", "Jun", | 96 "Tuesday", |
85 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | 97 "Wednesday", |
86 const List wkdaysLowerCase = | 98 "Thursday", |
87 const ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; | 99 "Friday", |
88 const List weekdaysLowerCase = const ["monday", "tuesday", "wednesday", | 100 "Saturday", |
89 "thursday", "friday", "saturday", | 101 "Sunday" |
90 "sunday"]; | 102 ]; |
91 const List monthsLowerCase = const ["jan", "feb", "mar", "apr", "may", | 103 const List months = const [ |
92 "jun", "jul", "aug", "sep", "oct", | 104 "Jan", |
93 "nov", "dec"]; | 105 "Feb", |
| 106 "Mar", |
| 107 "Apr", |
| 108 "May", |
| 109 "Jun", |
| 110 "Jul", |
| 111 "Aug", |
| 112 "Sep", |
| 113 "Oct", |
| 114 "Nov", |
| 115 "Dec" |
| 116 ]; |
| 117 const List wkdaysLowerCase = const [ |
| 118 "mon", |
| 119 "tue", |
| 120 "wed", |
| 121 "thu", |
| 122 "fri", |
| 123 "sat", |
| 124 "sun" |
| 125 ]; |
| 126 const List weekdaysLowerCase = const [ |
| 127 "monday", |
| 128 "tuesday", |
| 129 "wednesday", |
| 130 "thursday", |
| 131 "friday", |
| 132 "saturday", |
| 133 "sunday" |
| 134 ]; |
| 135 const List monthsLowerCase = const [ |
| 136 "jan", |
| 137 "feb", |
| 138 "mar", |
| 139 "apr", |
| 140 "may", |
| 141 "jun", |
| 142 "jul", |
| 143 "aug", |
| 144 "sep", |
| 145 "oct", |
| 146 "nov", |
| 147 "dec" |
| 148 ]; |
94 | 149 |
95 final int formatRfc1123 = 0; | 150 final int formatRfc1123 = 0; |
96 final int formatRfc850 = 1; | 151 final int formatRfc850 = 1; |
97 final int formatAsctime = 2; | 152 final int formatAsctime = 2; |
98 | 153 |
99 int index = 0; | 154 int index = 0; |
100 String tmp; | 155 String tmp; |
101 int format; | 156 int format; |
102 | 157 |
103 void expect(String s) { | 158 void expect(String s) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 minutes = expectNum(":"); | 254 minutes = expectNum(":"); |
200 seconds = expectNum(" "); | 255 seconds = expectNum(" "); |
201 expect("GMT"); | 256 expect("GMT"); |
202 } | 257 } |
203 expectEnd(); | 258 expectEnd(); |
204 return new DateTime.utc(year, month + 1, day, hours, minutes, seconds, 0); | 259 return new DateTime.utc(year, month + 1, day, hours, minutes, seconds, 0); |
205 } | 260 } |
206 | 261 |
207 // Parse a cookie date string. | 262 // Parse a cookie date string. |
208 static DateTime _parseCookieDate(String date) { | 263 static DateTime _parseCookieDate(String date) { |
209 const List monthsLowerCase = const ["jan", "feb", "mar", "apr", "may", | 264 const List monthsLowerCase = const [ |
210 "jun", "jul", "aug", "sep", "oct", | 265 "jan", |
211 "nov", "dec"]; | 266 "feb", |
| 267 "mar", |
| 268 "apr", |
| 269 "may", |
| 270 "jun", |
| 271 "jul", |
| 272 "aug", |
| 273 "sep", |
| 274 "oct", |
| 275 "nov", |
| 276 "dec" |
| 277 ]; |
212 | 278 |
213 int position = 0; | 279 int position = 0; |
214 | 280 |
215 void error() { | 281 void error() { |
216 throw new HttpException("Invalid cookie date $date"); | 282 throw new HttpException("Invalid cookie date $date"); |
217 } | 283 } |
218 | 284 |
219 bool isEnd() => position == date.length; | 285 bool isEnd() => position == date.length; |
220 | 286 |
221 bool isDelimiter(String s) { | 287 bool isDelimiter(String s) { |
222 int char = s.codeUnitAt(0); | 288 int char = s.codeUnitAt(0); |
223 if (char == 0x09) return true; | 289 if (char == 0x09) return true; |
224 if (char >= 0x20 && char <= 0x2F) return true; | 290 if (char >= 0x20 && char <= 0x2F) return true; |
225 if (char >= 0x3B && char <= 0x40) return true; | 291 if (char >= 0x3B && char <= 0x40) return true; |
226 if (char >= 0x5B && char <= 0x60) return true; | 292 if (char >= 0x5B && char <= 0x60) return true; |
227 if (char >= 0x7B && char <= 0x7E) return true; | 293 if (char >= 0x7B && char <= 0x7E) return true; |
228 return false; | 294 return false; |
229 } | 295 } |
230 | 296 |
231 bool isNonDelimiter(String s) { | 297 bool isNonDelimiter(String s) { |
232 int char = s.codeUnitAt(0); | 298 int char = s.codeUnitAt(0); |
233 if (char >= 0x00 && char <= 0x08) return true; | 299 if (char >= 0x00 && char <= 0x08) return true; |
234 if (char >= 0x0A && char <= 0x1F) return true; | 300 if (char >= 0x0A && char <= 0x1F) return true; |
235 if (char >= 0x30 && char <= 0x39) return true; // Digit | 301 if (char >= 0x30 && char <= 0x39) return true; // Digit |
236 if (char == 0x3A) return true; // ':' | 302 if (char == 0x3A) return true; // ':' |
237 if (char >= 0x41 && char <= 0x5A) return true; // Alpha | 303 if (char >= 0x41 && char <= 0x5A) return true; // Alpha |
238 if (char >= 0x61 && char <= 0x7A) return true; // Alpha | 304 if (char >= 0x61 && char <= 0x7A) return true; // Alpha |
239 if (char >= 0x7F && char <= 0xFF) return true; // Alpha | 305 if (char >= 0x7F && char <= 0xFF) return true; // Alpha |
240 return false; | 306 return false; |
241 } | 307 } |
242 | 308 |
243 bool isDigit(String s) { | 309 bool isDigit(String s) { |
244 int char = s.codeUnitAt(0); | 310 int char = s.codeUnitAt(0); |
245 if (char > 0x2F && char < 0x3A) return true; | 311 if (char > 0x2F && char < 0x3A) return true; |
246 return false; | 312 return false; |
247 } | 313 } |
248 | 314 |
249 int getMonth(String month) { | 315 int getMonth(String month) { |
(...skipping 16 matching lines...) Expand all Loading... |
266 while (!isEnd() && isDelimiter(date[position])) position++; | 332 while (!isEnd() && isDelimiter(date[position])) position++; |
267 } | 333 } |
268 | 334 |
269 String timeStr; | 335 String timeStr; |
270 String dayOfMonthStr; | 336 String dayOfMonthStr; |
271 String monthStr; | 337 String monthStr; |
272 String yearStr; | 338 String yearStr; |
273 | 339 |
274 for (var token in tokens) { | 340 for (var token in tokens) { |
275 if (token.length < 1) continue; | 341 if (token.length < 1) continue; |
276 if (timeStr == null && token.length >= 5 && isDigit(token[0]) && | 342 if (timeStr == null && |
| 343 token.length >= 5 && |
| 344 isDigit(token[0]) && |
277 (token[1] == ":" || (isDigit(token[1]) && token[2] == ":"))) { | 345 (token[1] == ":" || (isDigit(token[1]) && token[2] == ":"))) { |
278 timeStr = token; | 346 timeStr = token; |
279 } else if (dayOfMonthStr == null && isDigit(token[0])) { | 347 } else if (dayOfMonthStr == null && isDigit(token[0])) { |
280 dayOfMonthStr = token; | 348 dayOfMonthStr = token; |
281 } else if (monthStr == null && getMonth(token) >= 0) { | 349 } else if (monthStr == null && getMonth(token) >= 0) { |
282 monthStr = token; | 350 monthStr = token; |
283 } else if (yearStr == null && token.length >= 2 && | 351 } else if (yearStr == null && |
284 isDigit(token[0]) && isDigit(token[1])) { | 352 token.length >= 2 && |
| 353 isDigit(token[0]) && |
| 354 isDigit(token[1])) { |
285 yearStr = token; | 355 yearStr = token; |
286 } | 356 } |
287 } | 357 } |
288 | 358 |
289 if (timeStr == null || dayOfMonthStr == null || | 359 if (timeStr == null || |
290 monthStr == null || yearStr == null) { | 360 dayOfMonthStr == null || |
| 361 monthStr == null || |
| 362 yearStr == null) { |
291 error(); | 363 error(); |
292 } | 364 } |
293 | 365 |
294 int year = toInt(yearStr); | 366 int year = toInt(yearStr); |
295 if (year >= 70 && year <= 99) year += 1900; | 367 if (year >= 70 && year <= 99) |
| 368 year += 1900; |
296 else if (year >= 0 && year <= 69) year += 2000; | 369 else if (year >= 0 && year <= 69) year += 2000; |
297 if (year < 1601) error(); | 370 if (year < 1601) error(); |
298 | 371 |
299 int dayOfMonth = toInt(dayOfMonthStr); | 372 int dayOfMonth = toInt(dayOfMonthStr); |
300 if (dayOfMonth < 1 || dayOfMonth > 31) error(); | 373 if (dayOfMonth < 1 || dayOfMonth > 31) error(); |
301 | 374 |
302 int month = getMonth(monthStr) + 1; | 375 int month = getMonth(monthStr) + 1; |
303 | 376 |
304 var timeList = timeStr.split(":"); | 377 var timeList = timeStr.split(":"); |
305 if (timeList.length != 3) error(); | 378 if (timeList.length != 3) error(); |
306 int hour = toInt(timeList[0]); | 379 int hour = toInt(timeList[0]); |
307 int minute = toInt(timeList[1]); | 380 int minute = toInt(timeList[1]); |
308 int second = toInt(timeList[2]); | 381 int second = toInt(timeList[2]); |
309 if (hour > 23) error(); | 382 if (hour > 23) error(); |
310 if (minute > 59) error(); | 383 if (minute > 59) error(); |
311 if (second > 59) error(); | 384 if (second > 59) error(); |
312 | 385 |
313 return new DateTime.utc(year, month, dayOfMonth, hour, minute, second, 0); | 386 return new DateTime.utc(year, month, dayOfMonth, hour, minute, second, 0); |
314 } | 387 } |
315 } | 388 } |
OLD | NEW |