| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 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 | 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 class TimeZoneImplementation implements TimeZone { | 6 class TimeZoneImplementation implements TimeZone { |
| 7 const TimeZoneImplementation.utc() : isUtc = true; | 7 const TimeZoneImplementation.utc() : isUtc = true; |
| 8 TimeZoneImplementation.local() : isUtc = false {} | 8 TimeZoneImplementation.local() : isUtc = false {} |
| 9 | 9 |
| 10 bool operator ==(Object other) { | 10 bool operator ==(Object other) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 TimeZone timeZone) | 40 TimeZone timeZone) |
| 41 : timeZone = timeZone, | 41 : timeZone = timeZone, |
| 42 value = _brokenDownDateToMillisecondsSinceEpoch( | 42 value = _brokenDownDateToMillisecondsSinceEpoch( |
| 43 years, month, day, hours, minutes, seconds, milliseconds, | 43 years, month, day, hours, minutes, seconds, milliseconds, |
| 44 timeZone.isUtc) { | 44 timeZone.isUtc) { |
| 45 if (value === null) throw new IllegalArgumentException(); | 45 if (value === null) throw new IllegalArgumentException(); |
| 46 } | 46 } |
| 47 | 47 |
| 48 DateImplementation.now() | 48 DateImplementation.now() |
| 49 : timeZone = new TimeZone.local(), | 49 : timeZone = new TimeZone.local(), |
| 50 value = getCurrentMs_() { | 50 value = _getCurrentMs() { |
| 51 } | 51 } |
| 52 | 52 |
| 53 factory DateImplementation.fromString(String formattedString) { | 53 factory DateImplementation.fromString(String formattedString) { |
| 54 // Read in (a subset of) ISO 8601. | 54 // Read in (a subset of) ISO 8601. |
| 55 // Examples: | 55 // Examples: |
| 56 // - "2012-02-27 13:27:00" | 56 // - "2012-02-27 13:27:00" |
| 57 // - "2012-02-27 13:27:00.423z" | 57 // - "2012-02-27 13:27:00.423z" |
| 58 // - "20120227 13:27:00" | 58 // - "20120227 13:27:00" |
| 59 // - "20120227T132700" | 59 // - "20120227T132700" |
| 60 // - "20120227" | 60 // - "20120227" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 int hashCode() => value; | 124 int hashCode() => value; |
| 125 | 125 |
| 126 Date changeTimeZone(TimeZone targetTimeZone) { | 126 Date changeTimeZone(TimeZone targetTimeZone) { |
| 127 if (targetTimeZone === null) { | 127 if (targetTimeZone === null) { |
| 128 targetTimeZone = new TimeZoneImplementation.local(); | 128 targetTimeZone = new TimeZoneImplementation.local(); |
| 129 } | 129 } |
| 130 return new Date.fromEpoch(value, targetTimeZone); | 130 return new Date.fromEpoch(value, targetTimeZone); |
| 131 } | 131 } |
| 132 | 132 |
| 133 int get year() { | 133 int get year() { |
| 134 int secondsSinceEpoch = secondsSinceEpoch_; | 134 int secondsSinceEpoch = _secondsSinceEpoch; |
| 135 // According to V8 some library calls have troubles with negative values. | 135 // According to V8 some library calls have troubles with negative values. |
| 136 // Therefore clamp to 0 - year 2035 (which is less than the size of 32bit). | 136 // Therefore clamp to 0 - year 2035 (which is less than the size of 32bit). |
| 137 if (secondsSinceEpoch >= 0 && secondsSinceEpoch < SECONDS_YEAR_2035_) { | 137 if (secondsSinceEpoch >= 0 && secondsSinceEpoch < _SECONDS_YEAR_2035) { |
| 138 return getYear_(secondsSinceEpoch, timeZone.isUtc); | 138 return _getYear(secondsSinceEpoch, timeZone.isUtc); |
| 139 } | 139 } |
| 140 | 140 |
| 141 // Approximate the result. We don't take timeZone into account. | 141 // Approximate the result. We don't take timeZone into account. |
| 142 int approximateYear = yearsFromSecondsSinceEpoch_(secondsSinceEpoch); | 142 int approximateYear = _yearsFromSecondsSinceEpoch(secondsSinceEpoch); |
| 143 int equivalentYear = equivalentYear_(approximateYear); | 143 int equivalentYear = _equivalentYear(approximateYear); |
| 144 int y = getYear_(equivalentSeconds_(secondsSinceEpoch_), timeZone.isUtc); | 144 int y = _getYear(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); |
| 145 return approximateYear + (y - equivalentYear); | 145 return approximateYear + (y - equivalentYear); |
| 146 } | 146 } |
| 147 | 147 |
| 148 int get month() { | 148 int get month() { |
| 149 return getMonth_(equivalentSeconds_(secondsSinceEpoch_), timeZone.isUtc); | 149 return _getMonth(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); |
| 150 } | 150 } |
| 151 | 151 |
| 152 int get day() { | 152 int get day() { |
| 153 return getDay_(equivalentSeconds_(secondsSinceEpoch_), timeZone.isUtc); | 153 return _getDay(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); |
| 154 } | 154 } |
| 155 | 155 |
| 156 int get hours() { | 156 int get hours() { |
| 157 return getHours_(equivalentSeconds_(secondsSinceEpoch_), timeZone.isUtc); | 157 return _getHours(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); |
| 158 } | 158 } |
| 159 | 159 |
| 160 int get minutes() { | 160 int get minutes() { |
| 161 return getMinutes_(equivalentSeconds_(secondsSinceEpoch_), timeZone.isUtc); | 161 return _getMinutes(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); |
| 162 } | 162 } |
| 163 | 163 |
| 164 int get seconds() { | 164 int get seconds() { |
| 165 return getSeconds_(equivalentSeconds_(secondsSinceEpoch_), timeZone.isUtc); | 165 return _getSeconds(_equivalentSeconds(_secondsSinceEpoch), timeZone.isUtc); |
| 166 } | 166 } |
| 167 | 167 |
| 168 int get milliseconds() { | 168 int get milliseconds() { |
| 169 return value % Duration.MILLISECONDS_PER_SECOND; | 169 return value % Duration.MILLISECONDS_PER_SECOND; |
| 170 } | 170 } |
| 171 | 171 |
| 172 int get secondsSinceEpoch_() { | 172 int get _secondsSinceEpoch() { |
| 173 // Always round down. | 173 // Always round down. |
| 174 if (value < 0) { | 174 if (value < 0) { |
| 175 return (value + 1) ~/ Duration.MILLISECONDS_PER_SECOND - 1; | 175 return (value + 1) ~/ Duration.MILLISECONDS_PER_SECOND - 1; |
| 176 } else { | 176 } else { |
| 177 return value ~/ Duration.MILLISECONDS_PER_SECOND; | 177 return value ~/ Duration.MILLISECONDS_PER_SECOND; |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 | 180 |
| 181 int get weekday() { | 181 int get weekday() { |
| 182 final Date unixTimeStart = | 182 final Date unixTimeStart = |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 } | 252 } |
| 253 | 253 |
| 254 // Returns a [Duration] with the difference of [this] and [other]. | 254 // Returns a [Duration] with the difference of [this] and [other]. |
| 255 Duration difference(Date other) { | 255 Duration difference(Date other) { |
| 256 return new DurationImplementation(milliseconds: value - other.value); | 256 return new DurationImplementation(milliseconds: value - other.value); |
| 257 } | 257 } |
| 258 | 258 |
| 259 final int value; | 259 final int value; |
| 260 final TimeZoneImplementation timeZone; | 260 final TimeZoneImplementation timeZone; |
| 261 | 261 |
| 262 static final int SECONDS_YEAR_2035_ = 2051222400; | 262 static final int _SECONDS_YEAR_2035 = 2051222400; |
| 263 | 263 |
| 264 // Returns the UTC year for the corresponding [secondsSinceEpoch]. | 264 // Returns the UTC year for the corresponding [secondsSinceEpoch]. |
| 265 // It is relatively fast for values in the range 0 to year 2098. | 265 // It is relatively fast for values in the range 0 to year 2098. |
| 266 // Code is adapted from V8. | 266 // Code is adapted from V8. |
| 267 static int yearsFromSecondsSinceEpoch_(int secondsSinceEpoch) { | 267 static int _yearsFromSecondsSinceEpoch(int secondsSinceEpoch) { |
| 268 final int DAYS_IN_4_YEARS = 4 * 365 + 1; | 268 final int DAYS_IN_4_YEARS = 4 * 365 + 1; |
| 269 final int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; | 269 final int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; |
| 270 final int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1; | 270 final int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1; |
| 271 final int DAYS_1970_TO_2000 = 30 * 365 + 7; | 271 final int DAYS_1970_TO_2000 = 30 * 365 + 7; |
| 272 final int DAYS_OFFSET = 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - | 272 final int DAYS_OFFSET = 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - |
| 273 DAYS_1970_TO_2000; | 273 DAYS_1970_TO_2000; |
| 274 final int YEARS_OFFSET = 400000; | 274 final int YEARS_OFFSET = 400000; |
| 275 final int DAYS_YEAR_2098 = DAYS_IN_100_YEARS + 6 * DAYS_IN_4_YEARS; | 275 final int DAYS_YEAR_2098 = DAYS_IN_100_YEARS + 6 * DAYS_IN_4_YEARS; |
| 276 | 276 |
| 277 int days = secondsSinceEpoch ~/ Duration.SECONDS_PER_DAY; | 277 int days = secondsSinceEpoch ~/ Duration.SECONDS_PER_DAY; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 292 result += 4 * yd2; | 292 result += 4 * yd2; |
| 293 days--; | 293 days--; |
| 294 int yd3 = days ~/ 365; | 294 int yd3 = days ~/ 365; |
| 295 days = days.remainder(365); | 295 days = days.remainder(365); |
| 296 result += yd3; | 296 result += yd3; |
| 297 return result; | 297 return result; |
| 298 } | 298 } |
| 299 } | 299 } |
| 300 | 300 |
| 301 // Given [secondsSinceEpoch] returns seconds such that they are at the same | 301 // Given [secondsSinceEpoch] returns seconds such that they are at the same |
| 302 // time in an equivalent year (see [equivalentYear_]). | 302 // time in an equivalent year (see [_equivalentYear]). |
| 303 // Leap seconds are ignored. | 303 // Leap seconds are ignored. |
| 304 static int equivalentSeconds_(int secondsSinceEpoch) { | 304 static int _equivalentSeconds(int secondsSinceEpoch) { |
| 305 if (secondsSinceEpoch >= 0 && secondsSinceEpoch < SECONDS_YEAR_2035_) { | 305 if (secondsSinceEpoch >= 0 && secondsSinceEpoch < _SECONDS_YEAR_2035) { |
| 306 return secondsSinceEpoch; | 306 return secondsSinceEpoch; |
| 307 } | 307 } |
| 308 int year = yearsFromSecondsSinceEpoch_(secondsSinceEpoch); | 308 int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch); |
| 309 int days = dayFromYear_(year); | 309 int days = _dayFromYear(year); |
| 310 int equivalentYear = equivalentYear_(year); | 310 int equivalentYear = _equivalentYear(year); |
| 311 int equivalentDays = dayFromYear_(equivalentYear); | 311 int equivalentDays = _dayFromYear(equivalentYear); |
| 312 int diffDays = equivalentDays - days; | 312 int diffDays = equivalentDays - days; |
| 313 return secondsSinceEpoch + diffDays * Duration.SECONDS_PER_DAY; | 313 return secondsSinceEpoch + diffDays * Duration.SECONDS_PER_DAY; |
| 314 } | 314 } |
| 315 | 315 |
| 316 // Returns the days since 1970 for the start of the given [year]. | 316 // Returns the days since 1970 for the start of the given [year]. |
| 317 // [year] may be before epoch. | 317 // [year] may be before epoch. |
| 318 static int dayFromYear_(int year) { | 318 static int _dayFromYear(int year) { |
| 319 int flooredDivision(int a, int b) { | 319 int flooredDivision(int a, int b) { |
| 320 return (a - (a < 0 ? b - 1 : 0)) ~/ b; | 320 return (a - (a < 0 ? b - 1 : 0)) ~/ b; |
| 321 } | 321 } |
| 322 | 322 |
| 323 return 365 * (year - 1970) | 323 return 365 * (year - 1970) |
| 324 + flooredDivision(year - 1969, 4) | 324 + flooredDivision(year - 1969, 4) |
| 325 - flooredDivision(year - 1901, 100) | 325 - flooredDivision(year - 1901, 100) |
| 326 + flooredDivision(year - 1601, 400); | 326 + flooredDivision(year - 1601, 400); |
| 327 } | 327 } |
| 328 | 328 |
| 329 // Returns a year in the range 2008-2035 matching | 329 // Returns a year in the range 2008-2035 matching |
| 330 // - leap year, and | 330 // - leap year, and |
| 331 // - week day of first day. | 331 // - week day of first day. |
| 332 // Leap seconds are ignored. | 332 // Leap seconds are ignored. |
| 333 // Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9. | 333 // Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9. |
| 334 static equivalentYear_(int year) { | 334 static _equivalentYear(int year) { |
| 335 // Returns 1 if in leap year. 0 otherwise. | 335 // Returns 1 if in leap year. 0 otherwise. |
| 336 bool inLeapYear(year) { | 336 bool inLeapYear(year) { |
| 337 return (year.remainder(4) == 0) && | 337 return (year.remainder(4) == 0) && |
| 338 ((year.remainder(100) != 0) || (year.remainder(400) == 0)); | 338 ((year.remainder(100) != 0) || (year.remainder(400) == 0)); |
| 339 } | 339 } |
| 340 | 340 |
| 341 // Returns the week day (in range 0 - 6). | 341 // Returns the week day (in range 0 - 6). |
| 342 int weekDay(year) { | 342 int weekDay(year) { |
| 343 // 1/1/1970 was a Thursday. | 343 // 1/1/1970 was a Thursday. |
| 344 return (dayFromYear_(year) + 4) % 7; | 344 return (_dayFromYear(year) + 4) % 7; |
| 345 } | 345 } |
| 346 // 1/1/1956 was a Sunday (i.e. weekday 0). 1956 was a leap-year. | 346 // 1/1/1956 was a Sunday (i.e. weekday 0). 1956 was a leap-year. |
| 347 // 1/1/1967 was a Sunday (i.e. weekday 0). | 347 // 1/1/1967 was a Sunday (i.e. weekday 0). |
| 348 // Without leap years a subsequent year has a week day + 1 (for example | 348 // Without leap years a subsequent year has a week day + 1 (for example |
| 349 // 1/1/1968 was a Monday). With leap-years it jumps over one week day | 349 // 1/1/1968 was a Monday). With leap-years it jumps over one week day |
| 350 // (e.g. 1/1/1957 was a Tuesday). | 350 // (e.g. 1/1/1957 was a Tuesday). |
| 351 // After 12 years the weekdays have advanced by 12 days + 3 leap days = | 351 // After 12 years the weekdays have advanced by 12 days + 3 leap days = |
| 352 // 15 days. 15 % 7 = 1. So after 12 years the week day has always | 352 // 15 days. 15 % 7 = 1. So after 12 years the week day has always |
| 353 // (now independently of leap-years) advanced by one. | 353 // (now independently of leap-years) advanced by one. |
| 354 // weekDay * 12 gives thus a year starting with the wanted weekDay. | 354 // weekDay * 12 gives thus a year starting with the wanted weekDay. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 373 if ((milliseconds < 0) || (milliseconds > 999)) return null; | 373 if ((milliseconds < 0) || (milliseconds > 999)) return null; |
| 374 | 374 |
| 375 int equivalentYear; | 375 int equivalentYear; |
| 376 int offsetInSeconds; | 376 int offsetInSeconds; |
| 377 // According to V8 some library calls have troubles with negative values. | 377 // According to V8 some library calls have troubles with negative values. |
| 378 // Therefore clamp to 1970 - year 2035 (which is less than the size of | 378 // Therefore clamp to 1970 - year 2035 (which is less than the size of |
| 379 // 32bit). | 379 // 32bit). |
| 380 // We exclude the year 1970 when the time is not UTC, since the epoch | 380 // We exclude the year 1970 when the time is not UTC, since the epoch |
| 381 // value could then be negative. | 381 // value could then be negative. |
| 382 if (years < (isUtc ? 1970 : 1971) || years > 2035) { | 382 if (years < (isUtc ? 1970 : 1971) || years > 2035) { |
| 383 equivalentYear = equivalentYear_(years); | 383 equivalentYear = _equivalentYear(years); |
| 384 int offsetInDays = (dayFromYear_(years) - dayFromYear_(equivalentYear)); | 384 int offsetInDays = (_dayFromYear(years) - _dayFromYear(equivalentYear)); |
| 385 // Leap seconds are ignored. | 385 // Leap seconds are ignored. |
| 386 offsetInSeconds = offsetInDays * Duration.SECONDS_PER_DAY; | 386 offsetInSeconds = offsetInDays * Duration.SECONDS_PER_DAY; |
| 387 } else { | 387 } else { |
| 388 equivalentYear = years; | 388 equivalentYear = years; |
| 389 offsetInSeconds = 0; | 389 offsetInSeconds = 0; |
| 390 } | 390 } |
| 391 int secondsSinceEpoch = _brokenDownDateToSecondsSinceEpoch( | 391 int secondsSinceEpoch = _brokenDownDateToSecondsSinceEpoch( |
| 392 equivalentYear, month, day, hours, minutes, seconds, isUtc); | 392 equivalentYear, month, day, hours, minutes, seconds, isUtc); |
| 393 int adjustedSeconds = secondsSinceEpoch + offsetInSeconds; | 393 int adjustedSeconds = secondsSinceEpoch + offsetInSeconds; |
| 394 return adjustedSeconds * Duration.MILLISECONDS_PER_SECOND + milliseconds; | 394 return adjustedSeconds * Duration.MILLISECONDS_PER_SECOND + milliseconds; |
| 395 } | 395 } |
| 396 | 396 |
| 397 // Natives | 397 // Natives |
| 398 static _brokenDownDateToSecondsSinceEpoch( | 398 static _brokenDownDateToSecondsSinceEpoch( |
| 399 int years, int month, int day, int hours, int minutes, int seconds, | 399 int years, int month, int day, int hours, int minutes, int seconds, |
| 400 bool isUtc) native "DateNatives_brokenDownToSecondsSinceEpoch"; | 400 bool isUtc) native "DateNatives_brokenDownToSecondsSinceEpoch"; |
| 401 | 401 |
| 402 static int getCurrentMs_() native "DateNatives_currentTimeMillis"; | 402 static int _getCurrentMs() native "DateNatives_currentTimeMillis"; |
| 403 | 403 |
| 404 // TODO(floitsch): it would be more efficient if we didn't call the native | 404 // TODO(floitsch): it would be more efficient if we didn't call the native |
| 405 // function for every member, but cached the broken-down date. | 405 // function for every member, but cached the broken-down date. |
| 406 static int getYear_(int secondsSinceEpoch, bool isUtc) | 406 static int _getYear(int secondsSinceEpoch, bool isUtc) |
| 407 native "DateNatives_getYear"; | 407 native "DateNatives_getYear"; |
| 408 | 408 |
| 409 static int getMonth_(int secondsSinceEpoch, bool isUtc) | 409 static int _getMonth(int secondsSinceEpoch, bool isUtc) |
| 410 native "DateNatives_getMonth"; | 410 native "DateNatives_getMonth"; |
| 411 | 411 |
| 412 static int getDay_(int secondsSinceEpoch, bool isUtc) | 412 static int _getDay(int secondsSinceEpoch, bool isUtc) |
| 413 native "DateNatives_getDay"; | 413 native "DateNatives_getDay"; |
| 414 | 414 |
| 415 static int getHours_(int secondsSinceEpoch, bool isUtc) | 415 static int _getHours(int secondsSinceEpoch, bool isUtc) |
| 416 native "DateNatives_getHours"; | 416 native "DateNatives_getHours"; |
| 417 | 417 |
| 418 static int getMinutes_(int secondsSinceEpoch, bool isUtc) | 418 static int _getMinutes(int secondsSinceEpoch, bool isUtc) |
| 419 native "DateNatives_getMinutes"; | 419 native "DateNatives_getMinutes"; |
| 420 | 420 |
| 421 static int getSeconds_(int secondsSinceEpoch, bool isUtc) | 421 static int _getSeconds(int secondsSinceEpoch, bool isUtc) |
| 422 native "DateNatives_getSeconds"; | 422 native "DateNatives_getSeconds"; |
| 423 } | 423 } |
| OLD | NEW |