Commit 34445e49 authored by David Jean's avatar David Jean Committed by Commit Bot

[ios] Use posix TimeExploded

With 32 bits build gone, iOS can use the posix implementation of
TimeExploded, which is faster.

Bug: 985061
Change-Id: Ic1d42ebddfa2d0bb0d37bb7b2086683914aa87a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1763679
Commit-Queue: David Jean <djean@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Reviewed-by: default avatarJohn Budorick <jbudorick@chromium.org>
Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691094}
parent 3a2c0705
......@@ -1969,6 +1969,7 @@ jumbo_component("base") {
"task/thread_pool/thread_group_native_mac.mm",
"threading/platform_thread_mac.mm",
"time/time_conversion_posix.cc",
"time/time_exploded_posix.cc",
"time/time_mac.cc",
]
......
......@@ -492,10 +492,7 @@ class BASE_EXPORT Time : public time_internal::TimeBase<Time> {
#if defined(OS_WIN)
static constexpr int kExplodedMinYear = 1601;
static constexpr int kExplodedMaxYear = 30827;
#elif defined(OS_IOS)
static constexpr int kExplodedMinYear = std::numeric_limits<int>::min();
static constexpr int kExplodedMaxYear = std::numeric_limits<int>::max();
#elif defined(OS_MACOSX)
#elif defined(OS_IOS) || defined(OS_MACOSX)
static constexpr int kExplodedMinYear = 1902;
static constexpr int kExplodedMaxYear = std::numeric_limits<int>::max();
#elif defined(OS_ANDROID)
......
......@@ -32,7 +32,7 @@
#include "base/numerics/clamped_math.h"
#endif
#if defined(OS_MACOSX)
#if defined(OS_MACOSX) || defined(OS_IOS)
static_assert(sizeof(time_t) >= 8, "Y2038 problem!");
#endif
......
......@@ -175,102 +175,6 @@ CFAbsoluteTime Time::ToCFAbsoluteTime() const {
kCFAbsoluteTimeIntervalSince1970;
}
// Note: These implementations of Time::FromExploded() and Time::Explode() are
// only used on iOS now. Since Mac is now always 64-bit, we can use the POSIX
// versions of these functions as time_t is not capped at year 2038 on 64-bit
// builds. The POSIX functions are preferred since they don't suffer from some
// performance problems that are present in these implementations.
// See crbug.com/781601 for more details.
#if defined(OS_IOS)
// static
bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) {
base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
is_local
? CFTimeZoneCopySystem()
: CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, 0));
base::ScopedCFTypeRef<CFCalendarRef> gregorian(CFCalendarCreateWithIdentifier(
kCFAllocatorDefault, kCFGregorianCalendar));
CFCalendarSetTimeZone(gregorian, time_zone);
CFAbsoluteTime absolute_time;
// 'S' is not defined in componentDesc in Apple documentation, but can be
// found at http://www.opensource.apple.com/source/CF/CF-855.17/CFCalendar.c
CFCalendarComposeAbsoluteTime(
gregorian, &absolute_time, "yMdHmsS", exploded.year, exploded.month,
exploded.day_of_month, exploded.hour, exploded.minute, exploded.second,
exploded.millisecond);
CFAbsoluteTime seconds = absolute_time + kCFAbsoluteTimeIntervalSince1970;
// CFAbsolutTime is typedef of double. Convert seconds to
// microseconds and then cast to int64. If
// it cannot be suited to int64, then fail to avoid overflows.
double microseconds =
(seconds * kMicrosecondsPerSecond) + kTimeTToMicrosecondsOffset;
if (microseconds > std::numeric_limits<int64_t>::max() ||
microseconds < std::numeric_limits<int64_t>::min()) {
*time = Time(0);
return false;
}
base::Time converted_time = Time(static_cast<int64_t>(microseconds));
// If |exploded.day_of_month| is set to 31
// on a 28-30 day month, it will return the first day of the next month.
// Thus round-trip the time and compare the initial |exploded| with
// |utc_to_exploded| time.
base::Time::Exploded to_exploded;
if (!is_local)
converted_time.UTCExplode(&to_exploded);
else
converted_time.LocalExplode(&to_exploded);
if (ExplodedMostlyEquals(to_exploded, exploded)) {
*time = converted_time;
return true;
}
*time = Time(0);
return false;
}
void Time::Explode(bool is_local, Exploded* exploded) const {
// Avoid rounding issues, by only putting the integral number of seconds
// (rounded towards -infinity) into a |CFAbsoluteTime| (which is a |double|).
int64_t microsecond = us_ % kMicrosecondsPerSecond;
if (microsecond < 0)
microsecond += kMicrosecondsPerSecond;
CFAbsoluteTime seconds = ((us_ - microsecond - kTimeTToMicrosecondsOffset) /
kMicrosecondsPerSecond) -
kCFAbsoluteTimeIntervalSince1970;
base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
is_local
? CFTimeZoneCopySystem()
: CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, 0));
base::ScopedCFTypeRef<CFCalendarRef> gregorian(CFCalendarCreateWithIdentifier(
kCFAllocatorDefault, kCFGregorianCalendar));
CFCalendarSetTimeZone(gregorian, time_zone);
int second, day_of_week;
// 'E' sets the day of week, but is not defined in componentDesc in Apple
// documentation. It can be found in open source code here:
// http://www.opensource.apple.com/source/CF/CF-855.17/CFCalendar.c
CFCalendarDecomposeAbsoluteTime(gregorian, seconds, "yMdHmsE",
&exploded->year, &exploded->month,
&exploded->day_of_month, &exploded->hour,
&exploded->minute, &second, &day_of_week);
// Make sure seconds are rounded down towards -infinity.
exploded->second = floor(second);
// |Exploded|'s convention for day of week is 0 = Sunday, i.e. different
// from CF's 1 = Sunday.
exploded->day_of_week = (day_of_week - 1) % 7;
// Calculate milliseconds ourselves, since we rounded the |seconds|, making
// sure to round towards -infinity.
exploded->millisecond =
(microsecond >= 0) ? microsecond / kMicrosecondsPerMillisecond :
(microsecond - kMicrosecondsPerMillisecond + 1) /
kMicrosecondsPerMillisecond;
}
#endif // OS_IOS
// TimeTicks ------------------------------------------------------------------
namespace subtle {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment