// Copyright 2012 The Chromium Authors// 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.// Prefer to pass them by value, e.g.://// void MyFunction(TimeDelta arg);//// All time classes support `operator<<` with logging streams, e.g. `LOG(INFO)`.// For human-readable formatting, use //base/i18n/time_formatting.h.//// Example use cases for different time classes://// 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.//// Serialization://// Use the helpers in //base/json/values_util.h when serializing `Time`// or `TimeDelta` to/from `base::Value`.//// Otherwise://// - Time: use `FromDeltaSinceWindowsEpoch()`/`ToDeltaSinceWindowsEpoch()`.// - TimeDelta: use `base::Microseconds()`/`InMicroseconds()`.//// `TimeTicks` and `ThreadTicks` do not have a stable origin; serialization for// the purpose of persistence is not supported.#ifndef BASE_TIME_TIME_H_#define BASE_TIME_TIME_H_#include<stdint.h>#include<time.h>#include<iosfwd>#include<limits>#include<ostream>#include"base/base_export.h"#include"base/check.h"#include"base/check_op.h"#include"base/compiler_specific.h"#include"base/numerics/clamped_math.h"#include"build/build_config.h"#include"build/chromeos_buildflags.h"#if BUILDFLAG(IS_APPLE)#include"base/time/buildflags/buildflags.h"#endif#if BUILDFLAG(IS_FUCHSIA)#include<zircon/types.h>#endif#if BUILDFLAG(IS_APPLE)#include<CoreFoundation/CoreFoundation.h>#include<mach/mach_time.h>// Avoid Mac system header macro leak.#undef TYPE_BOOL#endif#if BUILDFLAG(IS_ANDROID)#include<jni.h>#endif#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)#include<unistd.h>#include<sys/time.h>#endif#if BUILDFLAG(IS_WIN)#include"base/gtest_prod_util.h"#include"base/win/windows_types.h"namespaceABI{namespaceWindows{namespaceFoundation{structDateTime;structTimeSpan;}// namespace Foundation}// namespace Windows}// namespace ABI#endifnamespacebase{classPlatformThreadHandle;classTimeDelta;template<typenameT>constexprTimeDeltaMicroseconds(Tn);// TimeDelta ------------------------------------------------------------------classBASE_EXPORTTimeDelta{public:constexprTimeDelta()=default;#if BUILDFLAG(IS_WIN)staticTimeDeltaFromQPCValue(LONGLONGqpc_value);// TODO(crbug.com/989694): Avoid base::TimeDelta factory functions// based on absolute timestaticTimeDeltaFromFileTime(FILETIMEft);staticTimeDeltaFromWinrtDateTime(ABI::Windows::Foundation::DateTimedt);staticTimeDeltaFromWinrtTimeSpan(ABI::Windows::Foundation::TimeSpants);#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)staticTimeDeltaFromTimeSpec(consttimespec&ts);#endif#if BUILDFLAG(IS_FUCHSIA)staticTimeDeltaFromZxDuration(zx_duration_tnanos);#endif#if BUILDFLAG(IS_APPLE)#if BUILDFLAG(ENABLE_MACH_ABSOLUTE_TIME_TICKS)staticTimeDeltaFromMachTime(uint64_tmach_time);#endif // BUILDFLAG(ENABLE_MACH_ABSOLUTE_TIME_TICKS)#endif // BUILDFLAG(IS_APPLE)// 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/634507staticconstexprTimeDeltaFromInternalValue(int64_tdelta){returnTimeDelta(delta);}// Returns the maximum time delta, which should be greater than any reasonable// time delta we might compare it to. If converted to double with ToDouble()// it becomes an IEEE double infinity. Use FiniteMax() if you want a very// large number that doesn't do this. TimeDelta math saturates at the end// points so adding to TimeDelta::Max() leaves the value unchanged.// Subtracting should leave the value unchanged but currently changes it// TODO(https://crbug.com/869387).staticconstexprTimeDeltaMax();// Returns the minimum time delta, which should be less than than any// reasonable time delta we might compare it to. For more details see the// comments for Max().staticconstexprTimeDeltaMin();// Returns the maximum time delta which is not equivalent to infinity. Only// subtracting a finite time delta from this time delta has a defined result.staticconstexprTimeDeltaFiniteMax();// Returns the minimum time delta which is not equivalent to -infinity. Only// adding a finite time delta to this time delta has a defined result.staticconstexprTimeDeltaFiniteMin();// 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/634507constexprint64_tToInternalValue()const{returndelta_;}// Returns the magnitude (absolute value) of this TimeDelta.constexprTimeDeltamagnitude()const{returnTimeDelta(delta_.Abs());}// Returns true if the time delta is a zero, positive or negative time delta.constexprboolis_zero()const{returndelta_==0;}constexprboolis_positive()const{returndelta_>0;}constexprboolis_negative()const{returndelta_<0;}// Returns true if the time delta is the maximum/minimum time delta.constexprboolis_max()const{return*this==Max();}constexprboolis_min()const{return*this==Min();}constexprboolis_inf()const{returnis_min()||is_max();}#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)structtimespecToTimeSpec()const;#endif#if BUILDFLAG(IS_FUCHSIA)zx_duration_tToZxDuration()const;#endif#if BUILDFLAG(IS_WIN)ABI::Windows::Foundation::DateTimeToWinrtDateTime()const;ABI::Windows::Foundation::TimeSpanToWinrtTimeSpan()const;#endif// Returns the frequency in Hertz (cycles per second) that has a period of// *this.constexprdoubleToHz()const;// 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 XXX(t.InXXXF()) may not precisely equal |t|.// Hence, floating point values should not be used for storage.constexprintInDays()const;constexprintInDaysFloored()const;constexprintInHours()const;constexprintInMinutes()const;constexprdoubleInSecondsF()const;constexprint64_tInSeconds()const;constexprint64_tInSecondsFloored()const;constexprdoubleInMillisecondsF()const;constexprint64_tInMilliseconds()const;constexprint64_tInMillisecondsRoundedUp()const;constexprint64_tInMicroseconds()const{returndelta_;}constexprdoubleInMicrosecondsF()const;constexprint64_tInNanoseconds()const;// Computations with other deltas.constexprTimeDeltaoperator+(TimeDeltaother)const;constexprTimeDeltaoperator-(TimeDeltaother)const;constexprTimeDelta&operator+=(TimeDeltaother){return*this=(*this+other);}constexprTimeDelta&operator-=(TimeDeltaother){return*this=(*this-other);}constexprTimeDeltaoperator-()const{if(!is_inf())returnTimeDelta(-delta_);return(delta_<0)?Max():Min();}// Computations with numeric types.template<typenameT>constexprTimeDeltaoperator*(Ta)const{returnTimeDelta(int64_t{delta_*a});}template<typenameT>constexprTimeDeltaoperator/(Ta)const{returnTimeDelta(int64_t{delta_/a});}template<typenameT>constexprTimeDelta&operator*=(Ta){return*this=(*this*a);}template<typenameT>constexprTimeDelta&operator/=(Ta){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.constexprdoubleoperator/(TimeDeltaa)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());CHECK(!is_inf()||!a.is_inf());returnToDouble()/a.ToDouble();}constexprint64_tIntDiv(TimeDeltaa)const{if(!is_inf()&&!a.is_zero())returnint64_t{delta_/a.delta_};// For consistency, use the same edge case CHECKs and behavior as the code// above.CHECK(!is_zero()||!a.is_zero());CHECK(!is_inf()||!a.is_inf());return((delta_<0)==(a.delta_<0))?std::numeric_limits<int64_t>::max():std::numeric_limits<int64_t>::min();}constexprTimeDeltaoperator%(TimeDeltaa)const{returnTimeDelta((is_inf()||a.is_zero()||a.is_inf())?delta_:(delta_%a.delta_));}constexprTimeDelta&operator%=(TimeDeltaother){return*this=(*this%other);}// Comparison operators.constexprbooloperator==(TimeDeltaother)const{returndelta_==other.delta_;}constexprbooloperator!=(TimeDeltaother)const{returndelta_!=other.delta_;}constexprbooloperator<(TimeDeltaother)const{returndelta_<other.delta_;}constexprbooloperator<=(TimeDeltaother)const{returndelta_<=other.delta_;}constexprbooloperator>(TimeDeltaother)const{returndelta_>other.delta_;}constexprbooloperator>=(TimeDeltaother)const{returndelta_>=other.delta_;}// Returns this delta, ceiled/floored/rounded-away-from-zero to the nearest// multiple of |interval|.TimeDeltaCeilToMultiple(TimeDeltainterval)const;TimeDeltaFloorToMultiple(TimeDeltainterval)const;TimeDeltaRoundToMultiple(TimeDeltainterval)const;private:// Constructs a delta given the duration in microseconds. This is private// to avoid confusion by callers with an integer constructor. Use// base::Seconds, base::Milliseconds, etc. instead.constexprexplicitTimeDelta(int64_tdelta_us):delta_(delta_us){}constexprexplicitTimeDelta(ClampedNumeric<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.constexprdoubleToDouble()const{if(!is_inf())returnstatic_cast<double>(delta_);return(delta_<0)?-std::numeric_limits<double>::infinity():std::numeric_limits<double>::infinity();}// Delta in microseconds.ClampedNumeric<int64_t>delta_=0;};constexprTimeDeltaTimeDelta::operator+(TimeDeltaother)const{if(!other.is_inf())returnTimeDelta(delta_+other.delta_);// Additions involving two infinities are only valid if signs match.CHECK(!is_inf()||(delta_==other.delta_));returnother;}constexprTimeDeltaTimeDelta::operator-(TimeDeltaother)const{if(!other.is_inf())returnTimeDelta(delta_-other.delta_);// Subtractions involving two infinities are only valid if signs differ.CHECK_NE(int64_t{delta_},int64_t{other.delta_});return(other.delta_<0)?Max():Min();}template<typenameT>constexprTimeDeltaoperator*(Ta,TimeDeltatd){returntd*a;}// For logging use only.BASE_EXPORTstd::ostream&operator<<(std::ostream&os,TimeDeltatime_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.namespacetime_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<classTimeClass>classTimeBase{public:staticconstexprint64_tkHoursPerDay=24;staticconstexprint64_tkSecondsPerMinute=60;staticconstexprint64_tkMinutesPerHour=60;staticconstexprint64_tkSecondsPerHour=kSecondsPerMinute*kMinutesPerHour;staticconstexprint64_tkMillisecondsPerSecond=1000;staticconstexprint64_tkMillisecondsPerDay=kMillisecondsPerSecond*kSecondsPerHour*kHoursPerDay;staticconstexprint64_tkMicrosecondsPerMillisecond=1000;staticconstexprint64_tkMicrosecondsPerSecond=kMicrosecondsPerMillisecond*kMillisecondsPerSecond;staticconstexprint64_tkMicrosecondsPerMinute=kMicrosecondsPerSecond*kSecondsPerMinute;staticconstexprint64_tkMicrosecondsPerHour=kMicrosecondsPerMinute*kMinutesPerHour;staticconstexprint64_tkMicrosecondsPerDay=kMicrosecondsPerHour*kHoursPerDay;staticconstexprint64_tkMicrosecondsPerWeek=kMicrosecondsPerDay*7;staticconstexprint64_tkNanosecondsPerMicrosecond=1000;staticconstexprint64_tkNanosecondsPerSecond=kNanosecondsPerMicrosecond*kMicrosecondsPerSecond;// TODO(https://crbug.com/1392437): Remove concept of "null" from base::Time.//// 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. If you find yourself using this method or// the zero-arg default constructor, please consider using an optional to// express the null state.//// Returns true if this object has not been initialized (probably).constexprboolis_null()const{returnus_==0;}// Returns true if this object represents the maximum/minimum time.constexprboolis_max()const{return*this==Max();}constexprboolis_min()const{return*this==Min();}constexprboolis_inf()const{returnis_min()||is_max();}// Returns the maximum/minimum times, which should be greater/less than than// any reasonable time with which we might compare it.staticconstexprTimeClassMax(){returnTimeClass(std::numeric_limits<int64_t>::max());}staticconstexprTimeClassMin(){returnTimeClass(std::numeric_limits<int64_t>::min());}// For legacy serialization only. When serializing to `base::Value`, prefer// the helpers from //base/json/values_util.h instead. Otherwise, use// `Time::ToDeltaSinceWindowsEpoch()` for `Time` and// `TimeDelta::InMicroseconds()` for `TimeDelta`. See http://crbug.com/634507.constexprint64_tToInternalValue()const{returnus_;}// 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.constexprTimeDeltasince_origin()const;// Compute the difference between two times.#if !defined(__aarch64__) && BUILDFLAG(IS_ANDROID)NOINLINE// https://crbug.com/1369775#endifconstexprTimeDeltaoperator-(constTimeBase<TimeClass>&other)const;// Return a new time modified by some delta.constexprTimeClassoperator+(TimeDeltadelta)const;constexprTimeClassoperator-(TimeDeltadelta)const;// Modify by some time delta.constexprTimeClass&operator+=(TimeDeltadelta){returnstatic_cast<TimeClass&>(*this=(*this+delta));}constexprTimeClass&operator-=(TimeDeltadelta){returnstatic_cast<TimeClass&>(*this=(*this-delta));}// Comparison operatorsconstexprbooloperator==(constTimeBase<TimeClass>&other)const{returnus_==other.us_;}constexprbooloperator!=(constTimeBase<TimeClass>&other)const{returnus_!=other.us_;}constexprbooloperator<(constTimeBase<TimeClass>&other)const{returnus_<other.us_;}constexprbooloperator<=(constTimeBase<TimeClass>&other)const{returnus_<=other.us_;}constexprbooloperator>(constTimeBase<TimeClass>&other)const{returnus_>other.us_;}constexprbooloperator>=(constTimeBase<TimeClass>&other)const{returnus_>=other.us_;}protected:constexprexplicitTimeBase(int64_tus):us_(us){}// Time value in a microsecond timebase.ClampedNumeric<int64_t>us_;};#if BUILDFLAG(IS_WIN)#if defined(ARCH_CPU_ARM64)// TSCTicksPerSecond is not supported on Windows on Arm systems because the// cycle-counting methods use the actual CPU cycle count, and not a consistent// incrementing counter.#else// Returns true if the CPU support constant rate TSC.[[nodiscard]]BASE_EXPORTboolHasConstantRateTSC();// Returns the frequency of the TSC in ticks per second, or 0 if it hasn't// been measured yet. Needs to be guarded with a call to HasConstantRateTSC().[[nodiscard]]BASE_EXPORTdoubleTSCTicksPerSecond();#endif#endif // BUILDFLAG(IS_WIN)}// namespace time_internaltemplate<classTimeClass>inlineconstexprTimeClassoperator+(TimeDeltadelta,TimeClasst){returnt+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).classBASE_EXPORTTime:publictime_internal::TimeBase<Time>{public:// Offset of UNIX epoch (1970-01-01 00:00:00 UTC) from Windows FILETIME epoch// (1601-01-01 00:00:00 UTC), in microseconds. This value is derived from the// following: ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the number// of leap year days between 1601 and 1970: (1970-1601)/4 excluding 1700,// 1800, and 1900.staticconstexprint64_tkTimeTToMicrosecondsOffset=INT64_C(11644473600000000);#if BUILDFLAG(IS_WIN)// To avoid overflow in QPC to Microseconds calculations, since we multiply// by kMicrosecondsPerSecond, then the QPC value should not exceed// (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply.staticconstexprint64_tkQPCOverflowThreshold=INT64_C(0x8637BD05AF7);#endif// kExplodedMinYear and kExplodedMaxYear define the platform-specific limits// for values passed to FromUTCExploded() and FromLocalExploded(). Those// functions will return false if passed values outside these limits. The limits// are inclusive, meaning that the API should support all dates within a given// limit year.//// WARNING: These are not the same limits for the inverse functionality,// UTCExplode() and LocalExplode(). See method comments for further details.#if BUILDFLAG(IS_WIN)staticconstexprintkExplodedMinYear=1601;staticconstexprintkExplodedMaxYear=30827;#elif BUILDFLAG(IS_IOS) && !__LP64__staticconstexprintkExplodedMinYear=std::numeric_limits<int>::min();staticconstexprintkExplodedMaxYear=std::numeric_limits<int>::max();#elif BUILDFLAG(IS_APPLE)staticconstexprintkExplodedMinYear=1902;staticconstexprintkExplodedMaxYear=std::numeric_limits<int>::max();#elif BUILDFLAG(IS_ANDROID)// Though we use 64-bit time APIs on both 32 and 64 bit Android, some OS// versions like KitKat (ARM but not x86 emulator) can't handle some early// dates (e.g. before 1170). So we set min conservatively here.staticconstexprintkExplodedMinYear=1902;staticconstexprintkExplodedMaxYear=std::numeric_limits<int>::max();#elsestaticconstexprintkExplodedMinYear=(sizeof(time_t)==4?1902:std::numeric_limits<int>::min());staticconstexprintkExplodedMaxYear=(sizeof(time_t)==4?2037:std::numeric_limits<int>::max());#endif// Represents an exploded time that can be formatted nicely. This is kind of// like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few// additions and changes to prevent errors.// This structure always represents dates in the Gregorian calendar and always// encodes day_of_week as Sunday==0, Monday==1, .., Saturday==6. This means// that base::Time::LocalExplode and base::Time::FromLocalExploded only// respect the current local time zone in the conversion and do *not* use a// calendar or day-of-week encoding from the current locale.structBASE_EXPORTExploded{intyear;// Four digit year "2007"intmonth;// 1-based month (values 1 = January, etc.)intday_of_week;// 0-based day of week (0 = Sunday, etc.)intday_of_month;// 1-based day of month (1-31)inthour;// Hour within the current day (0-23)intminute;// Minute within the current hour (0-59)intsecond;// Second within the current minute (0-59 plus leap// seconds which may take it up to 60).intmillisecond;// Milliseconds within the current second (0-999)// A cursory test for whether the data members are within their// respective ranges. A 'true' return value does not guarantee the// Exploded value can be successfully converted to a Time value.boolHasValidValues()const;};// TODO(https://crbug.com/1392437): Remove concept of "null" from base::Time.//// 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. If you find yourself using this constructor// or the is_null() method, please consider using an optional to express the// null state.//// Contains the NULL time. Use Time::Now() to get the current time.constexprTime():TimeBase(0){}// Returns the time for epoch in Unix-like system (Jan 1, 1970).staticconstexprTimeUnixEpoch(){returnTime(kTimeTToMicrosecondsOffset);}// Returns the current time. Watch out, the system might adjust its clock// in which case time will actually go backwards. We don't guarantee that// times are increasing, or that two calls to Now() won't be the same.staticTimeNow();// Returns the current time. Same as Now() except that this function always// uses system time so that there are no discrepancies between the returned// time and system time even on virtual environments including our test bot.// For timing sensitive unittests, this function should be used.staticTimeNowFromSystemTime();// Converts to/from TimeDeltas relative to the Windows epoch (1601-01-01// 00:00:00 UTC).//// For serialization, when handling `base::Value`, prefer the helpers in// //base/json/values_util.h instead. Otherwise, use these methods for// opaque serialization and deserialization, e.g.//// // Serialization:// base::Time last_updated = ...;// SaveToDatabase(last_updated.ToDeltaSinceWindowsEpoch().InMicroseconds());//// // Deserialization:// base::Time last_updated = base::Time::FromDeltaSinceWindowsEpoch(// base::Microseconds(LoadFromDatabase()));//// Do not use `FromInternalValue()` or `ToInternalValue()` for this purpose.staticconstexprTimeFromDeltaSinceWindowsEpoch(TimeDeltadelta){returnTime(delta.InMicroseconds());}constexprTimeDeltaToDeltaSinceWindowsEpoch()const{returnMicroseconds(us_);}// Converts to/from time_t in UTC and a Time class.staticconstexprTimeFromTimeT(time_ttt);constexprtime_tToTimeT()const;// Converts time to/from a double which is the number of seconds since epoch// (Jan 1, 1970). Webkit uses this format to represent time.// Because WebKit initializes double time value to 0 to indicate "not// initialized", we map it to empty Time object that also means "not// initialized".staticconstexprTimeFromDoubleT(doubledt);constexprdoubleToDoubleT()const;#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)// Converts the timespec structure to time. MacOS X 10.8.3 (and tentatively,// earlier versions) will have the |ts|'s tv_nsec component zeroed out,// having a 1 second resolution, which agrees with// https://developer.apple.com/legacy/library/#technotes/tn/tn1150.html#HFSPlusDates.staticconstexprTimeFromTimeSpec(consttimespec&ts);#endif// Converts to/from the Javascript convention for times, a number of// milliseconds since the epoch:// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/getTime.//// Don't use ToJsTime() in new code, since it contains a subtle hack (only// exactly 1601-01-01 00:00 UTC is represented as 1970-01-01 00:00 UTC), and// that is not appropriate for general use. Try to use ToJsTimeIgnoringNull()// unless you have a very good reason to use ToJsTime().staticconstexprTimeFromJsTime(doublems_since_epoch);constexprdoubleToJsTime()const;constexprdoubleToJsTimeIgnoringNull()const;// Converts to/from Java convention for times, a number of milliseconds since// the epoch. Because the Java format has less resolution, converting to Java// time is a lossy operation.staticconstexprTimeFromJavaTime(int64_tms_since_epoch);constexprint64_tToJavaTime()const;#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)staticTimeFromTimeVal(structtimevalt);structtimevalToTimeVal()const;#endif#if BUILDFLAG(IS_FUCHSIA)staticTimeFromZxTime(zx_time_ttime);zx_time_tToZxTime()const;#endif#if BUILDFLAG(IS_APPLE)staticTimeFromCFAbsoluteTime(CFAbsoluteTimet);CFAbsoluteTimeToCFAbsoluteTime()const;#if defined(__OBJC__)staticTimeFromNSDate(NSDate*date);NSDate*ToNSDate()const;#endif#endif#if BUILDFLAG(IS_WIN)staticTimeFromFileTime(FILETIMEft);FILETIMEToFileTime()const;// The minimum time of a low resolution timer. This is basically a windows// constant of ~15.6ms. While it does vary on some older OS versions, we'll// treat it as static across all windows versions.staticconstintkMinLowResolutionThresholdMs=16;// Enable or disable Windows high resolution timer.staticvoidEnableHighResolutionTimer(boolenable);// Activates or deactivates the high resolution timer based on the |activate|// flag. If the HighResolutionTimer is not Enabled (see// EnableHighResolutionTimer), this function will return false. Otherwise// returns true. Each successful activate call must be paired with a// subsequent deactivate call.// All callers to activate the high resolution timer must eventually call// this function to deactivate the high resolution timer.staticboolActivateHighResolutionTimer(boolactivate);// Returns true if the high resolution timer is both enabled and activated.// This is provided for testing only, and is not tracked in a thread-safe// way.staticboolIsHighResolutionTimerInUse();// The following two functions are used to report the fraction of elapsed time// that the high resolution timer is activated.// ResetHighResolutionTimerUsage() resets the cumulative usage and starts the// measurement interval and GetHighResolutionTimerUsage() returns the// percentage of time since the reset that the high resolution timer was// activated.// ResetHighResolutionTimerUsage() must be called at least once before calling// GetHighResolutionTimerUsage(); otherwise the usage result would be// undefined.staticvoidResetHighResolutionTimerUsage();staticdoubleGetHighResolutionTimerUsage();#endif // BUILDFLAG(IS_WIN)// Converts an exploded structure representing either the local time or UTC// into a Time class. Returns false on a failure when, for example, a day of// month is set to 31 on a 28-30 day month. Returns Time(0) on overflow.// FromLocalExploded respects the current time zone but does not attempt to// use the calendar or day-of-week encoding from the current locale - see the// comments on base::Time::Exploded for more information.[[nodiscard]]staticboolFromUTCExploded(constExploded&exploded,Time*time){returnFromExploded(false,exploded,time);}[[nodiscard]]staticboolFromLocalExploded(constExploded&exploded,Time*time){returnFromExploded(true,exploded,time);}// Converts a string representation of time to a Time object.// An example of a time string which is converted is as below:-// "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified// in the input string, FromString assumes local time and FromUTCString// assumes UTC. A timezone that cannot be parsed (e.g. "UTC" which is not// specified in RFC822) is treated as if the timezone is not specified.//// WARNING: the underlying converter is very permissive. For example: it is// not checked whether a given day of the week matches the date; Feb 29// silently becomes Mar 1 in non-leap years; under certain conditions, whole// English sentences may be parsed successfully and yield unexpected results.//// TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to// a new time converter class.[[nodiscard]]staticboolFromString(constchar*time_string,Time*parsed_time){returnFromStringInternal(time_string,true,parsed_time);}[[nodiscard]]staticboolFromUTCString(constchar*time_string,Time*parsed_time){returnFromStringInternal(time_string,false,parsed_time);}// Fills the given |exploded| structure with either the local time or UTC from// this Time instance. If the conversion cannot be made, the output will be// assigned invalid values. Use Exploded::HasValidValues() to confirm a// successful conversion.//// Y10K compliance: This method will successfully convert all Times that// represent dates on/after the start of the year 1601 and on/before the start// of the year 30828. Some platforms might convert over a wider input range.// LocalExplode respects the current time zone but does not attempt to use the// calendar or day-of-week encoding from the current locale - see the comments// on base::Time::Exploded for more information.voidUTCExplode(Exploded*exploded)const{Explode(false,exploded);}voidLocalExplode(Exploded*exploded)const{Explode(true,exploded);}// The following two functions round down the time to the nearest day in// either UTC or local time. It will represent midnight on that day.TimeUTCMidnight()const{returnMidnight(false);}TimeLocalMidnight()const{returnMidnight(true);}// For legacy deserialization only. Converts an integer value representing// Time to a class. This may be used when deserializing a |Time| 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. When deserializing from `base::Value`,// prefer the helpers from //base/json/values_util.h instead.// Otherwise, use `Time::FromDeltaSinceWindowsEpoch()` for `Time` and// `TimeDelta::FromMicroseconds()` for `TimeDelta`. http://crbug.com/634507staticconstexprTimeFromInternalValue(int64_tus){returnTime(us);}private:friendclasstime_internal::TimeBase<Time>;constexprexplicitTime(int64_tmicroseconds_since_win_epoch):TimeBase(microseconds_since_win_epoch){}// Explodes the given time to either local time |is_local = true| or UTC// |is_local = false|.voidExplode(boolis_local,Exploded*exploded)const;// Unexplodes a given time assuming the source is either local time// |is_local = true| or UTC |is_local = false|. Function returns false on// failure and sets |time| to Time(0). Otherwise returns true and sets |time|// to non-exploded time.[[nodiscard]]staticboolFromExploded(boolis_local,constExploded&exploded,Time*time);// Some platforms use the ICU library to provide To/FromExploded, when their// native library implementations are insufficient in some way.staticvoidExplodeUsingIcu(int64_tmillis_since_unix_epoch,boolis_local,Exploded*exploded);[[nodiscard]]staticboolFromExplodedUsingIcu(boolis_local,constExploded&exploded,int64_t*millis_since_unix_epoch);// Rounds down the time to the nearest day in either local time// |is_local = true| or UTC |is_local = false|.TimeMidnight(boolis_local)const;// Converts a string representation of time to a Time object.// An example of a time string which is converted is as below:-// "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified// in the input string, local time |is_local = true| or// UTC |is_local = false| is assumed. A timezone that cannot be parsed// (e.g. "UTC" which is not specified in RFC822) is treated as if the// timezone is not specified.[[nodiscard]]staticboolFromStringInternal(constchar*time_string,boolis_local,Time*parsed_time);// Comparison does not consider |day_of_week| when doing the operation.[[nodiscard]]staticboolExplodedMostlyEquals(constExploded&lhs,constExploded&rhs);// Converts the provided time in milliseconds since the Unix epoch (1970) to a// Time object, avoiding overflows.[[nodiscard]]staticboolFromMillisecondsSinceUnixEpoch(int64_tunix_milliseconds,Time*time);// Returns the milliseconds since the Unix epoch (1970), rounding the// microseconds towards -infinity.int64_tToRoundedDownMillisecondsSinceUnixEpoch()const;};// Factory methods that return a TimeDelta of the given unit.// WARNING: Floating point arithmetic is such that XXX(t.InXXXF()) may not// precisely equal |t|. Hence, floating point values should not be used for// storage.template<typenameT>constexprTimeDeltaDays(Tn){returnTimeDelta::FromInternalValue(MakeClampedNum(n)*Time::kMicrosecondsPerDay);}template<typenameT>constexprTimeDeltaHours(Tn){returnTimeDelta::FromInternalValue(MakeClampedNum(n)*Time::kMicrosecondsPerHour);}template<typenameT>constexprTimeDeltaMinutes(Tn){returnTimeDelta::FromInternalValue(MakeClampedNum(n)*Time::kMicrosecondsPerMinute);}template<typenameT>constexprTimeDeltaSeconds(Tn){returnTimeDelta::FromInternalValue(MakeClampedNum(n)*Time::kMicrosecondsPerSecond);}template<typenameT>constexprTimeDeltaMilliseconds(Tn){returnTimeDelta::FromInternalValue(MakeClampedNum(n)*Time::kMicrosecondsPerMillisecond);}template<typenameT>constexprTimeDeltaMicroseconds(Tn){returnTimeDelta::FromInternalValue(MakeClampedNum(n));}template<typenameT>constexprTimeDeltaNanoseconds(Tn){returnTimeDelta::FromInternalValue(MakeClampedNum(n)/Time::kNanosecondsPerMicrosecond);}template<typenameT>constexprTimeDeltaHertz(Tn){returnn?TimeDelta::FromInternalValue(Time::kMicrosecondsPerSecond/MakeClampedNum(n)):TimeDelta::Max();}// TimeDelta functions that must appear below the declarations of Time/TimeDeltaconstexprdoubleTimeDelta::ToHz()const{returnSeconds(1)/*this;}constexprintTimeDelta::InDays()const{if(!is_inf()){returnstatic_cast<int>(delta_/Time::kMicrosecondsPerDay);}return(delta_<0)?std::numeric_limits<int>::min():std::numeric_limits<int>::max();}constexprintTimeDelta::InDaysFloored()const{if(!is_inf()){constintresult=delta_/Time::kMicrosecondsPerDay;// Convert |result| from truncating to flooring.return(result*Time::kMicrosecondsPerDay>delta_)?(result-1):result;}return(delta_<0)?std::numeric_limits<int>::min():std::numeric_limits<int>::max();}constexprintTimeDelta::InHours()const{// saturated_cast<> is necessary since very large (but still less than// min/max) deltas would result in overflow.returnsaturated_cast<int>(delta_/Time::kMicrosecondsPerHour);}constexprintTimeDelta::InMinutes()const{// saturated_cast<> is necessary since very large (but still less than// min/max) deltas would result in overflow.returnsaturated_cast<int>(delta_/Time::kMicrosecondsPerMinute);}constexprdoubleTimeDelta::InSecondsF()const{if(!is_inf())returnstatic_cast<double>(delta_)/Time::kMicrosecondsPerSecond;return(delta_<0)?-std::numeric_limits<double>::infinity():std::numeric_limits<double>::infinity();}constexprint64_tTimeDelta::InSeconds()const{returnis_inf()?delta_:(delta_/Time::kMicrosecondsPerSecond);}constexprint64_tTimeDelta::InSecondsFloored()const{if(!is_inf()){constint64_tresult=delta_/Time::kMicrosecondsPerSecond;// Convert |result| from truncating to flooring.return(result*Time::kMicrosecondsPerSecond>delta_)?(result-1):result;}returndelta_;}constexprdoubleTimeDelta::InMillisecondsF()const{if(!is_inf()){returnstatic_cast<double>(delta_)/Time::kMicrosecondsPerMillisecond;}return(delta_<0)?-std::numeric_limits<double>::infinity():std::numeric_limits<double>::infinity();}constexprint64_tTimeDelta::InMilliseconds()const{if(!is_inf()){returndelta_/Time::kMicrosecondsPerMillisecond;}return(delta_<0)?std::numeric_limits<int64_t>::min():std::numeric_limits<int64_t>::max();}constexprint64_tTimeDelta::InMillisecondsRoundedUp()const{if(!is_inf()){constint64_tresult=delta_/Time::kMicrosecondsPerMillisecond;// Convert |result| from truncating to ceiling.return(delta_>result*Time::kMicrosecondsPerMillisecond)?(result+1):result;}returndelta_;}constexprdoubleTimeDelta::InMicrosecondsF()const{if(!is_inf()){returnstatic_cast<double>(delta_);}return(delta_<0)?-std::numeric_limits<double>::infinity():std::numeric_limits<double>::infinity();}constexprint64_tTimeDelta::InNanoseconds()const{returnbase::ClampMul(delta_,Time::kNanosecondsPerMicrosecond);}// staticconstexprTimeDeltaTimeDelta::Max(){returnTimeDelta(std::numeric_limits<int64_t>::max());}// staticconstexprTimeDeltaTimeDelta::Min(){returnTimeDelta(std::numeric_limits<int64_t>::min());}// staticconstexprTimeDeltaTimeDelta::FiniteMax(){returnTimeDelta(std::numeric_limits<int64_t>::max()-1);}// staticconstexprTimeDeltaTimeDelta::FiniteMin(){returnTimeDelta(std::numeric_limits<int64_t>::min()+1);}// TimeBase functions that must appear below the declarations of Time/TimeDeltanamespacetime_internal{template<classTimeClass>constexprTimeDeltaTimeBase<TimeClass>::since_origin()const{returnMicroseconds(us_);}template<classTimeClass>constexprTimeDeltaTimeBase<TimeClass>::operator-(constTimeBase<TimeClass>&other)const{returnMicroseconds(us_-other.us_);}template<classTimeClass>constexprTimeClassTimeBase<TimeClass>::operator+(TimeDeltadelta)const{returnTimeClass((Microseconds(us_)+delta).InMicroseconds());}template<classTimeClass>constexprTimeClassTimeBase<TimeClass>::operator-(TimeDeltadelta)const{returnTimeClass((Microseconds(us_)-delta).InMicroseconds());}}// namespace time_internal// Time functions that must appear below the declarations of Time/TimeDelta// staticconstexprTimeTime::FromTimeT(time_ttt){if(tt==0)returnTime();// Preserve 0 so we can tell it doesn't exist.return(tt==std::numeric_limits<time_t>::max())?Max():(UnixEpoch()+Seconds(tt));}constexprtime_tTime::ToTimeT()const{if(is_null()){return0;// Preserve 0 so we can tell it doesn't exist.}if(!is_inf()){returnsaturated_cast<time_t>((*this-UnixEpoch()).InSecondsFloored());}return(us_<0)?std::numeric_limits<time_t>::min():std::numeric_limits<time_t>::max();}// staticconstexprTimeTime::FromDoubleT(doubledt){// Preserve 0 so we can tell it doesn't exist.return(dt==0||std::isnan(dt))?Time():(UnixEpoch()+Seconds(dt));}constexprdoubleTime::ToDoubleT()const{if(is_null()){return0;// Preserve 0 so we can tell it doesn't exist.}if(!is_inf()){return(*this-UnixEpoch()).InSecondsF();}return(us_<0)?-std::numeric_limits<double>::infinity():std::numeric_limits<double>::infinity();}#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)// staticconstexprTimeTime::FromTimeSpec(consttimespec&ts){returnFromDoubleT(ts.tv_sec+static_cast<double>(ts.tv_nsec)/kNanosecondsPerSecond);}#endif// staticconstexprTimeTime::FromJsTime(doublems_since_epoch){// The epoch is a valid time, so this constructor doesn't interpret 0 as the// null time.returnUnixEpoch()+Milliseconds(ms_since_epoch);}constexprdoubleTime::ToJsTime()const{// Preserve 0 so the invalid result doesn't depend on the platform.returnis_null()?0:ToJsTimeIgnoringNull();}constexprdoubleTime::ToJsTimeIgnoringNull()const{// Preserve max and min without offset to prevent over/underflow.if(!is_inf()){return(*this-UnixEpoch()).InMillisecondsF();}return(us_<0)?-std::numeric_limits<double>::infinity():std::numeric_limits<double>::infinity();}constexprTimeTime::FromJavaTime(int64_tms_since_epoch){returnUnixEpoch()+Milliseconds(ms_since_epoch);}constexprint64_tTime::ToJavaTime()const{// Preserve 0 so the invalid result doesn't depend on the platform.if(is_null()){return0;}if(!is_inf()){return(*this-UnixEpoch()).InMilliseconds();}return(us_<0)?std::numeric_limits<int64_t>::min():std::numeric_limits<int64_t>::max();}// For logging use only.BASE_EXPORTstd::ostream&operator<<(std::ostream&os,Timetime);// TimeTicks ------------------------------------------------------------------// Represents monotonically non-decreasing clock time.classBASE_EXPORTTimeTicks:publictime_internal::TimeBase<TimeTicks>{public:// The underlying clock used to generate new TimeTicks.enumclassClock{FUCHSIA_ZX_CLOCK_MONOTONIC,LINUX_CLOCK_MONOTONIC,IOS_CF_ABSOLUTE_TIME_MINUS_KERN_BOOTTIME,MAC_MACH_ABSOLUTE_TIME,WIN_QPC,WIN_ROLLOVER_PROTECTED_TIME_GET_TIME};constexprTimeTicks():TimeBase(0){}// Platform-dependent tick count representing "right now." When// IsHighResolution() returns false, the resolution of the clock could be// as coarse as ~15.6ms. Otherwise, the resolution should be no worse than one// microsecond.staticTimeTicksNow();// Returns true if the high resolution clock is working on this system and// Now() will return high resolution values. Note that, on systems where the// high resolution clock works but is deemed inefficient, the low resolution// clock will be used instead.[[nodiscard]]staticboolIsHighResolution();// Returns true if TimeTicks is consistent across processes, meaning that// timestamps taken on different processes can be safely compared with one// another. (Note that, even on platforms where this returns true, time values// from different threads that are within one tick of each other must be// considered to have an ambiguous ordering.)[[nodiscard]]staticboolIsConsistentAcrossProcesses();#if BUILDFLAG(IS_FUCHSIA)// Converts between TimeTicks and an ZX_CLOCK_MONOTONIC zx_time_t value.staticTimeTicksFromZxTime(zx_time_tnanos_since_boot);zx_time_tToZxTime()const;#endif#if BUILDFLAG(IS_WIN)// Translates an absolute QPC timestamp into a TimeTicks value. The returned// value has the same origin as Now(). Do NOT attempt to use this if// IsHighResolution() returns false.staticTimeTicksFromQPCValue(LONGLONGqpc_value);#endif#if BUILDFLAG(IS_APPLE)#if BUILDFLAG(ENABLE_MACH_ABSOLUTE_TIME_TICKS)staticTimeTicksFromMachAbsoluteTime(uint64_tmach_absolute_time);// Sets the current Mach timebase to `timebase`. Returns the old timebase.staticmach_timebase_info_data_tSetMachTimebaseInfoForTesting(mach_timebase_info_data_ttimebase);#endif // BUILDFLAG(ENABLE_MACH_ABSOLUTE_TIME_TICKS)#endif // BUILDFLAG(IS_APPLE)#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)// Converts to TimeTicks the value obtained from SystemClock.uptimeMillis().// Note: this conversion may be non-monotonic in relation to previously// obtained TimeTicks::Now() values because of the truncation (to// milliseconds) performed by uptimeMillis().staticTimeTicksFromUptimeMillis(int64_tuptime_millis_value);#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)#if BUILDFLAG(IS_ANDROID)// Converts to TimeTicks the value obtained from System.nanoTime(). This// conversion will be monotonic in relation to previously obtained// TimeTicks::Now() values as the clocks are based on the same posix monotonic// clock, with nanoTime() potentially providing higher resolution.staticTimeTicksFromJavaNanoTime(int64_tnano_time_value);// Truncates the TimeTicks value to the precision of SystemClock#uptimeMillis.// Note that the clocks already share the same monotonic clock source.jlongToUptimeMillis()const;// Returns the TimeTicks value as microseconds in the timebase of// SystemClock#uptimeMillis.// Note that the clocks already share the same monotonic clock source.//// System.nanoTime() may be used to get sub-millisecond precision in Java code// and may be compared against this value as the two share the same clock// source (though be sure to convert nanos to micros).jlongToUptimeMicros()const;#endif // BUILDFLAG(IS_ANDROID)// Get an estimate of the TimeTick value at the time of the UnixEpoch. Because// Time and TimeTicks respond differently to user-set time and NTP// adjustments, this number is only an estimate. Nevertheless, this can be// useful when you need to relate the value of TimeTicks to a real time and// date. Note: Upon first invocation, this function takes a snapshot of the// realtime clock to establish a reference point. This function will return// the same value for the duration of the application, but will be different// in future application runs.staticTimeTicksUnixEpoch();staticvoidSetSharedUnixEpoch(TimeTicks);// Returns |this| snapped to the next tick, given a |tick_phase| and// repeating |tick_interval| in both directions. |this| may be before,// after, or equal to the |tick_phase|.TimeTicksSnappedToNextTick(TimeTickstick_phase,TimeDeltatick_interval)const;// Returns an enum indicating the underlying clock being used to generate// TimeTicks timestamps. This function should only be used for debugging and// logging purposes.staticClockGetClock();// Converts an integer value representing TimeTicks to a class. This may be// used when deserializing a |TimeTicks| 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. For deserializing TimeTicks values,// prefer TimeTicks + TimeDelta(); however, be aware that the origin is not// fixed and may vary. Serializing for persistence is strongly discouraged.// http://crbug.com/634507staticconstexprTimeTicksFromInternalValue(int64_tus){returnTimeTicks(us);}protected:#if BUILDFLAG(IS_WIN)typedefDWORD(*TickFunctionType)(void);staticTickFunctionTypeSetMockTickFunction(TickFunctionTypeticker);#endifprivate:friendclasstime_internal::TimeBase<TimeTicks>;// Please use Now() to create a new object. This is for internal use// and testing.constexprexplicitTimeTicks(int64_tus):TimeBase(us){}};// For logging use only.BASE_EXPORTstd::ostream&operator<<(std::ostream&os,TimeTickstime_ticks);// LiveTicks ------------------------------------------------------------------// Behaves similarly to `TimeTicks` (a monotonically non-decreasing clock time)// with the main difference being that `LiveTicks` is guaranteed not to advance// while the system is suspended.classBASE_EXPORTLiveTicks:publictime_internal::TimeBase<LiveTicks>{public:constexprLiveTicks():TimeBase(0){}staticLiveTicksNow();private:friendclasstime_internal::TimeBase<LiveTicks>;// Please use Now() to create a new object. This is for internal use// and testing.constexprexplicitLiveTicks(int64_tus):TimeBase(us){}};// ThreadTicks ----------------------------------------------------------------// Represents a clock, specific to a particular thread, than runs only while the// thread is running.classBASE_EXPORTThreadTicks:publictime_internal::TimeBase<ThreadTicks>{public:constexprThreadTicks():TimeBase(0){}// Returns true if ThreadTicks::Now() is supported on this system.[[nodiscard]]staticboolIsSupported(){#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \ BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)returntrue;#elif BUILDFLAG(IS_WIN)returnIsSupportedWin();#elsereturnfalse;#endif}// Waits until the initialization is completed. Needs to be guarded with a// call to IsSupported().staticvoidWaitUntilInitialized(){#if BUILDFLAG(IS_WIN)WaitUntilInitializedWin();#endif}// Returns thread-specific CPU-time on systems that support this feature.// Needs to be guarded with a call to IsSupported(). Use this timer// to (approximately) measure how much time the calling thread spent doing// actual work vs. being de-scheduled. May return bogus results if the thread// migrates to another CPU between two calls. Returns an empty ThreadTicks// object until the initialization is completed. If a clock reading is// absolutely needed, call WaitUntilInitialized() before this method.staticThreadTicksNow();#if BUILDFLAG(IS_WIN)// Similar to Now() above except this returns thread-specific CPU time for an// arbitrary thread. All comments for Now() method above apply apply to this// method as well.staticThreadTicksGetForThread(constPlatformThreadHandle&thread_handle);#endif// Converts an integer value representing ThreadTicks to a class. This may be// used when deserializing a |ThreadTicks| 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. For deserializing ThreadTicks values,// prefer ThreadTicks + TimeDelta(); however, be aware that the origin is not// fixed and may vary. Serializing for persistence is strongly// discouraged. http://crbug.com/634507staticconstexprThreadTicksFromInternalValue(int64_tus){returnThreadTicks(us);}private:friendclasstime_internal::TimeBase<ThreadTicks>;// Please use Now() or GetForThread() to create a new object. This is for// internal use and testing.constexprexplicitThreadTicks(int64_tus):TimeBase(us){}#if BUILDFLAG(IS_WIN)[[nodiscard]]staticboolIsSupportedWin();staticvoidWaitUntilInitializedWin();#endif};// For logging use only.BASE_EXPORTstd::ostream&operator<<(std::ostream&os,ThreadTickstime_ticks);// Returns a string representation of the given time in the IMF-fixdate format// defined by RFC 7231 (satisfying its HTTP-date format).BASE_EXPORTstd::stringTimeFormatHTTP(base::Timetime);}// namespace base#endif // BASE_TIME_TIME_H_