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

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: Created 8 years, 1 month 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)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 return Time((tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec) + 84 return Time((tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec) +
82 kWindowsEpochDeltaMicroseconds); 85 kWindowsEpochDeltaMicroseconds);
83 } 86 }
84 87
85 // static 88 // static
86 Time Time::NowFromSystemTime() { 89 Time Time::NowFromSystemTime() {
87 // Just use Now() because Now() returns the system time. 90 // Just use Now() because Now() returns the system time.
88 return Now(); 91 return Now();
89 } 92 }
90 93
94 // Define a system-specific SysTimeT that wraps either to a time_t or
brettw 2012/11/29 19:27:52 This should go in an anon. namespace at the top of
digit1 2012/11/30 14:10:15 Thanks, that makes sense. Done.
95 // a time64_t depending on the host system. See crbug.com/162007
96 #if defined(OS_ANDROID)
97 struct SysTimeT {
digit1 2012/11/29 13:49:30 A small comment here: I'm not really sure that a n
98 typedef time64_t type;
99
100 SysTimeT() : t(0) {}
101
102 explicit SysTimeT(struct tm* timestruct, bool is_local) {
103 if (is_local)
104 t = mktime64(timestruct);
105 else
106 t = timegm64(timestruct);
107 }
108
109 void ToTimeStruct(struct tm* timestruct, bool is_local) {
110 if (is_local)
111 localtime64_r(&t, timestruct);
112 else
113 gmtime64_r(&t, timestruct);
114 }
115
116 time64_t t;
117 };
118 #else
119 struct SysTimeT {
120 typedef time_t type;
121
122 SysTimeT() : t(0) {}
123
124 explicit SysTimeT(struct tm* timestruct, bool is_local) {
125 if (is_local)
126 t = mktime(timestruct);
127 else
128 t = timegm(timestruct);
129 }
130
131 void ToTimeStruct(struct tm* timestruct, bool is_local) {
132 if (is_local)
133 localtime_r(&t, timestruct);
134 else
135 gmtime_r(&t, timestruct);
136 }
137
138 time_t t;
139 };
140 #endif
141
91 void Time::Explode(bool is_local, Exploded* exploded) const { 142 void Time::Explode(bool is_local, Exploded* exploded) const {
92 // Time stores times with microsecond resolution, but Exploded only carries 143 // Time stores times with microsecond resolution, but Exploded only carries
93 // millisecond resolution, so begin by being lossy. Adjust from Windows 144 // millisecond resolution, so begin by being lossy. Adjust from Windows
94 // epoch (1601) to Unix epoch (1970); 145 // epoch (1601) to Unix epoch (1970);
95 int64 microseconds = us_ - kWindowsEpochDeltaMicroseconds; 146 int64 microseconds = us_ - kWindowsEpochDeltaMicroseconds;
96 // The following values are all rounded towards -infinity. 147 // The following values are all rounded towards -infinity.
97 int64 milliseconds; // Milliseconds since epoch. 148 int64 milliseconds; // Milliseconds since epoch.
98 time_t seconds; // Seconds since epoch. 149 SysTimeT seconds; // Seconds since epoch.
99 int millisecond; // Exploded millisecond value (0-999). 150 int millisecond; // Exploded millisecond value (0-999).
100 if (microseconds >= 0) { 151 if (microseconds >= 0) {
101 // Rounding towards -infinity <=> rounding towards 0, in this case. 152 // Rounding towards -infinity <=> rounding towards 0, in this case.
102 milliseconds = microseconds / kMicrosecondsPerMillisecond; 153 milliseconds = microseconds / kMicrosecondsPerMillisecond;
103 seconds = milliseconds / kMillisecondsPerSecond; 154 seconds.t = milliseconds / kMillisecondsPerSecond;
104 millisecond = milliseconds % kMillisecondsPerSecond; 155 millisecond = milliseconds % kMillisecondsPerSecond;
105 } else { 156 } else {
106 // Round these *down* (towards -infinity). 157 // Round these *down* (towards -infinity).
107 milliseconds = (microseconds - kMicrosecondsPerMillisecond + 1) / 158 milliseconds = (microseconds - kMicrosecondsPerMillisecond + 1) /
108 kMicrosecondsPerMillisecond; 159 kMicrosecondsPerMillisecond;
109 seconds = (milliseconds - kMillisecondsPerSecond + 1) / 160 seconds.t = (milliseconds - kMillisecondsPerSecond + 1) /
110 kMillisecondsPerSecond; 161 kMillisecondsPerSecond;
111 // Make this nonnegative (and between 0 and 999 inclusive). 162 // Make this nonnegative (and between 0 and 999 inclusive).
112 millisecond = milliseconds % kMillisecondsPerSecond; 163 millisecond = milliseconds % kMillisecondsPerSecond;
113 if (millisecond < 0) 164 if (millisecond < 0)
114 millisecond += kMillisecondsPerSecond; 165 millisecond += kMillisecondsPerSecond;
115 } 166 }
116 167
117 struct tm timestruct; 168 struct tm timestruct;
118 if (is_local) 169 seconds.ToTimeStruct(&timestruct, is_local);
119 localtime_r(&seconds, &timestruct);
120 else
121 gmtime_r(&seconds, &timestruct);
122 170
123 exploded->year = timestruct.tm_year + 1900; 171 exploded->year = timestruct.tm_year + 1900;
124 exploded->month = timestruct.tm_mon + 1; 172 exploded->month = timestruct.tm_mon + 1;
125 exploded->day_of_week = timestruct.tm_wday; 173 exploded->day_of_week = timestruct.tm_wday;
126 exploded->day_of_month = timestruct.tm_mday; 174 exploded->day_of_month = timestruct.tm_mday;
127 exploded->hour = timestruct.tm_hour; 175 exploded->hour = timestruct.tm_hour;
128 exploded->minute = timestruct.tm_min; 176 exploded->minute = timestruct.tm_min;
129 exploded->second = timestruct.tm_sec; 177 exploded->second = timestruct.tm_sec;
130 exploded->millisecond = millisecond; 178 exploded->millisecond = millisecond;
131 } 179 }
132 180
133 // static 181 // static
134 Time Time::FromExploded(bool is_local, const Exploded& exploded) { 182 Time Time::FromExploded(bool is_local, const Exploded& exploded) {
135 struct tm timestruct; 183 struct tm timestruct;
136 timestruct.tm_sec = exploded.second; 184 timestruct.tm_sec = exploded.second;
137 timestruct.tm_min = exploded.minute; 185 timestruct.tm_min = exploded.minute;
138 timestruct.tm_hour = exploded.hour; 186 timestruct.tm_hour = exploded.hour;
139 timestruct.tm_mday = exploded.day_of_month; 187 timestruct.tm_mday = exploded.day_of_month;
140 timestruct.tm_mon = exploded.month - 1; 188 timestruct.tm_mon = exploded.month - 1;
141 timestruct.tm_year = exploded.year - 1900; 189 timestruct.tm_year = exploded.year - 1900;
142 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this 190 timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this
143 timestruct.tm_yday = 0; // mktime/timegm ignore this 191 timestruct.tm_yday = 0; // mktime/timegm ignore this
144 timestruct.tm_isdst = -1; // attempt to figure it out 192 timestruct.tm_isdst = -1; // attempt to figure it out
145 #if !defined(OS_NACL) && !defined(OS_SOLARIS) 193 #if !defined(OS_NACL) && !defined(OS_SOLARIS)
146 timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore 194 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 195 timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore
148 #endif 196 #endif
149 197
150 time_t seconds; 198 SysTimeT seconds(&timestruct, is_local);
151 if (is_local)
152 seconds = mktime(&timestruct);
153 else
154 seconds = timegm(&timestruct);
155 199
156 int64 milliseconds; 200 int64 milliseconds;
157 // Handle overflow. Clamping the range to what mktime and timegm might 201 // 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 202 // 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 203 // than failing here or ignoring the overflow case and treating each time
160 // overflow as one second prior to the epoch. 204 // overflow as one second prior to the epoch.
161 if (seconds == -1 && 205 if (seconds.t == -1 &&
162 (exploded.year < 1969 || exploded.year > 1970)) { 206 (exploded.year < 1969 || exploded.year > 1970)) {
163 // If exploded.year is 1969 or 1970, take -1 as correct, with the 207 // 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 208 // 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 209 // 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. 210 // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC.
167 // 211 //
168 // The minimum and maximum representible times that mktime and timegm could 212 // 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 213 // return are used here instead of values outside that range to allow for
170 // proper round-tripping between exploded and counter-type time 214 // proper round-tripping between exploded and counter-type time
171 // representations in the presence of possible truncation to time_t by 215 // representations in the presence of possible truncation to time_t by
172 // division and use with other functions that accept time_t. 216 // division and use with other functions that accept time_t.
173 // 217 //
174 // When representing the most distant time in the future, add in an extra 218 // 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 219 // 999ms to avoid the time being less than any other possible value that
176 // this function can return. 220 // this function can return.
177 if (exploded.year < 1969) { 221 if (exploded.year < 1969) {
178 milliseconds = std::numeric_limits<time_t>::min() * 222 milliseconds = std::numeric_limits<SysTimeT::type>::min() *
179 kMillisecondsPerSecond; 223 kMillisecondsPerSecond;
180 } else { 224 } else {
181 milliseconds = (std::numeric_limits<time_t>::max() * 225 milliseconds = (std::numeric_limits<SysTimeT::type>::max() *
182 kMillisecondsPerSecond) + 226 kMillisecondsPerSecond) +
183 kMillisecondsPerSecond - 1; 227 kMillisecondsPerSecond - 1;
184 } 228 }
185 } else { 229 } else {
186 milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; 230 milliseconds = seconds.t * kMillisecondsPerSecond + exploded.millisecond;
187 } 231 }
188 232
189 // Adjust from Unix (1970) to Windows (1601) epoch. 233 // Adjust from Unix (1970) to Windows (1601) epoch.
190 return Time((milliseconds * kMicrosecondsPerMillisecond) + 234 return Time((milliseconds * kMicrosecondsPerMillisecond) +
191 kWindowsEpochDeltaMicroseconds); 235 kWindowsEpochDeltaMicroseconds);
192 } 236 }
193 237
194 // TimeTicks ------------------------------------------------------------------ 238 // TimeTicks ------------------------------------------------------------------
195 // FreeBSD 6 has CLOCK_MONOLITHIC but defines _POSIX_MONOTONIC_CLOCK to -1. 239 // FreeBSD 6 has CLOCK_MONOLITHIC but defines _POSIX_MONOTONIC_CLOCK to -1.
196 #if (defined(OS_POSIX) && \ 240 #if (defined(OS_POSIX) && \
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; 327 result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1;
284 return result; 328 return result;
285 } 329 }
286 int64 us = us_ - kTimeTToMicrosecondsOffset; 330 int64 us = us_ - kTimeTToMicrosecondsOffset;
287 result.tv_sec = us / Time::kMicrosecondsPerSecond; 331 result.tv_sec = us / Time::kMicrosecondsPerSecond;
288 result.tv_usec = us % Time::kMicrosecondsPerSecond; 332 result.tv_usec = us % Time::kMicrosecondsPerSecond;
289 return result; 333 return result;
290 } 334 }
291 335
292 } // namespace base 336 } // 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