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 // Dart core library. | 4 // Dart core library. |
5 | 5 |
6 // VM implementation of DateTime. | 6 // VM implementation of DateTime. |
7 @patch | 7 @patch class DateTime { |
8 class DateTime { | |
9 // Natives. | 8 // Natives. |
10 // The natives have been moved up here to work around Issue 10401. | 9 // The natives have been moved up here to work around Issue 10401. |
11 static int _getCurrentMicros() native "DateTime_currentTimeMicros"; | 10 static int _getCurrentMicros() native "DateTime_currentTimeMicros"; |
12 | 11 |
13 static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch) | 12 static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch) |
14 native "DateTime_timeZoneName"; | 13 native "DateTime_timeZoneName"; |
15 | 14 |
16 static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch) | 15 static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch) |
17 native "DateTime_timeZoneOffsetInSeconds"; | 16 native "DateTime_timeZoneOffsetInSeconds"; |
18 | 17 |
19 static int _localTimeZoneAdjustmentInSeconds() | 18 static int _localTimeZoneAdjustmentInSeconds() |
20 native "DateTime_localTimeZoneAdjustmentInSeconds"; | 19 native "DateTime_localTimeZoneAdjustmentInSeconds"; |
21 | 20 |
22 static const _MICROSECOND_INDEX = 0; | 21 static const _MICROSECOND_INDEX = 0; |
23 static const _MILLISECOND_INDEX = 1; | 22 static const _MILLISECOND_INDEX = 1; |
24 static const _SECOND_INDEX = 2; | 23 static const _SECOND_INDEX = 2; |
25 static const _MINUTE_INDEX = 3; | 24 static const _MINUTE_INDEX = 3; |
26 static const _HOUR_INDEX = 4; | 25 static const _HOUR_INDEX = 4; |
27 static const _DAY_INDEX = 5; | 26 static const _DAY_INDEX = 5; |
28 static const _WEEKDAY_INDEX = 6; | 27 static const _WEEKDAY_INDEX = 6; |
29 static const _MONTH_INDEX = 7; | 28 static const _MONTH_INDEX = 7; |
30 static const _YEAR_INDEX = 8; | 29 static const _YEAR_INDEX = 8; |
31 | 30 |
32 List __parts; | 31 List __parts; |
33 | 32 |
34 @patch | 33 @patch DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, |
35 DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, | 34 {bool isUtc: false}) |
36 {bool isUtc: false}) | |
37 : this._withValue( | 35 : this._withValue( |
38 millisecondsSinceEpoch * Duration.MICROSECONDS_PER_MILLISECOND, | 36 millisecondsSinceEpoch * Duration.MICROSECONDS_PER_MILLISECOND, |
39 isUtc: isUtc); | 37 isUtc: isUtc); |
40 | 38 |
41 @patch | 39 @patch DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch, |
42 DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch, | 40 {bool isUtc: false}) |
43 {bool isUtc: false}) | |
44 : this._withValue(microsecondsSinceEpoch, isUtc: isUtc); | 41 : this._withValue(microsecondsSinceEpoch, isUtc: isUtc); |
45 | 42 |
46 @patch | 43 @patch DateTime._internal(int year, |
47 DateTime._internal(int year, int month, int day, int hour, int minute, | 44 int month, |
48 int second, int millisecond, int microsecond, bool isUtc) | 45 int day, |
| 46 int hour, |
| 47 int minute, |
| 48 int second, |
| 49 int millisecond, |
| 50 int microsecond, |
| 51 bool isUtc) |
49 : this.isUtc = isUtc, | 52 : this.isUtc = isUtc, |
50 this._value = _brokenDownDateToValue(year, month, day, hour, minute, | 53 this._value = _brokenDownDateToValue( |
51 second, millisecond, microsecond, isUtc) { | 54 year, month, day, hour, minute, second, millisecond, microsecond, |
| 55 isUtc) { |
52 if (_value == null) throw new ArgumentError(); | 56 if (_value == null) throw new ArgumentError(); |
53 if (isUtc == null) throw new ArgumentError(); | 57 if (isUtc == null) throw new ArgumentError(); |
54 } | 58 } |
55 | 59 |
56 @patch | 60 @patch DateTime._now() |
57 DateTime._now() | |
58 : isUtc = false, | 61 : isUtc = false, |
59 _value = _getCurrentMicros() {} | 62 _value = _getCurrentMicros() { |
| 63 } |
60 | 64 |
61 @patch | 65 @patch String get timeZoneName { |
62 String get timeZoneName { | |
63 if (isUtc) return "UTC"; | 66 if (isUtc) return "UTC"; |
64 return _timeZoneName(microsecondsSinceEpoch); | 67 return _timeZoneName(microsecondsSinceEpoch); |
65 } | 68 } |
66 | 69 |
67 @patch | 70 @patch Duration get timeZoneOffset { |
68 Duration get timeZoneOffset { | |
69 if (isUtc) return new Duration(); | 71 if (isUtc) return new Duration(); |
70 int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch); | 72 int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch); |
71 return new Duration(seconds: offsetInSeconds); | 73 return new Duration(seconds: offsetInSeconds); |
72 } | 74 } |
73 | 75 |
74 /** The first list contains the days until each month in non-leap years. The | 76 /** The first list contains the days until each month in non-leap years. The |
75 * second list contains the days in leap years. */ | 77 * second list contains the days in leap years. */ |
76 static const List<List<int>> _DAYS_UNTIL_MONTH = const [ | 78 static const List<List<int>> _DAYS_UNTIL_MONTH = |
77 const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], | 79 const [const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], |
78 const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335] | 80 const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]]; |
79 ]; | |
80 | 81 |
81 static List _computeUpperPart(int localMicros) { | 82 static List _computeUpperPart(int localMicros) { |
82 const int DAYS_IN_4_YEARS = 4 * 365 + 1; | 83 const int DAYS_IN_4_YEARS = 4 * 365 + 1; |
83 const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; | 84 const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; |
84 const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1; | 85 const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1; |
85 const int DAYS_1970_TO_2000 = 30 * 365 + 7; | 86 const int DAYS_1970_TO_2000 = 30 * 365 + 7; |
86 const int DAYS_OFFSET = | 87 const int DAYS_OFFSET = 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - |
87 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - DAYS_1970_TO_2000; | 88 DAYS_1970_TO_2000; |
88 const int YEARS_OFFSET = 400000; | 89 const int YEARS_OFFSET = 400000; |
89 | 90 |
90 int resultYear = 0; | 91 int resultYear = 0; |
91 int resultMonth = 0; | 92 int resultMonth = 0; |
92 int resultDay = 0; | 93 int resultDay = 0; |
93 | 94 |
94 // Always round down. | 95 // Always round down. |
95 final int daysSince1970 = | 96 final int daysSince1970 = _flooredDivision(localMicros, |
96 _flooredDivision(localMicros, Duration.MICROSECONDS_PER_DAY); | 97 Duration.MICROSECONDS_PER_DAY); |
97 int days = daysSince1970; | 98 int days = daysSince1970; |
98 days += DAYS_OFFSET; | 99 days += DAYS_OFFSET; |
99 resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET; | 100 resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET; |
100 days = days.remainder(DAYS_IN_400_YEARS); | 101 days = days.remainder(DAYS_IN_400_YEARS); |
101 days--; | 102 days--; |
102 int yd1 = days ~/ DAYS_IN_100_YEARS; | 103 int yd1 = days ~/ DAYS_IN_100_YEARS; |
103 days = days.remainder(DAYS_IN_100_YEARS); | 104 days = days.remainder(DAYS_IN_100_YEARS); |
104 resultYear += 100 * yd1; | 105 resultYear += 100 * yd1; |
105 days++; | 106 days++; |
106 int yd2 = days ~/ DAYS_IN_4_YEARS; | 107 int yd2 = days ~/ DAYS_IN_4_YEARS; |
107 days = days.remainder(DAYS_IN_4_YEARS); | 108 days = days.remainder(DAYS_IN_4_YEARS); |
108 resultYear += 4 * yd2; | 109 resultYear += 4 * yd2; |
109 days--; | 110 days--; |
110 int yd3 = days ~/ 365; | 111 int yd3 = days ~/ 365; |
111 days = days.remainder(365); | 112 days = days.remainder(365); |
112 resultYear += yd3; | 113 resultYear += yd3; |
113 | 114 |
114 bool isLeap = (yd1 == 0 || yd2 != 0) && yd3 == 0; | 115 bool isLeap = (yd1 == 0 || yd2 != 0) && yd3 == 0; |
115 if (isLeap) days++; | 116 if (isLeap) days++; |
116 | 117 |
117 List<int> daysUntilMonth = _DAYS_UNTIL_MONTH[isLeap ? 1 : 0]; | 118 List<int> daysUntilMonth = _DAYS_UNTIL_MONTH[isLeap ? 1 : 0]; |
118 for (resultMonth = 12; | 119 for (resultMonth = 12; |
119 daysUntilMonth[resultMonth - 1] > days; | 120 daysUntilMonth[resultMonth - 1] > days; |
120 resultMonth--) { | 121 resultMonth--) { |
121 // Do nothing. | 122 // Do nothing. |
122 } | 123 } |
123 resultDay = days - daysUntilMonth[resultMonth - 1] + 1; | 124 resultDay = days - daysUntilMonth[resultMonth - 1] + 1; |
124 | 125 |
125 int resultMicrosecond = localMicros % Duration.MICROSECONDS_PER_MILLISECOND; | 126 int resultMicrosecond = localMicros % Duration.MICROSECONDS_PER_MILLISECOND; |
126 int resultMillisecond = | 127 int resultMillisecond = |
127 _flooredDivision(localMicros, Duration.MICROSECONDS_PER_MILLISECOND) % | 128 _flooredDivision(localMicros, Duration.MICROSECONDS_PER_MILLISECOND) % |
128 Duration.MILLISECONDS_PER_SECOND; | 129 Duration.MILLISECONDS_PER_SECOND; |
129 int resultSecond = | 130 int resultSecond = |
130 _flooredDivision(localMicros, Duration.MICROSECONDS_PER_SECOND) % | 131 _flooredDivision(localMicros, Duration.MICROSECONDS_PER_SECOND) % |
131 Duration.SECONDS_PER_MINUTE; | 132 Duration.SECONDS_PER_MINUTE; |
132 | 133 |
133 int resultMinute = | 134 int resultMinute = _flooredDivision(localMicros, |
134 _flooredDivision(localMicros, Duration.MICROSECONDS_PER_MINUTE); | 135 Duration.MICROSECONDS_PER_MINUTE); |
135 resultMinute %= Duration.MINUTES_PER_HOUR; | 136 resultMinute %= Duration.MINUTES_PER_HOUR; |
136 | 137 |
137 int resultHour = | 138 int resultHour = |
138 _flooredDivision(localMicros, Duration.MICROSECONDS_PER_HOUR); | 139 _flooredDivision(localMicros, Duration.MICROSECONDS_PER_HOUR); |
139 resultHour %= Duration.HOURS_PER_DAY; | 140 resultHour %= Duration.HOURS_PER_DAY; |
140 | 141 |
141 // In accordance with ISO 8601 a week | 142 // In accordance with ISO 8601 a week |
142 // starts with Monday. Monday has the value 1 up to Sunday with 7. | 143 // starts with Monday. Monday has the value 1 up to Sunday with 7. |
143 // 1970-1-1 was a Thursday. | 144 // 1970-1-1 was a Thursday. |
144 int resultWeekday = ((daysSince1970 + DateTime.THURSDAY - DateTime.MONDAY) % | 145 int resultWeekday = ((daysSince1970 + DateTime.THURSDAY - DateTime.MONDAY) % |
145 DateTime.DAYS_PER_WEEK) + | 146 DateTime.DAYS_PER_WEEK) + DateTime.MONDAY; |
146 DateTime.MONDAY; | |
147 | 147 |
148 List list = new List(_YEAR_INDEX + 1); | 148 List list = new List(_YEAR_INDEX + 1); |
149 list[_MICROSECOND_INDEX] = resultMicrosecond; | 149 list[_MICROSECOND_INDEX] = resultMicrosecond; |
150 list[_MILLISECOND_INDEX] = resultMillisecond; | 150 list[_MILLISECOND_INDEX] = resultMillisecond; |
151 list[_SECOND_INDEX] = resultSecond; | 151 list[_SECOND_INDEX] = resultSecond; |
152 list[_MINUTE_INDEX] = resultMinute; | 152 list[_MINUTE_INDEX] = resultMinute; |
153 list[_HOUR_INDEX] = resultHour; | 153 list[_HOUR_INDEX] = resultHour; |
154 list[_DAY_INDEX] = resultDay; | 154 list[_DAY_INDEX] = resultDay; |
155 list[_WEEKDAY_INDEX] = resultWeekday; | 155 list[_WEEKDAY_INDEX] = resultWeekday; |
156 list[_MONTH_INDEX] = resultMonth; | 156 list[_MONTH_INDEX] = resultMonth; |
157 list[_YEAR_INDEX] = resultYear; | 157 list[_YEAR_INDEX] = resultYear; |
158 return list; | 158 return list; |
159 } | 159 } |
160 | 160 |
161 get _parts { | 161 get _parts { |
162 if (__parts == null) { | 162 if (__parts == null) { |
163 __parts = _computeUpperPart(_localDateInUtcMicros); | 163 __parts = _computeUpperPart(_localDateInUtcMicros); |
164 } | 164 } |
165 return __parts; | 165 return __parts; |
166 } | 166 } |
167 | 167 |
168 @patch | 168 @patch DateTime add(Duration duration) { |
169 DateTime add(Duration duration) { | 169 return new DateTime._withValue( |
170 return new DateTime._withValue(_value + duration.inMicroseconds, | 170 _value + duration.inMicroseconds, isUtc: isUtc); |
171 isUtc: isUtc); | |
172 } | 171 } |
173 | 172 |
174 @patch | 173 @patch DateTime subtract(Duration duration) { |
175 DateTime subtract(Duration duration) { | 174 return new DateTime._withValue( |
176 return new DateTime._withValue(_value - duration.inMicroseconds, | 175 _value - duration.inMicroseconds, isUtc: isUtc); |
177 isUtc: isUtc); | |
178 } | 176 } |
179 | 177 |
180 @patch | 178 @patch Duration difference(DateTime other) { |
181 Duration difference(DateTime other) { | |
182 return new Duration(microseconds: _value - other._value); | 179 return new Duration(microseconds: _value - other._value); |
183 } | 180 } |
184 | 181 |
185 @patch | 182 @patch int get millisecondsSinceEpoch => |
186 int get millisecondsSinceEpoch => | |
187 _value ~/ Duration.MICROSECONDS_PER_MILLISECOND; | 183 _value ~/ Duration.MICROSECONDS_PER_MILLISECOND; |
188 | 184 |
189 @patch | 185 @patch int get microsecondsSinceEpoch => _value; |
190 int get microsecondsSinceEpoch => _value; | |
191 | 186 |
192 @patch | 187 @patch int get microsecond => _parts[_MICROSECOND_INDEX]; |
193 int get microsecond => _parts[_MICROSECOND_INDEX]; | |
194 | 188 |
195 @patch | 189 @patch int get millisecond => _parts[_MILLISECOND_INDEX]; |
196 int get millisecond => _parts[_MILLISECOND_INDEX]; | |
197 | 190 |
198 @patch | 191 @patch int get second => _parts[_SECOND_INDEX]; |
199 int get second => _parts[_SECOND_INDEX]; | |
200 | 192 |
201 @patch | 193 @patch int get minute => _parts[_MINUTE_INDEX]; |
202 int get minute => _parts[_MINUTE_INDEX]; | |
203 | 194 |
204 @patch | 195 @patch int get hour => _parts[_HOUR_INDEX]; |
205 int get hour => _parts[_HOUR_INDEX]; | |
206 | 196 |
207 @patch | 197 @patch int get day => _parts[_DAY_INDEX]; |
208 int get day => _parts[_DAY_INDEX]; | |
209 | 198 |
210 @patch | 199 @patch int get weekday => _parts[_WEEKDAY_INDEX]; |
211 int get weekday => _parts[_WEEKDAY_INDEX]; | |
212 | 200 |
213 @patch | 201 @patch int get month => _parts[_MONTH_INDEX]; |
214 int get month => _parts[_MONTH_INDEX]; | |
215 | 202 |
216 @patch | 203 @patch int get year => _parts[_YEAR_INDEX]; |
217 int get year => _parts[_YEAR_INDEX]; | |
218 | 204 |
219 /** | 205 /** |
220 * Returns the amount of microseconds in UTC that represent the same values | 206 * Returns the amount of microseconds in UTC that represent the same values |
221 * as [this]. | 207 * as [this]. |
222 * | 208 * |
223 * Say `t` is the result of this function, then | 209 * Say `t` is the result of this function, then |
224 * * `this.year == new DateTime.fromMicrosecondsSinceEpoch(t, true).year`, | 210 * * `this.year == new DateTime.fromMicrosecondsSinceEpoch(t, true).year`, |
225 * * `this.month == new DateTime.fromMicrosecondsSinceEpoch(t, true).month`, | 211 * * `this.month == new DateTime.fromMicrosecondsSinceEpoch(t, true).month`, |
226 * * `this.day == new DateTime.fromMicrosecondsSinceEpoch(t, true).day`, | 212 * * `this.day == new DateTime.fromMicrosecondsSinceEpoch(t, true).day`, |
227 * * `this.hour == new DateTime.fromMicrosecondsSinceEpoch(t, true).hour`, | 213 * * `this.hour == new DateTime.fromMicrosecondsSinceEpoch(t, true).hour`, |
(...skipping 11 matching lines...) Expand all Loading... |
239 return micros + offset; | 225 return micros + offset; |
240 } | 226 } |
241 | 227 |
242 static int _flooredDivision(int a, int b) { | 228 static int _flooredDivision(int a, int b) { |
243 return (a - (a < 0 ? b - 1 : 0)) ~/ b; | 229 return (a - (a < 0 ? b - 1 : 0)) ~/ b; |
244 } | 230 } |
245 | 231 |
246 // Returns the days since 1970 for the start of the given [year]. | 232 // Returns the days since 1970 for the start of the given [year]. |
247 // [year] may be before epoch. | 233 // [year] may be before epoch. |
248 static int _dayFromYear(int year) { | 234 static int _dayFromYear(int year) { |
249 return 365 * (year - 1970) + | 235 return 365 * (year - 1970) |
250 _flooredDivision(year - 1969, 4) - | 236 + _flooredDivision(year - 1969, 4) |
251 _flooredDivision(year - 1901, 100) + | 237 - _flooredDivision(year - 1901, 100) |
252 _flooredDivision(year - 1601, 400); | 238 + _flooredDivision(year - 1601, 400); |
253 } | 239 } |
254 | 240 |
255 static bool _isLeapYear(y) { | 241 static bool _isLeapYear(y) { |
256 // (y % 16 == 0) matches multiples of 400, and is faster than % 400. | 242 // (y % 16 == 0) matches multiples of 400, and is faster than % 400. |
257 return (y % 4 == 0) && ((y % 16 == 0) || (y % 100 != 0)); | 243 return (y % 4 == 0) && ((y % 16 == 0) || (y % 100 != 0)); |
258 } | 244 } |
259 | 245 |
260 /// Converts the given broken down date to microseconds. | 246 /// Converts the given broken down date to microseconds. |
261 @patch | 247 @patch static int _brokenDownDateToValue( |
262 static int _brokenDownDateToValue(int year, int month, int day, int hour, | 248 int year, int month, int day, |
263 int minute, int second, int millisecond, int microsecond, bool isUtc) { | 249 int hour, int minute, int second, int millisecond, int microsecond, |
| 250 bool isUtc) { |
264 // Simplify calculations by working with zero-based month. | 251 // Simplify calculations by working with zero-based month. |
265 --month; | 252 --month; |
266 // Deal with under and overflow. | 253 // Deal with under and overflow. |
267 if (month >= 12) { | 254 if (month >= 12) { |
268 year += month ~/ 12; | 255 year += month ~/ 12; |
269 month = month % 12; | 256 month = month % 12; |
270 } else if (month < 0) { | 257 } else if (month < 0) { |
271 int realMonth = month % 12; | 258 int realMonth = month % 12; |
272 year += (month - realMonth) ~/ 12; | 259 year += (month - realMonth) ~/ 12; |
273 month = realMonth; | 260 month = realMonth; |
274 } | 261 } |
275 | 262 |
276 // First compute the seconds in UTC, independent of the [isUtc] flag. If | 263 // First compute the seconds in UTC, independent of the [isUtc] flag. If |
277 // necessary we will add the time-zone offset later on. | 264 // necessary we will add the time-zone offset later on. |
278 int days = day - 1; | 265 int days = day - 1; |
279 days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month]; | 266 days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month]; |
280 days += _dayFromYear(year); | 267 days += _dayFromYear(year); |
281 int microsecondsSinceEpoch = days * Duration.MICROSECONDS_PER_DAY + | 268 int microsecondsSinceEpoch = |
282 hour * Duration.MICROSECONDS_PER_HOUR + | 269 days * Duration.MICROSECONDS_PER_DAY + |
| 270 hour * Duration.MICROSECONDS_PER_HOUR + |
283 minute * Duration.MICROSECONDS_PER_MINUTE + | 271 minute * Duration.MICROSECONDS_PER_MINUTE + |
284 second * Duration.MICROSECONDS_PER_SECOND + | 272 second * Duration.MICROSECONDS_PER_SECOND + |
285 millisecond * Duration.MICROSECONDS_PER_MILLISECOND + | 273 millisecond * Duration.MICROSECONDS_PER_MILLISECOND + |
286 microsecond; | 274 microsecond; |
287 | 275 |
288 // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of | 276 // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of |
289 // the valid range we do a preliminary test that weeds out values that can | 277 // the valid range we do a preliminary test that weeds out values that can |
290 // not become valid even with timezone adjustments. | 278 // not become valid even with timezone adjustments. |
291 // The timezone adjustment is always less than a day, so adding a security | 279 // The timezone adjustment is always less than a day, so adding a security |
292 // margin of one day should be enough. | 280 // margin of one day should be enough. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 * | 370 * |
383 * * The time since the beginning of the year is the same. | 371 * * The time since the beginning of the year is the same. |
384 * * If the given date is in a leap year then the returned | 372 * * If the given date is in a leap year then the returned |
385 * seconds are in a leap year, too. | 373 * seconds are in a leap year, too. |
386 * * The week day of given date is the same as the one for the | 374 * * The week day of given date is the same as the one for the |
387 * returned date. | 375 * returned date. |
388 */ | 376 */ |
389 static int _equivalentSeconds(int microsecondsSinceEpoch) { | 377 static int _equivalentSeconds(int microsecondsSinceEpoch) { |
390 const int CUT_OFF_SECONDS = 0x7FFFFFFF; | 378 const int CUT_OFF_SECONDS = 0x7FFFFFFF; |
391 | 379 |
392 int secondsSinceEpoch = _flooredDivision( | 380 int secondsSinceEpoch = _flooredDivision(microsecondsSinceEpoch, |
393 microsecondsSinceEpoch, Duration.MICROSECONDS_PER_SECOND); | 381 Duration.MICROSECONDS_PER_SECOND); |
394 | 382 |
395 if (secondsSinceEpoch.abs() > CUT_OFF_SECONDS) { | 383 if (secondsSinceEpoch.abs() > CUT_OFF_SECONDS) { |
396 int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch); | 384 int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch); |
397 int days = _dayFromYear(year); | 385 int days = _dayFromYear(year); |
398 int equivalentYear = _equivalentYear(year); | 386 int equivalentYear = _equivalentYear(year); |
399 int equivalentDays = _dayFromYear(equivalentYear); | 387 int equivalentDays = _dayFromYear(equivalentYear); |
400 int diffDays = equivalentDays - days; | 388 int diffDays = equivalentDays - days; |
401 secondsSinceEpoch += diffDays * Duration.SECONDS_PER_DAY; | 389 secondsSinceEpoch += diffDays * Duration.SECONDS_PER_DAY; |
402 } | 390 } |
403 return secondsSinceEpoch; | 391 return secondsSinceEpoch; |
404 } | 392 } |
405 | 393 |
406 static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) { | 394 static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) { |
407 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); | 395 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); |
408 return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds); | 396 return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds); |
409 } | 397 } |
410 | 398 |
411 static String _timeZoneName(int microsecondsSinceEpoch) { | 399 static String _timeZoneName(int microsecondsSinceEpoch) { |
412 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); | 400 int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); |
413 return _timeZoneNameForClampedSeconds(equivalentSeconds); | 401 return _timeZoneNameForClampedSeconds(equivalentSeconds); |
414 } | 402 } |
415 } | 403 } |
OLD | NEW |