// 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. // Time represents an absolute point in coordinated universal time (UTC), // internally represented as microseconds (s/1,000,000) since the Windows epoch // (1601-01-01 00:00:00 UTC). System-dependent clock interface routines are // defined in time_PLATFORM.cc. Note that values for Time may skew and jump // around as the operating system makes adjustments to synchronize (e.g., with // NTP servers). Thus, client code that uses the Time class must account for // this. // // TimeDelta represents a duration of time, internally represented in // microseconds. // // TimeTicks and ThreadTicks represent an abstract time that is most of the time // incrementing, for use in measuring time durations. Internally, they are // represented in microseconds. They cannot be converted to a human-readable // time, but are guaranteed not to decrease (unlike the Time class). Note that // TimeTicks may "stand still" (e.g., if the computer is suspended), and // ThreadTicks will "stand still" whenever the thread has been de-scheduled by // the operating system. // // All time classes are copyable, assignable, and occupy 64-bits per instance. // As a result, prefer passing them by value: // void MyFunction(TimeDelta arg); // If circumstances require, you may also pass by const reference: // void MyFunction(const TimeDelta& arg); // Not preferred. // // Definitions of operator<< are provided to make these types work with // DCHECK_EQ() and other log macros. For human-readable formatting, see // "base/i18n/time_formatting.h". // // So many choices! Which time class should you use? Examples: // // Time: Interpreting the wall-clock time provided by a remote system. // Detecting whether cached resources have expired. Providing the // user with a display of the current date and time. Determining // the amount of time between events across re-boots of the // machine. // // TimeTicks: Tracking the amount of time a task runs. Executing delayed // tasks at the right time. Computing presentation timestamps. // Synchronizing audio and video using TimeTicks as a common // reference clock (lip-sync). Measuring network round-trip // latency. // // ThreadTicks: Benchmarking how long the current thread has been doing actual // work. #ifndef BASE_TIME_TIME_H_ #define BASE_TIME_TIME_H_ #include #include #include #include #include "base/base_export.h" #include "base/check_op.h" #include "base/compiler_specific.h" #include "base/numerics/safe_math.h" #include "base/optional.h" #include "base/strings/string_piece.h" #include "build/build_config.h" #if defined(OS_FUCHSIA) #include #endif #if defined(OS_APPLE) #include // Avoid Mac system header macro leak. #undef TYPE_BOOL #endif #if defined(OS_ANDROID) #include #endif #if defined(OS_POSIX) || defined(OS_FUCHSIA) #include #include #endif #if defined(OS_WIN) #include "base/gtest_prod_util.h" #include "base/win/windows_types.h" namespace ABI { namespace Windows { namespace Foundation { struct DateTime; } // namespace Foundation } // namespace Windows } // namespace ABI #endif namespace base { class PlatformThreadHandle; // TimeDelta ------------------------------------------------------------------ class BASE_EXPORT TimeDelta { public: constexpr TimeDelta() = default; // Converts units of time to TimeDeltas. // These conversions treat minimum argument values as min type values or -inf, // and maximum ones as max type values or +inf; and their results will produce // an is_min() or is_max() TimeDelta. WARNING: Floating point arithmetic is // such that FromXXXD(t.InXXXF()) may not precisely equal |t|. Hence, floating // point values should not be used for storage. static constexpr TimeDelta FromDays(int days); static constexpr TimeDelta FromHours(int hours); static constexpr TimeDelta FromMinutes(int minutes); static constexpr TimeDelta FromSecondsD(double secs); static constexpr TimeDelta FromSeconds(int64_t secs); static constexpr TimeDelta FromMillisecondsD(double ms); static constexpr TimeDelta FromMilliseconds(int64_t ms); static constexpr TimeDelta FromMicrosecondsD(double us); static constexpr TimeDelta FromMicroseconds(int64_t us); static constexpr TimeDelta FromNanosecondsD(double ns); static constexpr TimeDelta FromNanoseconds(int64_t ns); #if defined(OS_WIN) static TimeDelta FromQPCValue(LONGLONG qpc_value); // TODO(crbug.com/989694): Avoid base::TimeDelta factory functions // based on absolute time static TimeDelta FromFileTime(FILETIME ft); static TimeDelta FromWinrtDateTime(ABI::Windows::Foundation::DateTime dt); #elif defined(OS_POSIX) || defined(OS_FUCHSIA) static TimeDelta FromTimeSpec(const timespec& ts); #endif #if defined(OS_FUCHSIA) static TimeDelta FromZxDuration(zx_duration_t nanos); #endif #if defined(OS_MAC) static TimeDelta FromMachTime(uint64_t mach_time); #endif // defined(OS_MAC) // Converts a frequency in Hertz (cycles per second) into a period. static constexpr TimeDelta FromHz(double frequency); // From Go's doc at https://golang.org/pkg/time/#ParseDuration // [ParseDuration] parses a duration string. A duration string is // a possibly signed sequence of decimal numbers, each with optional // fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". // Valid time units are "ns", "us" "ms", "s", "m", "h". // // Special values that are allowed without specifying units: // "0", "+0", "-0" -> TimeDelta() // "inf", "+inf" -> TimeDelta::Max() // "-inf" -> TimeDelta::Min() // Returns |base::nullopt| when parsing fails. Numbers larger than 2^63-1 // will fail parsing. Overflowing `number * unit` will return +/-inf, as // appropriate. static Optional FromString(StringPiece duration_string); // Converts an integer value representing TimeDelta to a class. This is used // when deserializing a |TimeDelta| structure, using a value known to be // compatible. It is not provided as a constructor because the integer type // may be unclear from the perspective of a caller. // // DEPRECATED - Do not use in new code. http://crbug.com/634507 static constexpr TimeDelta FromInternalValue(int64_t delta) { return TimeDelta(delta); } // Returns the maximum time delta, which should be greater than any reasonable // time delta we might compare it to. Adding or subtracting the maximum time // delta to a time or another time delta has an undefined result. static constexpr TimeDelta Max(); // Returns the minimum time delta, which should be less than than any // reasonable time delta we might compare it to. Adding or subtracting the // minimum time delta to a time or another time delta has an undefined result. static constexpr TimeDelta Min(); // Returns the internal numeric value of the TimeDelta object. Please don't // use this and do arithmetic on it, as it is more error prone than using the // provided operators. // For serializing, use FromInternalValue to reconstitute. // // DEPRECATED - Do not use in new code. http://crbug.com/634507 constexpr int64_t ToInternalValue() const { return delta_; } // Returns the magnitude (absolute value) of this TimeDelta. constexpr TimeDelta magnitude() const { // The code below will not work correctly in this corner case. if (is_min()) return Max(); // std::abs() is not currently constexpr. The following is a simple // branchless implementation: const int64_t mask = delta_ >> (sizeof(delta_) * 8 - 1); return TimeDelta((delta_ + mask) ^ mask); } // Returns true if the time delta is zero. constexpr bool is_zero() const { return delta_ == 0; } // Returns true if the time delta is the maximum/minimum time delta. constexpr bool is_max() const { return *this == Max(); } constexpr bool is_min() const { return *this == Min(); } constexpr bool is_inf() const { return is_min() || is_max(); } #if defined(OS_POSIX) || defined(OS_FUCHSIA) struct timespec ToTimeSpec() const; #endif #if defined(OS_FUCHSIA) zx_duration_t ToZxDuration() const; #endif #if defined(OS_WIN) ABI::Windows::Foundation::DateTime ToWinrtDateTime() const; #endif // Returns the frequency in Hertz (cycles per second) that has a period of // *this. constexpr double ToHz() const { return FromSeconds(1) / *this; } // Returns the time delta in some unit. Minimum argument values return as // -inf for doubles and min type values otherwise. Maximum ones are treated as // +inf for doubles and max type values otherwise. Their results will produce // an is_min() or is_max() TimeDelta. The InXYZF versions return a floating // point value. The InXYZ versions return a truncated value (aka rounded // towards zero, std::trunc() behavior). The InXYZFloored() versions round to // lesser integers (std::floor() behavior). The XYZRoundedUp() versions round // up to greater integers (std::ceil() behavior). WARNING: Floating point // arithmetic is such that FromXXXD(t.InXXXF()) may not precisely equal |t|. // Hence, floating point values should not be used for storage. int InDays() const; int InDaysFloored() const; constexpr int InHours() const; constexpr int InMinutes() const; double InSecondsF() const; int64_t InSeconds() const; double InMillisecondsF() const; int64_t InMilliseconds() const; int64_t InMillisecondsRoundedUp() const; constexpr int64_t InMicroseconds() const { return delta_; } double InMicrosecondsF() const; constexpr int64_t InNanoseconds() const; // Computations with other deltas. constexpr TimeDelta operator+(TimeDelta other) const; constexpr TimeDelta operator-(TimeDelta other) const; constexpr TimeDelta& operator+=(TimeDelta other) { return *this = (*this + other); } constexpr TimeDelta& operator-=(TimeDelta other) { return *this = (*this - other); } constexpr TimeDelta operator-() const { if (!is_inf()) return TimeDelta(-delta_); return (delta_ < 0) ? Max() : Min(); } // Computations with numeric types. template constexpr TimeDelta operator*(T a) const { CheckedNumeric rv(delta_); rv *= a; if (rv.IsValid()) return TimeDelta(rv.ValueOrDie()); return ((delta_ < 0) == (a < 0)) ? Max() : Min(); } template constexpr TimeDelta operator/(T a) const { CheckedNumeric rv(delta_); rv /= a; if (rv.IsValid()) return TimeDelta(rv.ValueOrDie()); return ((delta_ < 0) == (a < 0)) ? Max() : Min(); } template constexpr TimeDelta& operator*=(T a) { return *this = (*this * a); } template constexpr TimeDelta& operator/=(T a) { return *this = (*this / a); } // This does floating-point division. For an integer result, either call // IntDiv(), or (possibly clearer) use this operator with // base::Clamp{Ceil,Floor,Round}() or base::saturated_cast() (for truncation). // Note that converting to double here drops precision to 53 bits. constexpr double operator/(TimeDelta a) const { // 0/0 and inf/inf (any combination of positive and negative) are invalid // (they are almost certainly not intentional, and result in NaN, which // turns into 0 if clamped to an integer; this makes introducing subtle bugs // too easy). CHECK((!is_zero() || !a.is_zero()) && (!is_inf() || !a.is_inf())); return ToDouble() / a.ToDouble(); } constexpr int64_t IntDiv(TimeDelta a) const { if (!is_inf() && !a.is_zero()) return delta_ / a.delta_; // For consistency, use the same edge case CHECKs and behavior as the code // above. CHECK((!is_zero() || !a.is_zero()) && (!is_inf() || !a.is_inf())); return ((delta_ < 0) == (a.delta_ < 0)) ? std::numeric_limits::max() : std::numeric_limits::min(); } constexpr TimeDelta operator%(TimeDelta a) const { return TimeDelta( (is_inf() || a.is_zero() || a.is_inf()) ? delta_ : (delta_ % a.delta_)); } TimeDelta& operator%=(TimeDelta other) { return *this = (*this % other); } // Comparison operators. constexpr bool operator==(TimeDelta other) const { return delta_ == other.delta_; } constexpr bool operator!=(TimeDelta other) const { return delta_ != other.delta_; } constexpr bool operator<(TimeDelta other) const { return delta_ < other.delta_; } constexpr bool operator<=(TimeDelta other) const { return delta_ <= other.delta_; } constexpr bool operator>(TimeDelta other) const { return delta_ > other.delta_; } constexpr bool operator>=(TimeDelta other) const { return delta_ >= other.delta_; } // Returns this delta, ceiled/floored/rounded-away-from-zero to the nearest // multiple of |interval|. TimeDelta CeilToMultiple(TimeDelta interval) const; TimeDelta FloorToMultiple(TimeDelta interval) const; TimeDelta RoundToMultiple(TimeDelta interval) const; private: // Constructs a delta given the duration in microseconds. This is private // to avoid confusion by callers with an integer constructor. Use // FromSeconds, FromMilliseconds, etc. instead. constexpr explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {} // Returns a double representation of this TimeDelta's tick count. In // particular, Max()/Min() are converted to +/-infinity. constexpr double ToDouble() const { if (!is_inf()) return static_cast(delta_); return (delta_ < 0) ? -std::numeric_limits::infinity() : std::numeric_limits::infinity(); } // Delta in microseconds. int64_t delta_ = 0; }; constexpr TimeDelta TimeDelta::operator+(TimeDelta other) const { if (!other.is_inf()) return TimeDelta(int64_t{base::ClampAdd(delta_, other.delta_)}); // Additions involving two infinities are only valid if signs match. CHECK(!is_inf() || (delta_ == other.delta_)); return other; } constexpr TimeDelta TimeDelta::operator-(TimeDelta other) const { if (!other.is_inf()) return TimeDelta(int64_t{base::ClampSub(delta_, other.delta_)}); // Subtractions involving two infinities are only valid if signs differ. CHECK_NE(delta_, other.delta_); return (other.delta_ < 0) ? Max() : Min(); } template constexpr TimeDelta operator*(T a, TimeDelta td) { return td * a; } // For logging use only. BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeDelta time_delta); // TimeBase-------------------------------------------------------------------- // Do not reference the time_internal::TimeBase template class directly. Please // use one of the time subclasses instead, and only reference the public // TimeBase members via those classes. namespace time_internal { // Provides value storage and comparison/math operations common to all time // classes. Each subclass provides for strong type-checking to ensure // semantically meaningful comparison/math of time values from the same clock // source or timeline. template class TimeBase { public: static constexpr int64_t kHoursPerDay = 24; static constexpr int64_t kSecondsPerMinute = 60; static constexpr int64_t kMinutesPerHour = 60; static constexpr int64_t kSecondsPerHour = kSecondsPerMinute * kMinutesPerHour; static constexpr int64_t kMillisecondsPerSecond = 1000; static constexpr int64_t kMillisecondsPerDay = kMillisecondsPerSecond * kSecondsPerHour * kHoursPerDay; static constexpr int64_t kMicrosecondsPerMillisecond = 1000; static constexpr int64_t kMicrosecondsPerSecond = kMicrosecondsPerMillisecond * kMillisecondsPerSecond; static constexpr int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * kSecondsPerMinute; static constexpr int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * kMinutesPerHour; static constexpr int64_t kMicrosecondsPerDay = kMicrosecondsPerHour * kHoursPerDay; static constexpr int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7; static constexpr int64_t kNanosecondsPerMicrosecond = 1000; static constexpr int64_t kNanosecondsPerSecond = kNanosecondsPerMicrosecond * kMicrosecondsPerSecond; // Returns true if this object has not been initialized. // // Warning: Be careful when writing code that performs math on time values, // since it's possible to produce a valid "zero" result that should not be // interpreted as a "null" value. constexpr bool is_null() const { return us_ == 0; } // Returns true if this object represents the maximum/minimum time. constexpr bool is_max() const { return *this == Max(); } constexpr bool is_min() const { return *this == Min(); } constexpr bool is_inf() const { return is_min() || is_max(); } // Returns the maximum/minimum times, which should be greater/less than than // any reasonable time with which we might compare it. static constexpr TimeClass Max() { return TimeClass(std::numeric_limits::max()); } static constexpr TimeClass Min() { return TimeClass(std::numeric_limits::min()); } // For serializing only. Use FromInternalValue() to reconstitute. Please don't // use this and do arithmetic on it, as it is more error prone than using the // provided operators. // // DEPRECATED - Do not use in new code. For serializing Time values, prefer // Time::ToDeltaSinceWindowsEpoch().InMicroseconds(). http://crbug.com/634507 constexpr int64_t ToInternalValue() const { return us_; } // The amount of time since the origin (or "zero") point. This is a syntactic // convenience to aid in code readability, mainly for debugging/testing use // cases. // // Warning: While the Time subclass has a fixed origin point, the origin for // the other subclasses can vary each time the application is restarted. constexpr TimeDelta since_origin() const { return TimeDelta::FromMicroseconds(us_); } constexpr TimeClass& operator=(TimeClass other) { us_ = other.us_; return *(static_cast(this)); } // Compute the difference between two times. constexpr TimeDelta operator-(TimeClass other) const { return TimeDelta::FromMicroseconds(us_ - other.us_); } // Return a new time modified by some delta. constexpr TimeClass operator+(TimeDelta delta) const { return TimeClass( (TimeDelta::FromMicroseconds(us_) + delta).InMicroseconds()); } constexpr TimeClass operator-(TimeDelta delta) const { return TimeClass( (TimeDelta::FromMicroseconds(us_) - delta).InMicroseconds()); } // Modify by some time delta. constexpr TimeClass& operator+=(TimeDelta delta) { return static_cast(*this = (*this + delta)); } constexpr TimeClass& operator-=(TimeDelta delta) { return static_cast(*this = (*this - delta)); } // Comparison operators constexpr bool operator==(TimeClass other) const { return us_ == other.us_; } constexpr bool operator!=(TimeClass other) const { return us_ != other.us_; } constexpr bool operator<(TimeClass other) const { return us_ < other.us_; } constexpr bool operator<=(TimeClass other) const { return us_ <= other.us_; } constexpr bool operator>(TimeClass other) const { return us_ > other.us_; } constexpr bool operator>=(TimeClass other) const { return us_ >= other.us_; } protected: constexpr explicit TimeBase(int64_t us) : us_(us) {} // Time value in a microsecond timebase. int64_t us_; }; } // namespace time_internal template inline constexpr TimeClass operator+(TimeDelta delta, TimeClass t) { return t + delta; } // Time ----------------------------------------------------------------------- // Represents a wall clock time in UTC. Values are not guaranteed to be // monotonically non-decreasing and are subject to large amounts of skew. // Time is stored internally as microseconds since the Windows epoch (1601). class BASE_EXPORT Time : public time_internal::TimeBase