Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: base/time_posix.cc

Issue 11308176: base/time_posix.cc: Use time64_t on Android. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Simplify Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/time.h" 5 #include "base/time.h"
6 6
7 #include <sys/time.h> 7 #include <sys/time.h>
8 #include <time.h> 8 #include <time.h>
9 #if defined(OS_ANDROID)
10 #include <time64.h>
11 #endif
9 #include <unistd.h> 12 #include <unistd.h>
10 13
11 #include <limits> 14 #include <limits>
12 15
13 #include "base/basictypes.h" 16 #include "base/basictypes.h"
14 #include "base/logging.h" 17 #include "base/logging.h"
15 18
16 #if defined(OS_ANDROID) 19 #if defined(OS_ANDROID)
17 #include "base/os_compat_android.h" 20 #include "base/os_compat_android.h"
18 #elif defined(OS_NACL) 21 #elif defined(OS_NACL)
19 #include "base/os_compat_nacl.h" 22 #include "base/os_compat_nacl.h"
20 #endif 23 #endif
21 24
25 namespace {
26
27 // Define a system-specific SysTime that wraps either to a time_t or
28 // a time64_t depending on the host system, and associated convertion.
29 // See crbug.com/162007
30 #if defined(OS_ANDROID)
31 typedef time64_t SysTime;
32
33 SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) {
34 if (is_local)
35 return mktime64(timestruct);
36 else
37 return timegm64(timestruct);
38 }
39
40 void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) {
41 if (is_local)
42 localtime64_r(&t, timestruct);
43 else
44 gmtime64_r(&t, timestruct);
45 }
46
47 #else // OS_ANDROID
48 typedef time_t SysTime;
49
50 SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) {
51 if (is_local)
52 return mktime(timestruct);
53 else
54 return timegm(timestruct);
55 }
56
57 void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) {
58 if (is_local)
59 localtime_r(&t, timestruct);
60 else
61 gmtime_r(&t, timestruct);
62 }
63 #endif // OS_ANDROID
64
65 } // namespace
66
22 namespace base { 67 namespace base {
23 68
24 #if defined(OS_ANDROID) 69 #if defined(OS_ANDROID)
25 #define _POSIX_MONOTONIC_CLOCK 1 70 #define _POSIX_MONOTONIC_CLOCK 1
26 #endif 71 #endif
27 72
28 struct timespec TimeDelta::ToTimeSpec() const { 73 struct timespec TimeDelta::ToTimeSpec() const {
29 int64 microseconds = InMicroseconds(); 74 int64 microseconds = InMicroseconds();
30 time_t seconds = 0; 75 time_t seconds = 0;
31 if (microseconds >= Time::kMicrosecondsPerSecond) { 76 if (microseconds >= Time::kMicrosecondsPerSecond) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 return Now(); 133 return Now();
89 } 134 }
90 135
91 void Time::Explode(bool is_local, Exploded* exploded) const { 136 void Time::Explode(bool is_local, Exploded* exploded) const {
92 // Time stores times with microsecond resolution, but Exploded only carries 137 // Time stores times with microsecond resolution, but Exploded only carries
93 // millisecond resolution, so begin by being lossy. Adjust from Windows 138 // millisecond resolution, so begin by being lossy. Adjust from Windows
94 // epoch (1601) to Unix epoch (1970); 139 // epoch (1601) to Unix epoch (1970);
95 int64 microseconds = us_ - kWindowsEpochDeltaMicroseconds; 140 int64 microseconds = us_ - kWindowsEpochDeltaMicroseconds;
96 // The following values are all rounded towards -infinity. 141 // The following values are all rounded towards -infinity.
97 int64 milliseconds; // Milliseconds since epoch. 142 int64 milliseconds; // Milliseconds since epoch.
98 time_t seconds; // Seconds since epoch. 143 SysTime seconds; // Seconds since epoch.
99 int millisecond; // Exploded millisecond value (0-999). 144 int millisecond; // Exploded millisecond value (0-999).
100 if (microseconds >= 0) { 145 if (microseconds >= 0) {
101 // Rounding towards -infinity <=> rounding towards 0, in this case. 146 // Rounding towards -infinity <=> rounding towards 0, in this case.
102 milliseconds = microseconds / kMicrosecondsPerMillisecond; 147 milliseconds = microseconds / kMicrosecondsPerMillisecond;
103 seconds = milliseconds / kMillisecondsPerSecond; 148 seconds = milliseconds / kMillisecondsPerSecond;
104 millisecond = milliseconds % kMillisecondsPerSecond; 149 millisecond = milliseconds % kMillisecondsPerSecond;
105 } else { 150 } else {
106 // Round these *down* (towards -infinity). 151 // Round these *down* (towards -infinity).
107 milliseconds = (microseconds - kMicrosecondsPerMillisecond + 1) / 152 milliseconds = (microseconds - kMicrosecondsPerMillisecond + 1) /
108 kMicrosecondsPerMillisecond; 153 kMicrosecondsPerMillisecond;
109 seconds = (milliseconds - kMillisecondsPerSecond + 1) / 154 seconds = (milliseconds - kMillisecondsPerSecond + 1) /
110 kMillisecondsPerSecond; 155 kMillisecondsPerSecond;
111 // Make this nonnegative (and between 0 and 999 inclusive). 156 // Make this nonnegative (and between 0 and 999 inclusive).
112 millisecond = milliseconds % kMillisecondsPerSecond; 157 millisecond = milliseconds % kMillisecondsPerSecond;
113 if (millisecond < 0) 158 if (millisecond < 0)
114 millisecond += kMillisecondsPerSecond; 159 millisecond += kMillisecondsPerSecond;
115 } 160 }
116 161
117 struct tm timestruct; 162 struct tm timestruct;
118 if (is_local) 163 SysTimeToTimeStruct(seconds, &timestruct, is_local);
119 localtime_r(&seconds, &timestruct);
120 else
121 gmtime_r(&seconds, &timestruct);
122 164
123 exploded->year = timestruct.tm_year + 1900; 165 exploded->year = timestruct.tm_year + 1900;
124 exploded->month = timestruct.tm_mon + 1; 166 exploded->month = timestruct.tm_mon + 1;
125 exploded->day_of_week = timestruct.tm_wday; 167 exploded->day_of_week = timestruct.tm_wday;
126 exploded->day_of_month = timestruct.tm_mday; 168 exploded->day_of_month = timestruct.tm_mday;
127 exploded->hour = timestruct.tm_hour; 169 exploded->hour = timestruct.tm_hour;
128 exploded->minute = timestruct.tm_min; 170 exploded->minute = timestruct.tm_min;
129 exploded->second = timestruct.tm_sec; 171 exploded->second = timestruct.tm_sec;
130 exploded->millisecond = millisecond; 172 exploded->millisecond = millisecond;
131 } 173 }
132 174
133 // static 175 // static
134 Time Time::FromExploded(bool is_local, const Exploded& exploded) { 176 Time Time::FromExploded(bool is_local, const Exploded& exploded) {
135 struct tm timestruct; 177 struct tm timestruct;
136 timestruct.tm_sec = exploded.second; 178 timestruct.tm_sec = exploded.second;
137 timestruct.tm_min = exploded.minute; 179 timestruct.tm_min = exploded.minute;
138 timestruct.tm_hour = exploded.hour; 180 timestruct.tm_hour = exploded.hour;
139 timestruct.tm_mday = exploded.day_of_month; 181 timestruct.tm_mday = exploded.day_of_month;
140 timestruct.tm_mon = exploded.month - 1; 182 timestruct.tm_mon = exploded.month - 1;
141 timestruct.tm_year = exploded.year - 1900; 183 timestruct.tm_year = exploded.year - 1900;
142 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this 184 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this
143 timestruct.tm_yday = 0; // mktime/timegm ignore this 185 timestruct.tm_yday = 0; // mktime/timegm ignore this
144 timestruct.tm_isdst = -1; // attempt to figure it out 186 timestruct.tm_isdst = -1; // attempt to figure it out
145 #if !defined(OS_NACL) && !defined(OS_SOLARIS) 187 #if !defined(OS_NACL) && !defined(OS_SOLARIS)
146 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore 188 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore
147 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore 189 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore
148 #endif 190 #endif
149 191
150 time_t seconds; 192 SysTime seconds = SysTimeFromTimeStruct(&timestruct, is_local);
151 if (is_local)
152 seconds = mktime(&timestruct);
153 else
154 seconds = timegm(&timestruct);
155 193
156 int64 milliseconds; 194 int64 milliseconds;
157 // Handle overflow. Clamping the range to what mktime and timegm might 195 // Handle overflow. Clamping the range to what mktime and timegm might
158 // return is the best that can be done here. It's not ideal, but it's better 196 // return is the best that can be done here. It's not ideal, but it's better
159 // than failing here or ignoring the overflow case and treating each time 197 // than failing here or ignoring the overflow case and treating each time
160 // overflow as one second prior to the epoch. 198 // overflow as one second prior to the epoch.
161 if (seconds == -1 && 199 if (seconds == -1 &&
162 (exploded.year < 1969 || exploded.year > 1970)) { 200 (exploded.year < 1969 || exploded.year > 1970)) {
163 // If exploded.year is 1969 or 1970, take -1 as correct, with the 201 // If exploded.year is 1969 or 1970, take -1 as correct, with the
164 // time indicating 1 second prior to the epoch. (1970 is allowed to handle 202 // time indicating 1 second prior to the epoch. (1970 is allowed to handle
165 // time zone and DST offsets.) Otherwise, return the most future or past 203 // time zone and DST offsets.) Otherwise, return the most future or past
166 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC. 204 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC.
167 // 205 //
168 // The minimum and maximum representible times that mktime and timegm could 206 // The minimum and maximum representible times that mktime and timegm could
169 // return are used here instead of values outside that range to allow for 207 // return are used here instead of values outside that range to allow for
170 // proper round-tripping between exploded and counter-type time 208 // proper round-tripping between exploded and counter-type time
171 // representations in the presence of possible truncation to time_t by 209 // representations in the presence of possible truncation to time_t by
172 // division and use with other functions that accept time_t. 210 // division and use with other functions that accept time_t.
173 // 211 //
174 // When representing the most distant time in the future, add in an extra 212 // When representing the most distant time in the future, add in an extra
175 // 999ms to avoid the time being less than any other possible value that 213 // 999ms to avoid the time being less than any other possible value that
176 // this function can return. 214 // this function can return.
177 if (exploded.year < 1969) { 215 if (exploded.year < 1969) {
178 milliseconds = std::numeric_limits<time_t>::min() * 216 milliseconds = std::numeric_limits<SysTime>::min() *
179 kMillisecondsPerSecond; 217 kMillisecondsPerSecond;
180 } else { 218 } else {
181 milliseconds = (std::numeric_limits<time_t>::max() * 219 milliseconds = (std::numeric_limits<SysTime>::max() *
182 kMillisecondsPerSecond) + 220 kMillisecondsPerSecond) +
183 kMillisecondsPerSecond - 1; 221 kMillisecondsPerSecond - 1;
184 } 222 }
185 } else { 223 } else {
186 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; 224 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond;
187 } 225 }
188 226
189 // Adjust from Unix (1970) to Windows (1601) epoch. 227 // Adjust from Unix (1970) to Windows (1601) epoch.
190 return Time((milliseconds * kMicrosecondsPerMillisecond) + 228 return Time((milliseconds * kMicrosecondsPerMillisecond) +
191 kWindowsEpochDeltaMicroseconds); 229 kWindowsEpochDeltaMicroseconds);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; 321 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1;
284 return result; 322 return result;
285 } 323 }
286 int64 us = us_ - kTimeTToMicrosecondsOffset; 324 int64 us = us_ - kTimeTToMicrosecondsOffset;
287 result.tv_sec = us / Time::kMicrosecondsPerSecond; 325 result.tv_sec = us / Time::kMicrosecondsPerSecond;
288 result.tv_usec = us % Time::kMicrosecondsPerSecond; 326 result.tv_usec = us % Time::kMicrosecondsPerSecond;
289 return result; 327 return result;
290 } 328 }
291 329
292 } // namespace base 330 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698