// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/time.h" #include #if defined(OS_WIN) #include #endif #include #include "base/sys_string_conversions.h" #include "base/third_party/nspr/prtime.h" #include "base/logging.h" namespace base { namespace { #if defined(OS_WIN) inline bool isnan(double num) { return !!_isnan(num); } #endif } // TimeDelta ------------------------------------------------------------------ int TimeDelta::InDays() const { return static_cast(delta_ / Time::kMicrosecondsPerDay); } int TimeDelta::InHours() const { return static_cast(delta_ / Time::kMicrosecondsPerHour); } int TimeDelta::InMinutes() const { return static_cast(delta_ / Time::kMicrosecondsPerMinute); } double TimeDelta::InSecondsF() const { return static_cast(delta_) / Time::kMicrosecondsPerSecond; } int64 TimeDelta::InSeconds() const { return delta_ / Time::kMicrosecondsPerSecond; } double TimeDelta::InMillisecondsF() const { return static_cast(delta_) / Time::kMicrosecondsPerMillisecond; } int64 TimeDelta::InMilliseconds() const { return delta_ / Time::kMicrosecondsPerMillisecond; } int64 TimeDelta::InMillisecondsRoundedUp() const { return (delta_ + Time::kMicrosecondsPerMillisecond - 1) / Time::kMicrosecondsPerMillisecond; } int64 TimeDelta::InMicroseconds() const { return delta_; } // Time ----------------------------------------------------------------------- // static Time Time::Max() { return Time(std::numeric_limits::max()); } // static Time Time::FromTimeT(time_t tt) { if (tt == 0) return Time(); // Preserve 0 so we can tell it doesn't exist. if (tt == std::numeric_limits::max()) return Max(); return Time((tt * kMicrosecondsPerSecond) + kTimeTToMicrosecondsOffset); } time_t Time::ToTimeT() const { if (is_null()) return 0; // Preserve 0 so we can tell it doesn't exist. if (is_max()) { // Preserve max without offset to prevent overflow. return std::numeric_limits::max(); } if (std::numeric_limits::max() - kTimeTToMicrosecondsOffset <= us_) { DLOG(WARNING) << "Overflow when converting base::Time with internal " << "value " << us_ << " to time_t."; return std::numeric_limits::max(); } return (us_ - kTimeTToMicrosecondsOffset) / kMicrosecondsPerSecond; } // static Time Time::FromDoubleT(double dt) { if (dt == 0 || isnan(dt)) return Time(); // Preserve 0 so we can tell it doesn't exist. if (dt == std::numeric_limits::max()) return Max(); return Time(static_cast((dt * static_cast(kMicrosecondsPerSecond)) + kTimeTToMicrosecondsOffset)); } double Time::ToDoubleT() const { if (is_null()) return 0; // Preserve 0 so we can tell it doesn't exist. if (is_max()) { // Preserve max without offset to prevent overflow. return std::numeric_limits::max(); } return (static_cast(us_ - kTimeTToMicrosecondsOffset) / static_cast(kMicrosecondsPerSecond)); } // static Time Time::FromJsTime(double ms_since_epoch) { // The epoch is a valid time, so this constructor doesn't interpret // 0 as the null time. if (ms_since_epoch == std::numeric_limits::max()) return Max(); return Time(static_cast(ms_since_epoch * kMicrosecondsPerMillisecond) + kTimeTToMicrosecondsOffset); } double Time::ToJsTime() const { if (is_null()) { // Preserve 0 so the invalid result doesn't depend on the platform. return 0; } if (is_max()) { // Preserve max without offset to prevent overflow. return std::numeric_limits::max(); } return (static_cast(us_ - kTimeTToMicrosecondsOffset) / kMicrosecondsPerMillisecond); } // static Time Time::UnixEpoch() { Time time; time.us_ = kTimeTToMicrosecondsOffset; return time; } Time Time::LocalMidnight() const { Exploded exploded; LocalExplode(&exploded); exploded.hour = 0; exploded.minute = 0; exploded.second = 0; exploded.millisecond = 0; return FromLocalExploded(exploded); } // static bool Time::FromStringInternal(const char* time_string, bool is_local, Time* parsed_time) { DCHECK((time_string != NULL) && (parsed_time != NULL)); if (time_string[0] == '\0') return false; PRTime result_time = 0; PRStatus result = PR_ParseTimeString(time_string, is_local ? PR_FALSE : PR_TRUE, &result_time); if (PR_SUCCESS != result) return false; result_time += kTimeTToMicrosecondsOffset; *parsed_time = Time(result_time); return true; } // Time::Exploded ------------------------------------------------------------- inline bool is_in_range(int value, int lo, int hi) { return lo <= value && value <= hi; } bool Time::Exploded::HasValidValues() const { return is_in_range(month, 1, 12) && is_in_range(day_of_week, 0, 6) && is_in_range(day_of_month, 1, 31) && is_in_range(hour, 0, 23) && is_in_range(minute, 0, 59) && is_in_range(second, 0, 60) && is_in_range(millisecond, 0, 999); } } // namespace base