1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
8*635a8641SAndroid Build Coastguard Worker #include <sys/time.h>
9*635a8641SAndroid Build Coastguard Worker #include <time.h>
10*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID) && !defined(__LP64__)
11*635a8641SAndroid Build Coastguard Worker #include <time64.h>
12*635a8641SAndroid Build Coastguard Worker #endif
13*635a8641SAndroid Build Coastguard Worker #include <unistd.h>
14*635a8641SAndroid Build Coastguard Worker
15*635a8641SAndroid Build Coastguard Worker #include <limits>
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker #include "base/numerics/safe_math.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
19*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
22*635a8641SAndroid Build Coastguard Worker #include "base/os_compat_android.h"
23*635a8641SAndroid Build Coastguard Worker #elif defined(OS_NACL)
24*635a8641SAndroid Build Coastguard Worker #include "base/os_compat_nacl.h"
25*635a8641SAndroid Build Coastguard Worker #endif
26*635a8641SAndroid Build Coastguard Worker
27*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
28*635a8641SAndroid Build Coastguard Worker static_assert(sizeof(time_t) >= 8, "Y2038 problem!");
29*635a8641SAndroid Build Coastguard Worker #endif
30*635a8641SAndroid Build Coastguard Worker
31*635a8641SAndroid Build Coastguard Worker namespace {
32*635a8641SAndroid Build Coastguard Worker
33*635a8641SAndroid Build Coastguard Worker // This prevents a crash on traversing the environment global and looking up
34*635a8641SAndroid Build Coastguard Worker // the 'TZ' variable in libc. See: crbug.com/390567.
GetSysTimeToTimeStructLock()35*635a8641SAndroid Build Coastguard Worker base::Lock* GetSysTimeToTimeStructLock() {
36*635a8641SAndroid Build Coastguard Worker static auto* lock = new base::Lock();
37*635a8641SAndroid Build Coastguard Worker return lock;
38*635a8641SAndroid Build Coastguard Worker }
39*635a8641SAndroid Build Coastguard Worker
40*635a8641SAndroid Build Coastguard Worker // Define a system-specific SysTime that wraps either to a time_t or
41*635a8641SAndroid Build Coastguard Worker // a time64_t depending on the host system, and associated convertion.
42*635a8641SAndroid Build Coastguard Worker // See crbug.com/162007
43*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID) && !defined(__LP64__)
44*635a8641SAndroid Build Coastguard Worker typedef time64_t SysTime;
45*635a8641SAndroid Build Coastguard Worker
SysTimeFromTimeStruct(struct tm * timestruct,bool is_local)46*635a8641SAndroid Build Coastguard Worker SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) {
47*635a8641SAndroid Build Coastguard Worker base::AutoLock locked(*GetSysTimeToTimeStructLock());
48*635a8641SAndroid Build Coastguard Worker if (is_local)
49*635a8641SAndroid Build Coastguard Worker return mktime64(timestruct);
50*635a8641SAndroid Build Coastguard Worker else
51*635a8641SAndroid Build Coastguard Worker return timegm64(timestruct);
52*635a8641SAndroid Build Coastguard Worker }
53*635a8641SAndroid Build Coastguard Worker
SysTimeToTimeStruct(SysTime t,struct tm * timestruct,bool is_local)54*635a8641SAndroid Build Coastguard Worker void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) {
55*635a8641SAndroid Build Coastguard Worker base::AutoLock locked(*GetSysTimeToTimeStructLock());
56*635a8641SAndroid Build Coastguard Worker if (is_local)
57*635a8641SAndroid Build Coastguard Worker localtime64_r(&t, timestruct);
58*635a8641SAndroid Build Coastguard Worker else
59*635a8641SAndroid Build Coastguard Worker gmtime64_r(&t, timestruct);
60*635a8641SAndroid Build Coastguard Worker }
61*635a8641SAndroid Build Coastguard Worker
62*635a8641SAndroid Build Coastguard Worker #elif defined(OS_AIX)
63*635a8641SAndroid Build Coastguard Worker
64*635a8641SAndroid Build Coastguard Worker // The function timegm is not available on AIX.
aix_timegm(struct tm * tm)65*635a8641SAndroid Build Coastguard Worker time_t aix_timegm(struct tm* tm) {
66*635a8641SAndroid Build Coastguard Worker time_t ret;
67*635a8641SAndroid Build Coastguard Worker char* tz;
68*635a8641SAndroid Build Coastguard Worker
69*635a8641SAndroid Build Coastguard Worker tz = getenv("TZ");
70*635a8641SAndroid Build Coastguard Worker if (tz) {
71*635a8641SAndroid Build Coastguard Worker tz = strdup(tz);
72*635a8641SAndroid Build Coastguard Worker }
73*635a8641SAndroid Build Coastguard Worker setenv("TZ", "GMT0", 1);
74*635a8641SAndroid Build Coastguard Worker tzset();
75*635a8641SAndroid Build Coastguard Worker ret = mktime(tm);
76*635a8641SAndroid Build Coastguard Worker if (tz) {
77*635a8641SAndroid Build Coastguard Worker setenv("TZ", tz, 1);
78*635a8641SAndroid Build Coastguard Worker free(tz);
79*635a8641SAndroid Build Coastguard Worker } else {
80*635a8641SAndroid Build Coastguard Worker unsetenv("TZ");
81*635a8641SAndroid Build Coastguard Worker }
82*635a8641SAndroid Build Coastguard Worker tzset();
83*635a8641SAndroid Build Coastguard Worker return ret;
84*635a8641SAndroid Build Coastguard Worker }
85*635a8641SAndroid Build Coastguard Worker
86*635a8641SAndroid Build Coastguard Worker typedef time_t SysTime;
87*635a8641SAndroid Build Coastguard Worker
SysTimeFromTimeStruct(struct tm * timestruct,bool is_local)88*635a8641SAndroid Build Coastguard Worker SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) {
89*635a8641SAndroid Build Coastguard Worker base::AutoLock locked(*GetSysTimeToTimeStructLock());
90*635a8641SAndroid Build Coastguard Worker if (is_local)
91*635a8641SAndroid Build Coastguard Worker return mktime(timestruct);
92*635a8641SAndroid Build Coastguard Worker else
93*635a8641SAndroid Build Coastguard Worker return aix_timegm(timestruct);
94*635a8641SAndroid Build Coastguard Worker }
95*635a8641SAndroid Build Coastguard Worker
SysTimeToTimeStruct(SysTime t,struct tm * timestruct,bool is_local)96*635a8641SAndroid Build Coastguard Worker void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) {
97*635a8641SAndroid Build Coastguard Worker base::AutoLock locked(*GetSysTimeToTimeStructLock());
98*635a8641SAndroid Build Coastguard Worker if (is_local)
99*635a8641SAndroid Build Coastguard Worker localtime_r(&t, timestruct);
100*635a8641SAndroid Build Coastguard Worker else
101*635a8641SAndroid Build Coastguard Worker gmtime_r(&t, timestruct);
102*635a8641SAndroid Build Coastguard Worker }
103*635a8641SAndroid Build Coastguard Worker
104*635a8641SAndroid Build Coastguard Worker #else // OS_ANDROID && !__LP64__
105*635a8641SAndroid Build Coastguard Worker typedef time_t SysTime;
106*635a8641SAndroid Build Coastguard Worker
SysTimeFromTimeStruct(struct tm * timestruct,bool is_local)107*635a8641SAndroid Build Coastguard Worker SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) {
108*635a8641SAndroid Build Coastguard Worker base::AutoLock locked(*GetSysTimeToTimeStructLock());
109*635a8641SAndroid Build Coastguard Worker if (is_local)
110*635a8641SAndroid Build Coastguard Worker return mktime(timestruct);
111*635a8641SAndroid Build Coastguard Worker else
112*635a8641SAndroid Build Coastguard Worker return timegm(timestruct);
113*635a8641SAndroid Build Coastguard Worker }
114*635a8641SAndroid Build Coastguard Worker
SysTimeToTimeStruct(SysTime t,struct tm * timestruct,bool is_local)115*635a8641SAndroid Build Coastguard Worker void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) {
116*635a8641SAndroid Build Coastguard Worker base::AutoLock locked(*GetSysTimeToTimeStructLock());
117*635a8641SAndroid Build Coastguard Worker if (is_local)
118*635a8641SAndroid Build Coastguard Worker localtime_r(&t, timestruct);
119*635a8641SAndroid Build Coastguard Worker else
120*635a8641SAndroid Build Coastguard Worker gmtime_r(&t, timestruct);
121*635a8641SAndroid Build Coastguard Worker }
122*635a8641SAndroid Build Coastguard Worker #endif // OS_ANDROID
123*635a8641SAndroid Build Coastguard Worker
124*635a8641SAndroid Build Coastguard Worker } // namespace
125*635a8641SAndroid Build Coastguard Worker
126*635a8641SAndroid Build Coastguard Worker namespace base {
127*635a8641SAndroid Build Coastguard Worker
Explode(bool is_local,Exploded * exploded) const128*635a8641SAndroid Build Coastguard Worker void Time::Explode(bool is_local, Exploded* exploded) const {
129*635a8641SAndroid Build Coastguard Worker // Time stores times with microsecond resolution, but Exploded only carries
130*635a8641SAndroid Build Coastguard Worker // millisecond resolution, so begin by being lossy. Adjust from Windows
131*635a8641SAndroid Build Coastguard Worker // epoch (1601) to Unix epoch (1970);
132*635a8641SAndroid Build Coastguard Worker int64_t microseconds = us_ - kTimeTToMicrosecondsOffset;
133*635a8641SAndroid Build Coastguard Worker // The following values are all rounded towards -infinity.
134*635a8641SAndroid Build Coastguard Worker int64_t milliseconds; // Milliseconds since epoch.
135*635a8641SAndroid Build Coastguard Worker SysTime seconds; // Seconds since epoch.
136*635a8641SAndroid Build Coastguard Worker int millisecond; // Exploded millisecond value (0-999).
137*635a8641SAndroid Build Coastguard Worker if (microseconds >= 0) {
138*635a8641SAndroid Build Coastguard Worker // Rounding towards -infinity <=> rounding towards 0, in this case.
139*635a8641SAndroid Build Coastguard Worker milliseconds = microseconds / kMicrosecondsPerMillisecond;
140*635a8641SAndroid Build Coastguard Worker seconds = milliseconds / kMillisecondsPerSecond;
141*635a8641SAndroid Build Coastguard Worker millisecond = milliseconds % kMillisecondsPerSecond;
142*635a8641SAndroid Build Coastguard Worker } else {
143*635a8641SAndroid Build Coastguard Worker // Round these *down* (towards -infinity).
144*635a8641SAndroid Build Coastguard Worker milliseconds = (microseconds - kMicrosecondsPerMillisecond + 1) /
145*635a8641SAndroid Build Coastguard Worker kMicrosecondsPerMillisecond;
146*635a8641SAndroid Build Coastguard Worker seconds =
147*635a8641SAndroid Build Coastguard Worker (milliseconds - kMillisecondsPerSecond + 1) / kMillisecondsPerSecond;
148*635a8641SAndroid Build Coastguard Worker // Make this nonnegative (and between 0 and 999 inclusive).
149*635a8641SAndroid Build Coastguard Worker millisecond = milliseconds % kMillisecondsPerSecond;
150*635a8641SAndroid Build Coastguard Worker if (millisecond < 0)
151*635a8641SAndroid Build Coastguard Worker millisecond += kMillisecondsPerSecond;
152*635a8641SAndroid Build Coastguard Worker }
153*635a8641SAndroid Build Coastguard Worker
154*635a8641SAndroid Build Coastguard Worker struct tm timestruct;
155*635a8641SAndroid Build Coastguard Worker SysTimeToTimeStruct(seconds, ×truct, is_local);
156*635a8641SAndroid Build Coastguard Worker
157*635a8641SAndroid Build Coastguard Worker exploded->year = timestruct.tm_year + 1900;
158*635a8641SAndroid Build Coastguard Worker exploded->month = timestruct.tm_mon + 1;
159*635a8641SAndroid Build Coastguard Worker exploded->day_of_week = timestruct.tm_wday;
160*635a8641SAndroid Build Coastguard Worker exploded->day_of_month = timestruct.tm_mday;
161*635a8641SAndroid Build Coastguard Worker exploded->hour = timestruct.tm_hour;
162*635a8641SAndroid Build Coastguard Worker exploded->minute = timestruct.tm_min;
163*635a8641SAndroid Build Coastguard Worker exploded->second = timestruct.tm_sec;
164*635a8641SAndroid Build Coastguard Worker exploded->millisecond = millisecond;
165*635a8641SAndroid Build Coastguard Worker }
166*635a8641SAndroid Build Coastguard Worker
167*635a8641SAndroid Build Coastguard Worker // static
FromExploded(bool is_local,const Exploded & exploded,Time * time)168*635a8641SAndroid Build Coastguard Worker bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) {
169*635a8641SAndroid Build Coastguard Worker CheckedNumeric<int> month = exploded.month;
170*635a8641SAndroid Build Coastguard Worker month--;
171*635a8641SAndroid Build Coastguard Worker CheckedNumeric<int> year = exploded.year;
172*635a8641SAndroid Build Coastguard Worker year -= 1900;
173*635a8641SAndroid Build Coastguard Worker if (!month.IsValid() || !year.IsValid()) {
174*635a8641SAndroid Build Coastguard Worker *time = Time(0);
175*635a8641SAndroid Build Coastguard Worker return false;
176*635a8641SAndroid Build Coastguard Worker }
177*635a8641SAndroid Build Coastguard Worker
178*635a8641SAndroid Build Coastguard Worker struct tm timestruct;
179*635a8641SAndroid Build Coastguard Worker timestruct.tm_sec = exploded.second;
180*635a8641SAndroid Build Coastguard Worker timestruct.tm_min = exploded.minute;
181*635a8641SAndroid Build Coastguard Worker timestruct.tm_hour = exploded.hour;
182*635a8641SAndroid Build Coastguard Worker timestruct.tm_mday = exploded.day_of_month;
183*635a8641SAndroid Build Coastguard Worker timestruct.tm_mon = month.ValueOrDie();
184*635a8641SAndroid Build Coastguard Worker timestruct.tm_year = year.ValueOrDie();
185*635a8641SAndroid Build Coastguard Worker timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this
186*635a8641SAndroid Build Coastguard Worker timestruct.tm_yday = 0; // mktime/timegm ignore this
187*635a8641SAndroid Build Coastguard Worker timestruct.tm_isdst = -1; // attempt to figure it out
188*635a8641SAndroid Build Coastguard Worker #if !defined(OS_NACL) && !defined(OS_SOLARIS) && !defined(OS_AIX)
189*635a8641SAndroid Build Coastguard Worker timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore
190*635a8641SAndroid Build Coastguard Worker timestruct.tm_zone = nullptr; // not a POSIX field, so mktime/timegm ignore
191*635a8641SAndroid Build Coastguard Worker #endif
192*635a8641SAndroid Build Coastguard Worker
193*635a8641SAndroid Build Coastguard Worker SysTime seconds;
194*635a8641SAndroid Build Coastguard Worker
195*635a8641SAndroid Build Coastguard Worker // Certain exploded dates do not really exist due to daylight saving times,
196*635a8641SAndroid Build Coastguard Worker // and this causes mktime() to return implementation-defined values when
197*635a8641SAndroid Build Coastguard Worker // tm_isdst is set to -1. On Android, the function will return -1, while the
198*635a8641SAndroid Build Coastguard Worker // C libraries of other platforms typically return a liberally-chosen value.
199*635a8641SAndroid Build Coastguard Worker // Handling this requires the special code below.
200*635a8641SAndroid Build Coastguard Worker
201*635a8641SAndroid Build Coastguard Worker // SysTimeFromTimeStruct() modifies the input structure, save current value.
202*635a8641SAndroid Build Coastguard Worker struct tm timestruct0 = timestruct;
203*635a8641SAndroid Build Coastguard Worker
204*635a8641SAndroid Build Coastguard Worker seconds = SysTimeFromTimeStruct(×truct, is_local);
205*635a8641SAndroid Build Coastguard Worker if (seconds == -1) {
206*635a8641SAndroid Build Coastguard Worker // Get the time values with tm_isdst == 0 and 1, then select the closest one
207*635a8641SAndroid Build Coastguard Worker // to UTC 00:00:00 that isn't -1.
208*635a8641SAndroid Build Coastguard Worker timestruct = timestruct0;
209*635a8641SAndroid Build Coastguard Worker timestruct.tm_isdst = 0;
210*635a8641SAndroid Build Coastguard Worker int64_t seconds_isdst0 = SysTimeFromTimeStruct(×truct, is_local);
211*635a8641SAndroid Build Coastguard Worker
212*635a8641SAndroid Build Coastguard Worker timestruct = timestruct0;
213*635a8641SAndroid Build Coastguard Worker timestruct.tm_isdst = 1;
214*635a8641SAndroid Build Coastguard Worker int64_t seconds_isdst1 = SysTimeFromTimeStruct(×truct, is_local);
215*635a8641SAndroid Build Coastguard Worker
216*635a8641SAndroid Build Coastguard Worker // seconds_isdst0 or seconds_isdst1 can be -1 for some timezones.
217*635a8641SAndroid Build Coastguard Worker // E.g. "CLST" (Chile Summer Time) returns -1 for 'tm_isdt == 1'.
218*635a8641SAndroid Build Coastguard Worker if (seconds_isdst0 < 0)
219*635a8641SAndroid Build Coastguard Worker seconds = seconds_isdst1;
220*635a8641SAndroid Build Coastguard Worker else if (seconds_isdst1 < 0)
221*635a8641SAndroid Build Coastguard Worker seconds = seconds_isdst0;
222*635a8641SAndroid Build Coastguard Worker else
223*635a8641SAndroid Build Coastguard Worker seconds = std::min(seconds_isdst0, seconds_isdst1);
224*635a8641SAndroid Build Coastguard Worker }
225*635a8641SAndroid Build Coastguard Worker
226*635a8641SAndroid Build Coastguard Worker // Handle overflow. Clamping the range to what mktime and timegm might
227*635a8641SAndroid Build Coastguard Worker // return is the best that can be done here. It's not ideal, but it's better
228*635a8641SAndroid Build Coastguard Worker // than failing here or ignoring the overflow case and treating each time
229*635a8641SAndroid Build Coastguard Worker // overflow as one second prior to the epoch.
230*635a8641SAndroid Build Coastguard Worker int64_t milliseconds = 0;
231*635a8641SAndroid Build Coastguard Worker if (seconds == -1 && (exploded.year < 1969 || exploded.year > 1970)) {
232*635a8641SAndroid Build Coastguard Worker // If exploded.year is 1969 or 1970, take -1 as correct, with the
233*635a8641SAndroid Build Coastguard Worker // time indicating 1 second prior to the epoch. (1970 is allowed to handle
234*635a8641SAndroid Build Coastguard Worker // time zone and DST offsets.) Otherwise, return the most future or past
235*635a8641SAndroid Build Coastguard Worker // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC.
236*635a8641SAndroid Build Coastguard Worker //
237*635a8641SAndroid Build Coastguard Worker // The minimum and maximum representible times that mktime and timegm could
238*635a8641SAndroid Build Coastguard Worker // return are used here instead of values outside that range to allow for
239*635a8641SAndroid Build Coastguard Worker // proper round-tripping between exploded and counter-type time
240*635a8641SAndroid Build Coastguard Worker // representations in the presence of possible truncation to time_t by
241*635a8641SAndroid Build Coastguard Worker // division and use with other functions that accept time_t.
242*635a8641SAndroid Build Coastguard Worker //
243*635a8641SAndroid Build Coastguard Worker // When representing the most distant time in the future, add in an extra
244*635a8641SAndroid Build Coastguard Worker // 999ms to avoid the time being less than any other possible value that
245*635a8641SAndroid Build Coastguard Worker // this function can return.
246*635a8641SAndroid Build Coastguard Worker
247*635a8641SAndroid Build Coastguard Worker // On Android, SysTime is int64_t, special care must be taken to avoid
248*635a8641SAndroid Build Coastguard Worker // overflows.
249*635a8641SAndroid Build Coastguard Worker const int64_t min_seconds = (sizeof(SysTime) < sizeof(int64_t))
250*635a8641SAndroid Build Coastguard Worker ? std::numeric_limits<SysTime>::min()
251*635a8641SAndroid Build Coastguard Worker : std::numeric_limits<int32_t>::min();
252*635a8641SAndroid Build Coastguard Worker const int64_t max_seconds = (sizeof(SysTime) < sizeof(int64_t))
253*635a8641SAndroid Build Coastguard Worker ? std::numeric_limits<SysTime>::max()
254*635a8641SAndroid Build Coastguard Worker : std::numeric_limits<int32_t>::max();
255*635a8641SAndroid Build Coastguard Worker if (exploded.year < 1969) {
256*635a8641SAndroid Build Coastguard Worker milliseconds = min_seconds * kMillisecondsPerSecond;
257*635a8641SAndroid Build Coastguard Worker } else {
258*635a8641SAndroid Build Coastguard Worker milliseconds = max_seconds * kMillisecondsPerSecond;
259*635a8641SAndroid Build Coastguard Worker milliseconds += (kMillisecondsPerSecond - 1);
260*635a8641SAndroid Build Coastguard Worker }
261*635a8641SAndroid Build Coastguard Worker } else {
262*635a8641SAndroid Build Coastguard Worker base::CheckedNumeric<int64_t> checked_millis = seconds;
263*635a8641SAndroid Build Coastguard Worker checked_millis *= kMillisecondsPerSecond;
264*635a8641SAndroid Build Coastguard Worker checked_millis += exploded.millisecond;
265*635a8641SAndroid Build Coastguard Worker if (!checked_millis.IsValid()) {
266*635a8641SAndroid Build Coastguard Worker *time = base::Time(0);
267*635a8641SAndroid Build Coastguard Worker return false;
268*635a8641SAndroid Build Coastguard Worker }
269*635a8641SAndroid Build Coastguard Worker milliseconds = checked_millis.ValueOrDie();
270*635a8641SAndroid Build Coastguard Worker }
271*635a8641SAndroid Build Coastguard Worker
272*635a8641SAndroid Build Coastguard Worker // Adjust from Unix (1970) to Windows (1601) epoch avoiding overflows.
273*635a8641SAndroid Build Coastguard Worker base::CheckedNumeric<int64_t> checked_microseconds_win_epoch = milliseconds;
274*635a8641SAndroid Build Coastguard Worker checked_microseconds_win_epoch *= kMicrosecondsPerMillisecond;
275*635a8641SAndroid Build Coastguard Worker checked_microseconds_win_epoch += kTimeTToMicrosecondsOffset;
276*635a8641SAndroid Build Coastguard Worker if (!checked_microseconds_win_epoch.IsValid()) {
277*635a8641SAndroid Build Coastguard Worker *time = base::Time(0);
278*635a8641SAndroid Build Coastguard Worker return false;
279*635a8641SAndroid Build Coastguard Worker }
280*635a8641SAndroid Build Coastguard Worker base::Time converted_time(checked_microseconds_win_epoch.ValueOrDie());
281*635a8641SAndroid Build Coastguard Worker
282*635a8641SAndroid Build Coastguard Worker // If |exploded.day_of_month| is set to 31 on a 28-30 day month, it will
283*635a8641SAndroid Build Coastguard Worker // return the first day of the next month. Thus round-trip the time and
284*635a8641SAndroid Build Coastguard Worker // compare the initial |exploded| with |utc_to_exploded| time.
285*635a8641SAndroid Build Coastguard Worker base::Time::Exploded to_exploded;
286*635a8641SAndroid Build Coastguard Worker if (!is_local)
287*635a8641SAndroid Build Coastguard Worker converted_time.UTCExplode(&to_exploded);
288*635a8641SAndroid Build Coastguard Worker else
289*635a8641SAndroid Build Coastguard Worker converted_time.LocalExplode(&to_exploded);
290*635a8641SAndroid Build Coastguard Worker
291*635a8641SAndroid Build Coastguard Worker if (ExplodedMostlyEquals(to_exploded, exploded)) {
292*635a8641SAndroid Build Coastguard Worker *time = converted_time;
293*635a8641SAndroid Build Coastguard Worker return true;
294*635a8641SAndroid Build Coastguard Worker }
295*635a8641SAndroid Build Coastguard Worker
296*635a8641SAndroid Build Coastguard Worker *time = Time(0);
297*635a8641SAndroid Build Coastguard Worker return false;
298*635a8641SAndroid Build Coastguard Worker }
299*635a8641SAndroid Build Coastguard Worker
300*635a8641SAndroid Build Coastguard Worker } // namespace base
301