Commit 664e7caa authored by digit@chromium.org's avatar digit@chromium.org

base/time_posix.cc: Use time64_t on Android.

Android's time_t is 32-bit by default, but the platform provides
a <time64.h> providing for time64_t and associated functions.

Use time64_t in base/time_posix.cc to implement base::Time::Exploded
conversion routines. This avoids un-necessary clamping of the year
to the 1901-2038 range when calling base::Time::Explode() or
base::Time::FromExploded().

BUG=162007
NOTRY=true

Review URL: https://chromiumcodereview.appspot.com/11308176

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@170738 0039d316-1c4b-4281-b951-d872f2087c98
parent d9c747af
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#if defined(OS_ANDROID)
#include <time64.h>
#endif
#include <unistd.h> #include <unistd.h>
#include <limits> #include <limits>
...@@ -19,6 +22,48 @@ ...@@ -19,6 +22,48 @@
#include "base/os_compat_nacl.h" #include "base/os_compat_nacl.h"
#endif #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 { namespace base {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
...@@ -95,7 +140,7 @@ void Time::Explode(bool is_local, Exploded* exploded) const { ...@@ -95,7 +140,7 @@ void Time::Explode(bool is_local, Exploded* exploded) const {
int64 microseconds = us_ - kWindowsEpochDeltaMicroseconds; int64 microseconds = us_ - kWindowsEpochDeltaMicroseconds;
// The following values are all rounded towards -infinity. // The following values are all rounded towards -infinity.
int64 milliseconds; // Milliseconds since epoch. int64 milliseconds; // Milliseconds since epoch.
time_t seconds; // Seconds since epoch. SysTime seconds; // Seconds since epoch.
int millisecond; // Exploded millisecond value (0-999). int millisecond; // Exploded millisecond value (0-999).
if (microseconds >= 0) { if (microseconds >= 0) {
// Rounding towards -infinity <=> rounding towards 0, in this case. // Rounding towards -infinity <=> rounding towards 0, in this case.
...@@ -115,10 +160,7 @@ void Time::Explode(bool is_local, Exploded* exploded) const { ...@@ -115,10 +160,7 @@ void Time::Explode(bool is_local, Exploded* exploded) const {
} }
struct tm timestruct; struct tm timestruct;
if (is_local) SysTimeToTimeStruct(seconds, &timestruct, is_local);
localtime_r(&seconds, &timestruct);
else
gmtime_r(&seconds, &timestruct);
exploded->year = timestruct.tm_year + 1900; exploded->year = timestruct.tm_year + 1900;
exploded->month = timestruct.tm_mon + 1; exploded->month = timestruct.tm_mon + 1;
...@@ -147,11 +189,7 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) { ...@@ -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 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore
#endif #endif
time_t seconds; SysTime seconds = SysTimeFromTimeStruct(&timestruct, is_local);
if (is_local)
seconds = mktime(&timestruct);
else
seconds = timegm(&timestruct);
int64 milliseconds; int64 milliseconds;
// Handle overflow. Clamping the range to what mktime and timegm might // Handle overflow. Clamping the range to what mktime and timegm might
...@@ -175,10 +213,10 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) { ...@@ -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 // 999ms to avoid the time being less than any other possible value that
// this function can return. // this function can return.
if (exploded.year < 1969) { if (exploded.year < 1969) {
milliseconds = std::numeric_limits<time_t>::min() * milliseconds = std::numeric_limits<SysTime>::min() *
kMillisecondsPerSecond; kMillisecondsPerSecond;
} else { } else {
milliseconds = (std::numeric_limits<time_t>::max() * milliseconds = (std::numeric_limits<SysTime>::max() *
kMillisecondsPerSecond) + kMillisecondsPerSecond) +
kMillisecondsPerSecond - 1; kMillisecondsPerSecond - 1;
} }
......
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