| Index: base/time/time_mac.cc
|
| diff --git a/base/time/time_mac.cc b/base/time/time_mac.cc
|
| index 139e0c9e297ad7ec3d95e61447c801c8689a45bc..7d83f9d8081ae2bb14bec995cc0316f31a0e122a 100644
|
| --- a/base/time/time_mac.cc
|
| +++ b/base/time/time_mac.cc
|
| @@ -165,19 +165,27 @@ Time Time::NowFromSystemTime() {
|
|
|
| // static
|
| Time Time::FromExploded(bool is_local, const Exploded& exploded) {
|
| - CFGregorianDate date;
|
| - date.second = exploded.second +
|
| - exploded.millisecond / static_cast<double>(kMillisecondsPerSecond);
|
| - date.minute = exploded.minute;
|
| - date.hour = exploded.hour;
|
| - date.day = exploded.day_of_month;
|
| - date.month = exploded.month;
|
| - date.year = exploded.year;
|
| -
|
| base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
|
| - is_local ? CFTimeZoneCopySystem() : NULL);
|
| - CFAbsoluteTime seconds = CFGregorianDateGetAbsoluteTime(date, time_zone) +
|
| - kCFAbsoluteTimeIntervalSince1970;
|
| + is_local ? CFTimeZoneCopySystem() :
|
| + CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, 0));
|
| + base::ScopedCFTypeRef<CFCalendarRef> gregorian(
|
| + CFCalendarCreateWithIdentifier(kCFAllocatorDefault,
|
| + kCFGregorianCalendar));
|
| + CFCalendarSetTimeZone(gregorian, time_zone);
|
| + CFAbsoluteTime absolute_time;
|
| + CFCalendarComposeAbsoluteTime(gregorian, &absolute_time, "yMdHms",
|
| + static_cast<int>(exploded.year),
|
| + static_cast<int>(exploded.month),
|
| + static_cast<int>(exploded.day_of_month),
|
| + static_cast<int>(exploded.hour),
|
| + static_cast<int>(exploded.minute),
|
| + static_cast<int>(exploded.second));
|
| + // Milliseconds from |exploded| is added back to |absolute_time| here
|
| + // because CFCalendar parameters are integer values.
|
| + double milliseconds =
|
| + exploded.millisecond / static_cast<double>(kMillisecondsPerSecond);
|
| + CFAbsoluteTime seconds =
|
| + absolute_time + milliseconds + kCFAbsoluteTimeIntervalSince1970;
|
| return Time(static_cast<int64>(seconds * kMicrosecondsPerSecond) +
|
| kWindowsEpochDeltaMicroseconds);
|
| }
|
| @@ -193,19 +201,29 @@ void Time::Explode(bool is_local, Exploded* exploded) const {
|
| kCFAbsoluteTimeIntervalSince1970;
|
|
|
| base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
|
| - is_local ? CFTimeZoneCopySystem() : NULL);
|
| - CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(seconds, time_zone);
|
| - // 1 = Monday, ..., 7 = Sunday.
|
| - int cf_day_of_week = CFAbsoluteTimeGetDayOfWeek(seconds, time_zone);
|
| -
|
| - exploded->year = date.year;
|
| - exploded->month = date.month;
|
| - exploded->day_of_week = cf_day_of_week % 7;
|
| - exploded->day_of_month = date.day;
|
| - exploded->hour = date.hour;
|
| - exploded->minute = date.minute;
|
| + is_local ? CFTimeZoneCopySystem() :
|
| + CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, 0));
|
| + base::ScopedCFTypeRef<CFCalendarRef> gregorian(
|
| + CFCalendarCreateWithIdentifier(kCFAllocatorDefault,
|
| + kCFGregorianCalendar));
|
| + CFCalendarSetTimeZone(gregorian, time_zone);
|
| + int year, month, day, hour, minute, second;
|
| + CFCalendarDecomposeAbsoluteTime(gregorian, seconds, "yMdHms", &year, &month,
|
| + &day, &hour, &minute, &second);
|
| +
|
| + // Calculate the day of week using CFCalendar, which returns 1 = Sunday,
|
| + // 2 = Monday, etc., then convert to |Exploded|'s 0 = Sunday convention.
|
| + CFIndex cf_day_of_week = CFCalendarGetOrdinalityOfUnit(
|
| + gregorian, kCFCalendarUnitWeekday, kCFCalendarUnitWeekOfMonth, seconds);
|
| +
|
| + exploded->year = year;
|
| + exploded->month = month;
|
| + exploded->day_of_week = (cf_day_of_week - 1) % 7;
|
| + exploded->day_of_month = day;
|
| + exploded->hour = hour;
|
| + exploded->minute = minute;
|
| // Make sure seconds are rounded down towards -infinity.
|
| - exploded->second = floor(date.second);
|
| + exploded->second = floor(second);
|
| // Calculate milliseconds ourselves, since we rounded the |seconds|, making
|
| // sure to round towards -infinity.
|
| exploded->millisecond =
|
|
|