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

Side by Side Diff: client/util/DateUtils.dart

Issue 9382027: Move client/{base, observable, layout, touch, util, view} to samples/ui_lib . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « client/util/CollectionUtils.dart ('k') | client/util/StringUtils.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /**
6 * General purpose date/time utilities.
7 */
8 class DateUtils {
9 // TODO(jmesserly): localized strings
10 static final WEEKDAYS = const ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
11 'Friday', 'Saturday', 'Sunday'];
12
13 static final YESTERDAY = 'Yesterday';
14
15 static final MS_IN_WEEK = Date.DAYS_IN_WEEK * Duration.MILLISECONDS_PER_DAY;
16
17 // TODO(jmesserly): workaround for missing Date.fromDate in Dartium
18 // Remove this once that is implemented. See b/5055106
19 // Parse a string like: "Mon, 27 Jun 2011 15:22:00 -0700"
20 static Date fromString(String text) {
21 final parts = text.split(' ');
22 if (parts.length == 1) {
23 return _parseIsoDate(text);
24 }
25
26 if (parts.length != 6) {
27 throw 'bad date format, expected 6 parts: ' + text;
28 }
29
30 // skip parts[0], the weekday
31
32 int day = Math.parseInt(parts[1]);
33
34 final months = const['Jan', 'Feb', 'Mar', 'Apr',
35 'May', 'Jun', 'Jul', 'Aug',
36 'Sep', 'Oct', 'Nov', 'Dec'];
37 int month = months.indexOf(parts[2], 0) + 1;
38 if (month < 0) {
39 throw 'bad month, expected 3 letter month code, got: ' + parts[2];
40 }
41
42 int year = Math.parseInt(parts[3]);
43
44 final timeParts = parts[4].split(':');
45 if (timeParts.length != 3) {
46 throw 'bad time format, expected 3 parts: ' + parts[4];
47 }
48
49 int hours = Math.parseInt(timeParts[0]);
50 int minutes = Math.parseInt(timeParts[1]);
51 int seconds = Math.parseInt(timeParts[2]);
52
53 // TODO(jmesserly): TimeZone is not implemented in Dartium. This ugly
54 // hack applies the timezone from the string to the final time
55 int zoneOffset = Math.parseInt(parts[5]) ~/ 100;
56
57 // Pretend it's a UTC time
58 Date result = new Date.withTimeZone(
59 year, month, day, hours, minutes, seconds, 0, new TimeZone.utc());
60 // Shift it to the proper zone, but it's still a UTC time
61 result = result.subtract(new Duration(hours: zoneOffset));
62 // Then render it as a local time
63 return result.changeTimeZone(new TimeZone.local());
64 }
65
66 /** Parse a string like: 2011-07-19T22:03:04.000Z */
67 // TODO(jmesserly): workaround for Date.fromDate, which has issues:
68 // * on Dart VM it doesn't handle all of ISO 8601. See b/5055106.
69 // * on DartC it doesn't work on Safari. See b/5062557.
70 // Remove this once that function is fully implemented
71 static Date _parseIsoDate(String text) {
72 void ensure(bool value) {
73 if (!value) {
74 throw 'bad date format, expected YYYY-MM-DDTHH:MM:SS.mmmZ: ' + text;
75 }
76 }
77
78 TimeZone zone;
79 if (text.endsWith('Z')) {
80 text = text.substring(0, text.length - 1);
81 zone = new TimeZone.utc();
82 } else {
83 zone = new TimeZone.local();
84 }
85
86 final parts = text.split('T');
87 ensure(parts.length == 2);
88
89 final date = parts[0].split('-');
90 ensure(date.length == 3);
91
92 final time = parts[1].split(':');
93 ensure(time.length == 3);
94
95 final seconds = time[2].split('.');
96 ensure(seconds.length >= 1 && seconds.length <= 2);
97 int milliseconds = 0;
98 if (seconds.length == 2) {
99 milliseconds = Math.parseInt(seconds[1]);
100 }
101
102 return new Date.withTimeZone(
103 Math.parseInt(date[0]),
104 Math.parseInt(date[1]),
105 Math.parseInt(date[2]),
106 Math.parseInt(time[0]),
107 Math.parseInt(time[1]),
108 Math.parseInt(seconds[0]),
109 milliseconds,
110 zone);
111 }
112
113 /**
114 * A date/time formatter that takes into account the current date/time:
115 * - if it's from today, just show the time
116 * - if it's from yesterday, just show 'Yesterday'
117 * - if it's from the same week, just show the weekday
118 * - otherwise, show just the date
119 */
120 static String toRecentTimeString(Date then) {
121 bool datesAreEqual(Date d1, Date d2) {
122 return (d1.year == d2.year) && (d1.month == d2.month) &&
123 (d1.day == d2.day);
124 }
125
126 final now = new Date.now();
127 if (datesAreEqual(then, now)) {
128 return toHourMinutesString(new Duration(
129 0, then.hours, then.minutes, then.seconds, then.milliseconds));
130 }
131
132 final today = new Date(now.year, now.month, now.day, 0, 0, 0, 0);
133 Duration delta = today.difference(then);
134 if (delta.inMilliseconds < Duration.MILLISECONDS_PER_DAY) {
135 return YESTERDAY;
136 } else if (delta.inMilliseconds < MS_IN_WEEK) {
137 return WEEKDAYS[getWeekday(then)];
138 } else {
139 // TODO(jmesserly): locale specific date format
140 String twoDigits(int n) {
141 if (n >= 10) return "${n}";
142 return "0${n}";
143 }
144 String twoDigitMonth = twoDigits(then.month);
145 String twoDigitDay = twoDigits(then.day);
146 return "${then.year}-${twoDigitMonth}-${twoDigitDay}";
147 }
148 }
149
150 // TODO(jmesserly): this is a workaround for unimplemented Date.weekday
151 // Code inspired by v8/src/date.js
152 static int getWeekday(Date dateTime) {
153 final unixTimeStart = new Date(1970, 1, 1, 0, 0, 0, 0);
154 int msSince1970 = dateTime.difference(unixTimeStart).inMilliseconds;
155 int daysSince1970 = msSince1970 ~/ Duration.MILLISECONDS_PER_DAY;
156 // 1970-1-1 was Thursday
157 return ((daysSince1970 + Date.THU) % Date.DAYS_IN_WEEK);
158 }
159
160 /** Formats a time in H:MM A format */
161 // TODO(jmesserly): should get 12 vs 24 hour clock setting from the locale
162 static String toHourMinutesString(Duration duration) {
163 assert(duration.inDays == 0);
164 int hours = duration.inHours;
165 String a;
166 if (hours >= 12) {
167 a = 'pm';
168 if (hours != 12) {
169 hours -= 12;
170 }
171 } else {
172 a = 'am';
173 if (hours == 0) {
174 hours += 12;
175 }
176 }
177 String twoDigits(int n) {
178 if (n >= 10) return "${n}";
179 return "0${n}";
180 }
181 String mm =
182 twoDigits(duration.inMinutes.remainder(Duration.MINUTES_PER_HOUR));
183 return "${hours}:${mm} ${a}";
184 }
185 }
OLDNEW
« no previous file with comments | « client/util/CollectionUtils.dart ('k') | client/util/StringUtils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698