Index: base/time_posix.cc |
diff --git a/base/time_posix.cc b/base/time_posix.cc |
index 8b295bdc61af555a773c61b009a592b5c492d4d1..b6a12501212e64cee0686d0aaa6d04d581b141dd 100644 |
--- a/base/time_posix.cc |
+++ b/base/time_posix.cc |
@@ -6,6 +6,9 @@ |
#include <sys/time.h> |
#include <time.h> |
+#if defined(OS_ANDROID) |
+#include <time64.h> |
+#endif |
#include <unistd.h> |
#include <limits> |
@@ -19,6 +22,48 @@ |
#include "base/os_compat_nacl.h" |
#endif |
+namespace { |
+ |
+// Define a system-specific SysTime that wraps either to a time_t or |
+// a time64_t depending on the host system, and associated convertion. |
+// See crbug.com/162007 |
+#if defined(OS_ANDROID) |
+typedef time64_t SysTime; |
+ |
+SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { |
+ if (is_local) |
+ return mktime64(timestruct); |
+ else |
+ return timegm64(timestruct); |
+} |
+ |
+void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { |
+ if (is_local) |
+ localtime64_r(&t, timestruct); |
+ else |
+ gmtime64_r(&t, timestruct); |
+} |
+ |
+#else // OS_ANDROID |
+typedef time_t SysTime; |
+ |
+SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { |
+ if (is_local) |
+ return mktime(timestruct); |
+ else |
+ return timegm(timestruct); |
+} |
+ |
+void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { |
+ if (is_local) |
+ localtime_r(&t, timestruct); |
+ else |
+ gmtime_r(&t, timestruct); |
+} |
+#endif // OS_ANDROID |
+ |
+} // namespace |
+ |
namespace base { |
#if defined(OS_ANDROID) |
@@ -95,7 +140,7 @@ void Time::Explode(bool is_local, Exploded* exploded) const { |
int64 microseconds = us_ - kWindowsEpochDeltaMicroseconds; |
// The following values are all rounded towards -infinity. |
int64 milliseconds; // Milliseconds since epoch. |
- time_t seconds; // Seconds since epoch. |
+ SysTime seconds; // Seconds since epoch. |
int millisecond; // Exploded millisecond value (0-999). |
if (microseconds >= 0) { |
// Rounding towards -infinity <=> rounding towards 0, in this case. |
@@ -115,10 +160,7 @@ void Time::Explode(bool is_local, Exploded* exploded) const { |
} |
struct tm timestruct; |
- if (is_local) |
- localtime_r(&seconds, ×truct); |
- else |
- gmtime_r(&seconds, ×truct); |
+ SysTimeToTimeStruct(seconds, ×truct, is_local); |
exploded->year = timestruct.tm_year + 1900; |
exploded->month = timestruct.tm_mon + 1; |
@@ -147,11 +189,7 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) { |
timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore |
#endif |
- time_t seconds; |
- if (is_local) |
- seconds = mktime(×truct); |
- else |
- seconds = timegm(×truct); |
+ SysTime seconds = SysTimeFromTimeStruct(×truct, is_local); |
int64 milliseconds; |
// Handle overflow. Clamping the range to what mktime and timegm might |
@@ -175,10 +213,10 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) { |
// 999ms to avoid the time being less than any other possible value that |
// this function can return. |
if (exploded.year < 1969) { |
- milliseconds = std::numeric_limits<time_t>::min() * |
+ milliseconds = std::numeric_limits<SysTime>::min() * |
kMillisecondsPerSecond; |
} else { |
- milliseconds = (std::numeric_limits<time_t>::max() * |
+ milliseconds = (std::numeric_limits<SysTime>::max() * |
kMillisecondsPerSecond) + |
kMillisecondsPerSecond - 1; |
} |