Source File
time.go
Belonging Package
time
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package time provides functionality for measuring and displaying time.
//
// The calendrical calculations always assume a Gregorian calendar, with
// no leap seconds.
//
// # Monotonic Clocks
//
// Operating systems provide both a “wall clock,” which is subject to
// changes for clock synchronization, and a “monotonic clock,” which is
// not. The general rule is that the wall clock is for telling time and
// the monotonic clock is for measuring time. Rather than split the API,
// in this package the Time returned by [time.Now] contains both a wall
// clock reading and a monotonic clock reading; later time-telling
// operations use the wall clock reading, but later time-measuring
// operations, specifically comparisons and subtractions, use the
// monotonic clock reading.
//
// For example, this code always computes a positive elapsed time of
// approximately 20 milliseconds, even if the wall clock is changed during
// the operation being timed:
//
// start := time.Now()
// ... operation that takes 20 milliseconds ...
// t := time.Now()
// elapsed := t.Sub(start)
//
// Other idioms, such as [time.Since](start), [time.Until](deadline), and
// time.Now().Before(deadline), are similarly robust against wall clock
// resets.
//
// The rest of this section gives the precise details of how operations
// use monotonic clocks, but understanding those details is not required
// to use this package.
//
// The Time returned by time.Now contains a monotonic clock reading.
// If Time t has a monotonic clock reading, t.Add adds the same duration to
// both the wall clock and monotonic clock readings to compute the result.
// Because t.AddDate(y, m, d), t.Round(d), and t.Truncate(d) are wall time
// computations, they always strip any monotonic clock reading from their results.
// Because t.In, t.Local, and t.UTC are used for their effect on the interpretation
// of the wall time, they also strip any monotonic clock reading from their results.
// The canonical way to strip a monotonic clock reading is to use t = t.Round(0).
//
// If Times t and u both contain monotonic clock readings, the operations
// t.After(u), t.Before(u), t.Equal(u), t.Compare(u), and t.Sub(u) are carried out
// using the monotonic clock readings alone, ignoring the wall clock
// readings. If either t or u contains no monotonic clock reading, these
// operations fall back to using the wall clock readings.
//
// On some systems the monotonic clock will stop if the computer goes to sleep.
// On such a system, t.Sub(u) may not accurately reflect the actual
// time that passed between t and u. The same applies to other functions and
// methods that subtract times, such as [Since], [Until], [Before], [After],
// [Add], [Sub], [Equal] and [Compare]. In some cases, you may need to strip
// the monotonic clock to get accurate results.
//
// Because the monotonic clock reading has no meaning outside
// the current process, the serialized forms generated by t.GobEncode,
// t.MarshalBinary, t.MarshalJSON, and t.MarshalText omit the monotonic
// clock reading, and t.Format provides no format for it. Similarly, the
// constructors [time.Date], [time.Parse], [time.ParseInLocation], and [time.Unix],
// as well as the unmarshalers t.GobDecode, t.UnmarshalBinary.
// t.UnmarshalJSON, and t.UnmarshalText always create times with
// no monotonic clock reading.
//
// The monotonic clock reading exists only in [Time] values. It is not
// a part of [Duration] values or the Unix times returned by t.Unix and
// friends.
//
// Note that the Go == operator compares not just the time instant but
// also the [Location] and the monotonic clock reading. See the
// documentation for the Time type for a discussion of equality
// testing for Time values.
//
// For debugging, the result of t.String does include the monotonic
// clock reading if present. If t != u because of different monotonic clock readings,
// that difference will be visible when printing t.String() and u.String().
//
// # Timer Resolution
//
// [Timer] resolution varies depending on the Go runtime, the operating system
// and the underlying hardware.
// On Unix, the resolution is ~1ms.
// On Windows version 1803 and newer, the resolution is ~0.5ms.
// On older Windows versions, the default resolution is ~16ms, but
// a higher resolution may be requested using [golang.org/x/sys/windows.TimeBeginPeriod].
package time
import (
_ // for go:linkname
)
// A Time represents an instant in time with nanosecond precision.
//
// Programs using times should typically store and pass them as values,
// not pointers. That is, time variables and struct fields should be of
// type [time.Time], not *time.Time.
//
// A Time value can be used by multiple goroutines simultaneously except
// that the methods [Time.GobDecode], [Time.UnmarshalBinary], [Time.UnmarshalJSON] and
// [Time.UnmarshalText] are not concurrency-safe.
//
// Time instants can be compared using the [Time.Before], [Time.After], and [Time.Equal] methods.
// The [Time.Sub] method subtracts two instants, producing a [Duration].
// The [Time.Add] method adds a Time and a Duration, producing a Time.
//
// The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC.
// As this time is unlikely to come up in practice, the [Time.IsZero] method gives
// a simple way of detecting a time that has not been initialized explicitly.
//
// Each time has an associated [Location]. The methods [Time.Local], [Time.UTC], and Time.In return a
// Time with a specific Location. Changing the Location of a Time value with
// these methods does not change the actual instant it represents, only the time
// zone in which to interpret it.
//
// Representations of a Time value saved by the [Time.GobEncode], [Time.MarshalBinary],
// [Time.MarshalJSON], and [Time.MarshalText] methods store the [Time.Location]'s offset, but not
// the location name. They therefore lose information about Daylight Saving Time.
//
// In addition to the required “wall clock” reading, a Time may contain an optional
// reading of the current process's monotonic clock, to provide additional precision
// for comparison or subtraction.
// See the “Monotonic Clocks” section in the package documentation for details.
//
// Note that the Go == operator compares not just the time instant but also the
// Location and the monotonic clock reading. Therefore, Time values should not
// be used as map or database keys without first guaranteeing that the
// identical Location has been set for all values, which can be achieved
// through use of the UTC or Local method, and that the monotonic clock reading
// has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u)
// to t == u, since t.Equal uses the most accurate comparison available and
// correctly handles the case when only one of its arguments has a monotonic
// clock reading.
type Time struct {
// wall and ext encode the wall time seconds, wall time nanoseconds,
// and optional monotonic clock reading in nanoseconds.
//
// From high to low bit position, wall encodes a 1-bit flag (hasMonotonic),
// a 33-bit seconds field, and a 30-bit wall time nanoseconds field.
// The nanoseconds field is in the range [0, 999999999].
// If the hasMonotonic bit is 0, then the 33-bit field must be zero
// and the full signed 64-bit wall seconds since Jan 1 year 1 is stored in ext.
// If the hasMonotonic bit is 1, then the 33-bit field holds a 33-bit
// unsigned wall seconds since Jan 1 year 1885, and ext holds a
// signed 64-bit monotonic clock reading, nanoseconds since process start.
wall uint64
ext int64
// loc specifies the Location that should be used to
// determine the minute, hour, month, day, and year
// that correspond to this Time.
// The nil location means UTC.
// All UTC times are represented with loc==nil, never loc==&utcLoc.
loc *Location
}
const (
hasMonotonic = 1 << 63
maxWall = wallToInternal + (1<<33 - 1) // year 2157
minWall = wallToInternal // year 1885
nsecMask = 1<<30 - 1
nsecShift = 30
)
// These helpers for manipulating the wall and monotonic clock readings
// take pointer receivers, even when they don't modify the time,
// to make them cheaper to call.
// nsec returns the time's nanoseconds.
func ( *Time) () int32 {
return int32(.wall & nsecMask)
}
// sec returns the time's seconds since Jan 1 year 1.
func ( *Time) () int64 {
if .wall&hasMonotonic != 0 {
return wallToInternal + int64(.wall<<1>>(nsecShift+1))
}
return .ext
}
// unixSec returns the time's seconds since Jan 1 1970 (Unix time).
func ( *Time) () int64 { return .sec() + internalToUnix }
// addSec adds d seconds to the time.
func ( *Time) ( int64) {
if .wall&hasMonotonic != 0 {
:= int64(.wall << 1 >> (nsecShift + 1))
:= +
if 0 <= && <= 1<<33-1 {
.wall = .wall&nsecMask | uint64()<<nsecShift | hasMonotonic
return
}
// Wall second now out of range for packed field.
// Move to ext.
.stripMono()
}
// Check if the sum of t.ext and d overflows and handle it properly.
:= .ext +
if ( > .ext) == ( > 0) {
.ext =
} else if > 0 {
.ext = 1<<63 - 1
} else {
.ext = -(1<<63 - 1)
}
}
// setLoc sets the location associated with the time.
func ( *Time) ( *Location) {
if == &utcLoc {
= nil
}
.stripMono()
.loc =
}
// stripMono strips the monotonic clock reading in t.
func ( *Time) () {
if .wall&hasMonotonic != 0 {
.ext = .sec()
.wall &= nsecMask
}
}
// setMono sets the monotonic clock reading in t.
// If t cannot hold a monotonic clock reading,
// because its wall time is too large,
// setMono is a no-op.
func ( *Time) ( int64) {
if .wall&hasMonotonic == 0 {
:= .ext
if < minWall || maxWall < {
return
}
.wall |= hasMonotonic | uint64(-minWall)<<nsecShift
}
.ext =
}
// mono returns t's monotonic clock reading.
// It returns 0 for a missing reading.
// This function is used only for testing,
// so it's OK that technically 0 is a valid
// monotonic clock reading as well.
func ( *Time) () int64 {
if .wall&hasMonotonic == 0 {
return 0
}
return .ext
}
// After reports whether the time instant t is after u.
func ( Time) ( Time) bool {
if .wall&.wall&hasMonotonic != 0 {
return .ext > .ext
}
:= .sec()
:= .sec()
return > || == && .nsec() > .nsec()
}
// Before reports whether the time instant t is before u.
func ( Time) ( Time) bool {
if .wall&.wall&hasMonotonic != 0 {
return .ext < .ext
}
:= .sec()
:= .sec()
return < || == && .nsec() < .nsec()
}
// Compare compares the time instant t with u. If t is before u, it returns -1;
// if t is after u, it returns +1; if they're the same, it returns 0.
func ( Time) ( Time) int {
var , int64
if .wall&.wall&hasMonotonic != 0 {
, = .ext, .ext
} else {
, = .sec(), .sec()
if == {
, = int64(.nsec()), int64(.nsec())
}
}
switch {
case < :
return -1
case > :
return +1
}
return 0
}
// Equal reports whether t and u represent the same time instant.
// Two times can be equal even if they are in different locations.
// For example, 6:00 +0200 and 4:00 UTC are Equal.
// See the documentation on the Time type for the pitfalls of using == with
// Time values; most code should use Equal instead.
func ( Time) ( Time) bool {
if .wall&.wall&hasMonotonic != 0 {
return .ext == .ext
}
return .sec() == .sec() && .nsec() == .nsec()
}
// A Month specifies a month of the year (January = 1, ...).
type Month int
const (
January Month = 1 + iota
February
March
April
May
June
July
August
September
October
November
December
)
// String returns the English name of the month ("January", "February", ...).
func ( Month) () string {
if January <= && <= December {
return longMonthNames[-1]
}
:= make([]byte, 20)
:= fmtInt(, uint64())
return "%!Month(" + string([:]) + ")"
}
// A Weekday specifies a day of the week (Sunday = 0, ...).
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
// String returns the English name of the day ("Sunday", "Monday", ...).
func ( Weekday) () string {
if Sunday <= && <= Saturday {
return longDayNames[]
}
:= make([]byte, 20)
:= fmtInt(, uint64())
return "%!Weekday(" + string([:]) + ")"
}
// Computations on time.
//
// The zero value for a Time is defined to be
// January 1, year 1, 00:00:00.000000000 UTC
// which (1) looks like a zero, or as close as you can get in a date
// (1-1-1 00:00:00 UTC), (2) is unlikely enough to arise in practice to
// be a suitable "not set" sentinel, unlike Jan 1 1970, and (3) has a
// non-negative year even in time zones west of UTC, unlike 1-1-0
// 00:00:00 UTC, which would be 12-31-(-1) 19:00:00 in New York.
//
// The zero Time value does not force a specific epoch for the time
// representation. For example, to use the Unix epoch internally, we
// could define that to distinguish a zero value from Jan 1 1970, that
// time would be represented by sec=-1, nsec=1e9. However, it does
// suggest a representation, namely using 1-1-1 00:00:00 UTC as the
// epoch, and that's what we do.
//
// The Add and Sub computations are oblivious to the choice of epoch.
//
// The presentation computations - year, month, minute, and so on - all
// rely heavily on division and modulus by positive constants. For
// calendrical calculations we want these divisions to round down, even
// for negative values, so that the remainder is always positive, but
// Go's division (like most hardware division instructions) rounds to
// zero. We can still do those computations and then adjust the result
// for a negative numerator, but it's annoying to write the adjustment
// over and over. Instead, we can change to a different epoch so long
// ago that all the times we care about will be positive, and then round
// to zero and round down coincide. These presentation routines already
// have to add the zone offset, so adding the translation to the
// alternate epoch is cheap. For example, having a non-negative time t
// means that we can write
//
// sec = t % 60
//
// instead of
//
// sec = t % 60
// if sec < 0 {
// sec += 60
// }
//
// everywhere.
//
// The calendar runs on an exact 400 year cycle: a 400-year calendar
// printed for 1970-2369 will apply as well to 2370-2769. Even the days
// of the week match up. It simplifies the computations to choose the
// cycle boundaries so that the exceptional years are always delayed as
// long as possible. That means choosing a year equal to 1 mod 400, so
// that the first leap year is the 4th year, the first missed leap year
// is the 100th year, and the missed missed leap year is the 400th year.
// So we'd prefer instead to print a calendar for 2001-2400 and reuse it
// for 2401-2800.
//
// Finally, it's convenient if the delta between the Unix epoch and
// long-ago epoch is representable by an int64 constant.
//
// These three considerations—choose an epoch as early as possible, that
// uses a year equal to 1 mod 400, and that is no more than 2⁶³ seconds
// earlier than 1970—bring us to the year -292277022399. We refer to
// this year as the absolute zero year, and to times measured as a uint64
// seconds since this year as absolute times.
//
// Times measured as an int64 seconds since the year 1—the representation
// used for Time's sec field—are called internal times.
//
// Times measured as an int64 seconds since the year 1970 are called Unix
// times.
//
// It is tempting to just use the year 1 as the absolute epoch, defining
// that the routines are only valid for years >= 1. However, the
// routines would then be invalid when displaying the epoch in time zones
// west of UTC, since it is year 0. It doesn't seem tenable to say that
// printing the zero time correctly isn't supported in half the time
// zones. By comparison, it's reasonable to mishandle some times in
// the year -292277022399.
//
// All this is opaque to clients of the API and can be changed if a
// better implementation presents itself.
const (
// The unsigned zero year for internal calculations.
// Must be 1 mod 400, and times before it will not compute correctly,
// but otherwise can be changed at will.
absoluteZeroYear = -292277022399
// The year of the zero Time.
// Assumed by the unixToInternal computation below.
internalYear = 1
// Offsets to convert between internal and absolute or Unix times.
absoluteToInternal int64 = (absoluteZeroYear - internalYear) * 365.2425 * secondsPerDay
internalToAbsolute = -absoluteToInternal
unixToInternal int64 = (1969*365 + 1969/4 - 1969/100 + 1969/400) * secondsPerDay
internalToUnix int64 = -unixToInternal
wallToInternal int64 = (1884*365 + 1884/4 - 1884/100 + 1884/400) * secondsPerDay
)
// IsZero reports whether t represents the zero time instant,
// January 1, year 1, 00:00:00 UTC.
func ( Time) () bool {
return .sec() == 0 && .nsec() == 0
}
// abs returns the time t as an absolute time, adjusted by the zone offset.
// It is called when computing a presentation property like Month or Hour.
func ( Time) () uint64 {
:= .loc
// Avoid function calls when possible.
if == nil || == &localLoc {
= .get()
}
:= .unixSec()
if != &utcLoc {
if .cacheZone != nil && .cacheStart <= && < .cacheEnd {
+= int64(.cacheZone.offset)
} else {
, , , , := .lookup()
+= int64()
}
}
return uint64( + (unixToInternal + internalToAbsolute))
}
// locabs is a combination of the Zone and abs methods,
// extracting both return values from a single zone lookup.
func ( Time) () ( string, int, uint64) {
:= .loc
if == nil || == &localLoc {
= .get()
}
// Avoid function call if we hit the local time cache.
:= .unixSec()
if != &utcLoc {
if .cacheZone != nil && .cacheStart <= && < .cacheEnd {
= .cacheZone.name
= .cacheZone.offset
} else {
, , _, _, _ = .lookup()
}
+= int64()
} else {
= "UTC"
}
= uint64( + (unixToInternal + internalToAbsolute))
return
}
// Date returns the year, month, and day in which t occurs.
func ( Time) () ( int, Month, int) {
, , , _ = .date(true)
return
}
// Year returns the year in which t occurs.
func ( Time) () int {
, , , := .date(false)
return
}
// Month returns the month of the year specified by t.
func ( Time) () Month {
, , , := .date(true)
return
}
// Day returns the day of the month specified by t.
func ( Time) () int {
, , , := .date(true)
return
}
// Weekday returns the day of the week specified by t.
func ( Time) () Weekday {
return absWeekday(.abs())
}
// absWeekday is like Weekday but operates on an absolute time.
func absWeekday( uint64) Weekday {
// January 1 of the absolute year, like January 1 of 2001, was a Monday.
:= ( + uint64(Monday)*secondsPerDay) % secondsPerWeek
return Weekday(int() / secondsPerDay)
}
// ISOWeek returns the ISO 8601 year and week number in which t occurs.
// Week ranges from 1 to 53. Jan 01 to Jan 03 of year n might belong to
// week 52 or 53 of year n-1, and Dec 29 to Dec 31 might belong to week 1
// of year n+1.
func ( Time) () (, int) {
// According to the rule that the first calendar week of a calendar year is
// the week including the first Thursday of that year, and that the last one is
// the week immediately preceding the first calendar week of the next calendar year.
// See https://www.iso.org/obp/ui#iso:std:iso:8601:-1:ed-1:v1:en:term:3.1.1.23 for details.
// weeks start with Monday
// Monday Tuesday Wednesday Thursday Friday Saturday Sunday
// 1 2 3 4 5 6 7
// +3 +2 +1 0 -1 -2 -3
// the offset to Thursday
:= .abs()
:= Thursday - absWeekday()
// handle Sunday
if == 4 {
= -3
}
// find the Thursday of the calendar week
+= uint64() * secondsPerDay
, , , := absDate(, false)
return , /7 + 1
}
// Clock returns the hour, minute, and second within the day specified by t.
func ( Time) () (, , int) {
return absClock(.abs())
}
// absClock is like clock but operates on an absolute time.
//
// absClock should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/phuslu/log
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname absClock
func absClock( uint64) (, , int) {
= int( % secondsPerDay)
= / secondsPerHour
-= * secondsPerHour
= / secondsPerMinute
-= * secondsPerMinute
return
}
// Hour returns the hour within the day specified by t, in the range [0, 23].
func ( Time) () int {
return int(.abs()%secondsPerDay) / secondsPerHour
}
// Minute returns the minute offset within the hour specified by t, in the range [0, 59].
func ( Time) () int {
return int(.abs()%secondsPerHour) / secondsPerMinute
}
// Second returns the second offset within the minute specified by t, in the range [0, 59].
func ( Time) () int {
return int(.abs() % secondsPerMinute)
}
// Nanosecond returns the nanosecond offset within the second specified by t,
// in the range [0, 999999999].
func ( Time) () int {
return int(.nsec())
}
// YearDay returns the day of the year specified by t, in the range [1,365] for non-leap years,
// and [1,366] in leap years.
func ( Time) () int {
, , , := .date(false)
return + 1
}
// A Duration represents the elapsed time between two instants
// as an int64 nanosecond count. The representation limits the
// largest representable duration to approximately 290 years.
type Duration int64
const (
minDuration Duration = -1 << 63
maxDuration Duration = 1<<63 - 1
)
// Common durations. There is no definition for units of Day or larger
// to avoid confusion across daylight savings time zone transitions.
//
// To count the number of units in a [Duration], divide:
//
// second := time.Second
// fmt.Print(int64(second/time.Millisecond)) // prints 1000
//
// To convert an integer number of units to a Duration, multiply:
//
// seconds := 10
// fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
// String returns a string representing the duration in the form "72h3m0.5s".
// Leading zero units are omitted. As a special case, durations less than one
// second format use a smaller unit (milli-, micro-, or nanoseconds) to ensure
// that the leading digit is non-zero. The zero duration formats as 0s.
func ( Duration) () string {
// This is inlinable to take advantage of "function outlining".
// Thus, the caller can decide whether a string must be heap allocated.
var [32]byte
:= .format(&)
return string([:])
}
// format formats the representation of d into the end of buf and
// returns the offset of the first character.
func ( Duration) ( *[32]byte) int {
// Largest time is 2540400h10m10.000000000s
:= len()
:= uint64()
:= < 0
if {
= -
}
if < uint64(Second) {
// Special case: if duration is smaller than a second,
// use smaller units, like 1.2ms
var int
--
[] = 's'
--
switch {
case == 0:
[] = '0'
return
case < uint64(Microsecond):
// print nanoseconds
= 0
[] = 'n'
case < uint64(Millisecond):
// print microseconds
= 3
// U+00B5 'µ' micro sign == 0xC2 0xB5
-- // Need room for two bytes.
copy([:], "µ")
default:
// print milliseconds
= 6
[] = 'm'
}
, = fmtFrac([:], , )
= fmtInt([:], )
} else {
--
[] = 's'
, = fmtFrac([:], , 9)
// u is now integer seconds
= fmtInt([:], %60)
/= 60
// u is now integer minutes
if > 0 {
--
[] = 'm'
= fmtInt([:], %60)
/= 60
// u is now integer hours
// Stop at hours because days can be different lengths.
if > 0 {
--
[] = 'h'
= fmtInt([:], )
}
}
}
if {
--
[] = '-'
}
return
}
// fmtFrac formats the fraction of v/10**prec (e.g., ".12345") into the
// tail of buf, omitting trailing zeros. It omits the decimal
// point too when the fraction is 0. It returns the index where the
// output bytes begin and the value v/10**prec.
func fmtFrac( []byte, uint64, int) ( int, uint64) {
// Omit trailing zeros up to and including decimal point.
:= len()
:= false
for := 0; < ; ++ {
:= % 10
= || != 0
if {
--
[] = byte() + '0'
}
/= 10
}
if {
--
[] = '.'
}
return ,
}
// fmtInt formats v into the tail of buf.
// It returns the index where the output begins.
func fmtInt( []byte, uint64) int {
:= len()
if == 0 {
--
[] = '0'
} else {
for > 0 {
--
[] = byte(%10) + '0'
/= 10
}
}
return
}
// Nanoseconds returns the duration as an integer nanosecond count.
func ( Duration) () int64 { return int64() }
// Microseconds returns the duration as an integer microsecond count.
func ( Duration) () int64 { return int64() / 1e3 }
// Milliseconds returns the duration as an integer millisecond count.
func ( Duration) () int64 { return int64() / 1e6 }
// These methods return float64 because the dominant
// use case is for printing a floating point number like 1.5s, and
// a truncation to integer would make them not useful in those cases.
// Splitting the integer and fraction ourselves guarantees that
// converting the returned float64 to an integer rounds the same
// way that a pure integer conversion would have, even in cases
// where, say, float64(d.Nanoseconds())/1e9 would have rounded
// differently.
// Seconds returns the duration as a floating point number of seconds.
func ( Duration) () float64 {
:= / Second
:= % Second
return float64() + float64()/1e9
}
// Minutes returns the duration as a floating point number of minutes.
func ( Duration) () float64 {
:= / Minute
:= % Minute
return float64() + float64()/(60*1e9)
}
// Hours returns the duration as a floating point number of hours.
func ( Duration) () float64 {
:= / Hour
:= % Hour
return float64() + float64()/(60*60*1e9)
}
// Truncate returns the result of rounding d toward zero to a multiple of m.
// If m <= 0, Truncate returns d unchanged.
func ( Duration) ( Duration) Duration {
if <= 0 {
return
}
return - %
}
// lessThanHalf reports whether x+x < y but avoids overflow,
// assuming x and y are both positive (Duration is signed).
func lessThanHalf(, Duration) bool {
return uint64()+uint64() < uint64()
}
// Round returns the result of rounding d to the nearest multiple of m.
// The rounding behavior for halfway values is to round away from zero.
// If the result exceeds the maximum (or minimum)
// value that can be stored in a [Duration],
// Round returns the maximum (or minimum) duration.
// If m <= 0, Round returns d unchanged.
func ( Duration) ( Duration) Duration {
if <= 0 {
return
}
:= %
if < 0 {
= -
if lessThanHalf(, ) {
return +
}
if := - + ; < {
return
}
return minDuration // overflow
}
if lessThanHalf(, ) {
return -
}
if := + - ; > {
return
}
return maxDuration // overflow
}
// Abs returns the absolute value of d.
// As a special case, [math.MinInt64] is converted to [math.MaxInt64].
func ( Duration) () Duration {
switch {
case >= 0:
return
case == minDuration:
return maxDuration
default:
return -
}
}
// Add returns the time t+d.
func ( Time) ( Duration) Time {
:= int64( / 1e9)
:= .nsec() + int32(%1e9)
if >= 1e9 {
++
-= 1e9
} else if < 0 {
--
+= 1e9
}
.wall = .wall&^nsecMask | uint64() // update nsec
.addSec()
if .wall&hasMonotonic != 0 {
:= .ext + int64()
if < 0 && > .ext || > 0 && < .ext {
// Monotonic clock reading now out of range; degrade to wall-only.
.stripMono()
} else {
.ext =
}
}
return
}
// Sub returns the duration t-u. If the result exceeds the maximum (or minimum)
// value that can be stored in a [Duration], the maximum (or minimum) duration
// will be returned.
// To compute t-d for a duration d, use t.Add(-d).
func ( Time) ( Time) Duration {
if .wall&.wall&hasMonotonic != 0 {
return subMono(.ext, .ext)
}
:= Duration(.sec()-.sec())*Second + Duration(.nsec()-.nsec())
// Check for overflow or underflow.
switch {
case .Add().Equal():
return // d is correct
case .Before():
return minDuration // t - u is negative out of range
default:
return maxDuration // t - u is positive out of range
}
}
func subMono(, int64) Duration {
:= Duration( - )
if < 0 && > {
return maxDuration // t - u is positive out of range
}
if > 0 && < {
return minDuration // t - u is negative out of range
}
return
}
// Since returns the time elapsed since t.
// It is shorthand for time.Now().Sub(t).
func ( Time) Duration {
if .wall&hasMonotonic != 0 {
// Common case optimization: if t has monotonic time, then Sub will use only it.
return subMono(runtimeNano()-startNano, .ext)
}
return Now().Sub()
}
// Until returns the duration until t.
// It is shorthand for t.Sub(time.Now()).
func ( Time) Duration {
if .wall&hasMonotonic != 0 {
// Common case optimization: if t has monotonic time, then Sub will use only it.
return subMono(.ext, runtimeNano()-startNano)
}
return .Sub(Now())
}
// AddDate returns the time corresponding to adding the
// given number of years, months, and days to t.
// For example, AddDate(-1, 2, 3) applied to January 1, 2011
// returns March 4, 2010.
//
// Note that dates are fundamentally coupled to timezones, and calendrical
// periods like days don't have fixed durations. AddDate uses the Location of
// the Time value to determine these durations. That means that the same
// AddDate arguments can produce a different shift in absolute time depending on
// the base Time value and its Location. For example, AddDate(0, 0, 1) applied
// to 12:00 on March 27 always returns 12:00 on March 28. At some locations and
// in some years this is a 24 hour shift. In others it's a 23 hour shift due to
// daylight savings time transitions.
//
// AddDate normalizes its result in the same way that Date does,
// so, for example, adding one month to October 31 yields
// December 1, the normalized form for November 31.
func ( Time) ( int, int, int) Time {
, , := .Date()
, , := .Clock()
return Date(+, +Month(), +, , , , int(.nsec()), .Location())
}
const (
secondsPerMinute = 60
secondsPerHour = 60 * secondsPerMinute
secondsPerDay = 24 * secondsPerHour
secondsPerWeek = 7 * secondsPerDay
daysPer400Years = 365*400 + 97
daysPer100Years = 365*100 + 24
daysPer4Years = 365*4 + 1
)
// date computes the year, day of year, and when full=true,
// the month and day in which t occurs.
func ( Time) ( bool) ( int, Month, int, int) {
return absDate(.abs(), )
}
// absDate is like date but operates on an absolute time.
//
// absDate should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/phuslu/log
// - gitee.com/quant1x/gox
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname absDate
func absDate( uint64, bool) ( int, Month, int, int) {
// Split into time and day.
:= / secondsPerDay
// Account for 400 year cycles.
:= / daysPer400Years
:= 400 *
-= daysPer400Years *
// Cut off 100-year cycles.
// The last cycle has one extra leap year, so on the last day
// of that year, day / daysPer100Years will be 4 instead of 3.
// Cut it back down to 3 by subtracting n>>2.
= / daysPer100Years
-= >> 2
+= 100 *
-= daysPer100Years *
// Cut off 4-year cycles.
// The last cycle has a missing leap year, which does not
// affect the computation.
= / daysPer4Years
+= 4 *
-= daysPer4Years *
// Cut off years within a 4-year cycle.
// The last year is a leap year, so on the last day of that year,
// day / 365 will be 4 instead of 3. Cut it back down to 3
// by subtracting n>>2.
= / 365
-= >> 2
+=
-= 365 *
= int(int64() + absoluteZeroYear)
= int()
if ! {
return
}
=
if isLeap() {
// Leap year
switch {
case > 31+29-1:
// After leap day; pretend it wasn't there.
--
case == 31+29-1:
// Leap day.
= February
= 29
return
}
}
// Estimate month on assumption that every month has 31 days.
// The estimate may be too low by at most one month, so adjust.
= Month( / 31)
:= int(daysBefore[+1])
var int
if >= {
++
=
} else {
= int(daysBefore[])
}
++ // because January is 1
= - + 1
return
}
// daysBefore[m] counts the number of days in a non-leap year
// before month m begins. There is an entry for m=12, counting
// the number of days before January of next year (365).
var daysBefore = [...]int32{
0,
31,
31 + 28,
31 + 28 + 31,
31 + 28 + 31 + 30,
31 + 28 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
}
func daysIn( Month, int) int {
if == February && isLeap() {
return 29
}
return int(daysBefore[] - daysBefore[-1])
}
// daysSinceEpoch takes a year and returns the number of days from
// the absolute epoch to the start of that year.
// This is basically (year - zeroYear) * 365, but accounting for leap days.
func daysSinceEpoch( int) uint64 {
:= uint64(int64() - absoluteZeroYear)
// Add in days from 400-year cycles.
:= / 400
-= 400 *
:= daysPer400Years *
// Add in 100-year cycles.
= / 100
-= 100 *
+= daysPer100Years *
// Add in 4-year cycles.
= / 4
-= 4 *
+= daysPer4Years *
// Add in non-leap years.
=
+= 365 *
return
}
// Provided by package runtime.
func now() ( int64, int32, int64)
// runtimeNano returns the current value of the runtime clock in nanoseconds.
//
//go:linkname runtimeNano runtime.nanotime
func runtimeNano() int64
// Monotonic times are reported as offsets from startNano.
// We initialize startNano to runtimeNano() - 1 so that on systems where
// monotonic time resolution is fairly low (e.g. Windows 2008
// which appears to have a default resolution of 15ms),
// we avoid ever reporting a monotonic time of 0.
// (Callers may want to use 0 as "time not set".)
var startNano int64 = runtimeNano() - 1
// x/tools uses a linkname of time.Now in its tests. No harm done.
//go:linkname Now
// Now returns the current local time.
func () Time {
, , := now()
-= startNano
+= unixToInternal - minWall
if uint64()>>33 != 0 {
// Seconds field overflowed the 33 bits available when
// storing a monotonic time. This will be true after
// March 16, 2157.
return Time{uint64(), + minWall, Local}
}
return Time{hasMonotonic | uint64()<<nsecShift | uint64(), , Local}
}
func unixTime( int64, int32) Time {
return Time{uint64(), + unixToInternal, Local}
}
// UTC returns t with the location set to UTC.
func ( Time) () Time {
.setLoc(&utcLoc)
return
}
// Local returns t with the location set to local time.
func ( Time) () Time {
.setLoc(Local)
return
}
// In returns a copy of t representing the same time instant, but
// with the copy's location information set to loc for display
// purposes.
//
// In panics if loc is nil.
func ( Time) ( *Location) Time {
if == nil {
panic("time: missing Location in call to Time.In")
}
.setLoc()
return
}
// Location returns the time zone information associated with t.
func ( Time) () *Location {
:= .loc
if == nil {
= UTC
}
return
}
// Zone computes the time zone in effect at time t, returning the abbreviated
// name of the zone (such as "CET") and its offset in seconds east of UTC.
func ( Time) () ( string, int) {
, , _, _, _ = .loc.lookup(.unixSec())
return
}
// ZoneBounds returns the bounds of the time zone in effect at time t.
// The zone begins at start and the next zone begins at end.
// If the zone begins at the beginning of time, start will be returned as a zero Time.
// If the zone goes on forever, end will be returned as a zero Time.
// The Location of the returned times will be the same as t.
func ( Time) () (, Time) {
, , , , := .loc.lookup(.unixSec())
if != alpha {
= unixTime(, 0)
.setLoc(.loc)
}
if != omega {
= unixTime(, 0)
.setLoc(.loc)
}
return
}
// Unix returns t as a Unix time, the number of seconds elapsed
// since January 1, 1970 UTC. The result does not depend on the
// location associated with t.
// Unix-like operating systems often record time as a 32-bit
// count of seconds, but since the method here returns a 64-bit
// value it is valid for billions of years into the past or future.
func ( Time) () int64 {
return .unixSec()
}
// UnixMilli returns t as a Unix time, the number of milliseconds elapsed since
// January 1, 1970 UTC. The result is undefined if the Unix time in
// milliseconds cannot be represented by an int64 (a date more than 292 million
// years before or after 1970). The result does not depend on the
// location associated with t.
func ( Time) () int64 {
return .unixSec()*1e3 + int64(.nsec())/1e6
}
// UnixMicro returns t as a Unix time, the number of microseconds elapsed since
// January 1, 1970 UTC. The result is undefined if the Unix time in
// microseconds cannot be represented by an int64 (a date before year -290307 or
// after year 294246). The result does not depend on the location associated
// with t.
func ( Time) () int64 {
return .unixSec()*1e6 + int64(.nsec())/1e3
}
// UnixNano returns t as a Unix time, the number of nanoseconds elapsed
// since January 1, 1970 UTC. The result is undefined if the Unix time
// in nanoseconds cannot be represented by an int64 (a date before the year
// 1678 or after 2262). Note that this means the result of calling UnixNano
// on the zero Time is undefined. The result does not depend on the
// location associated with t.
func ( Time) () int64 {
return (.unixSec())*1e9 + int64(.nsec())
}
const (
timeBinaryVersionV1 byte = iota + 1 // For general situation
timeBinaryVersionV2 // For LMT only
)
// MarshalBinary implements the encoding.BinaryMarshaler interface.
func ( Time) () ([]byte, error) {
var int16 // minutes east of UTC. -1 is UTC.
var int8
:= timeBinaryVersionV1
if .Location() == UTC {
= -1
} else {
, := .Zone()
if %60 != 0 {
= timeBinaryVersionV2
= int8( % 60)
}
/= 60
if < -32768 || == -1 || > 32767 {
return nil, errors.New("Time.MarshalBinary: unexpected zone offset")
}
= int16()
}
:= .sec()
:= .nsec()
:= []byte{
, // byte 0 : version
byte( >> 56), // bytes 1-8: seconds
byte( >> 48),
byte( >> 40),
byte( >> 32),
byte( >> 24),
byte( >> 16),
byte( >> 8),
byte(),
byte( >> 24), // bytes 9-12: nanoseconds
byte( >> 16),
byte( >> 8),
byte(),
byte( >> 8), // bytes 13-14: zone offset in minutes
byte(),
}
if == timeBinaryVersionV2 {
= append(, byte())
}
return , nil
}
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
func ( *Time) ( []byte) error {
:=
if len() == 0 {
return errors.New("Time.UnmarshalBinary: no data")
}
:= [0]
if != timeBinaryVersionV1 && != timeBinaryVersionV2 {
return errors.New("Time.UnmarshalBinary: unsupported version")
}
:= /*version*/ 1 + /*sec*/ 8 + /*nsec*/ 4 + /*zone offset*/ 2
if == timeBinaryVersionV2 {
++
}
if len() != {
return errors.New("Time.UnmarshalBinary: invalid length")
}
= [1:]
:= int64([7]) | int64([6])<<8 | int64([5])<<16 | int64([4])<<24 |
int64([3])<<32 | int64([2])<<40 | int64([1])<<48 | int64([0])<<56
= [8:]
:= int32([3]) | int32([2])<<8 | int32([1])<<16 | int32([0])<<24
= [4:]
:= int(int16([1])|int16([0])<<8) * 60
if == timeBinaryVersionV2 {
+= int([2])
}
* = Time{}
.wall = uint64()
.ext =
if == -1*60 {
.setLoc(&utcLoc)
} else if , , , , := Local.lookup(.unixSec()); == {
.setLoc(Local)
} else {
.setLoc(FixedZone("", ))
}
return nil
}
// TODO(rsc): Remove GobEncoder, GobDecoder, MarshalJSON, UnmarshalJSON in Go 2.
// The same semantics will be provided by the generic MarshalBinary, MarshalText,
// UnmarshalBinary, UnmarshalText.
// GobEncode implements the gob.GobEncoder interface.
func ( Time) () ([]byte, error) {
return .MarshalBinary()
}
// GobDecode implements the gob.GobDecoder interface.
func ( *Time) ( []byte) error {
return .UnmarshalBinary()
}
// MarshalJSON implements the [json.Marshaler] interface.
// The time is a quoted string in the RFC 3339 format with sub-second precision.
// If the timestamp cannot be represented as valid RFC 3339
// (e.g., the year is out of range), then an error is reported.
func ( Time) () ([]byte, error) {
:= make([]byte, 0, len(RFC3339Nano)+len(`""`))
= append(, '"')
, := .appendStrictRFC3339()
= append(, '"')
if != nil {
return nil, errors.New("Time.MarshalJSON: " + .Error())
}
return , nil
}
// UnmarshalJSON implements the [json.Unmarshaler] interface.
// The time must be a quoted string in the RFC 3339 format.
func ( *Time) ( []byte) error {
if string() == "null" {
return nil
}
// TODO(https://go.dev/issue/47353): Properly unescape a JSON string.
if len() < 2 || [0] != '"' || [len()-1] != '"' {
return errors.New("Time.UnmarshalJSON: input is not a JSON string")
}
= [len(`"`) : len()-len(`"`)]
var error
*, = parseStrictRFC3339()
return
}
// MarshalText implements the [encoding.TextMarshaler] interface.
// The time is formatted in RFC 3339 format with sub-second precision.
// If the timestamp cannot be represented as valid RFC 3339
// (e.g., the year is out of range), then an error is reported.
func ( Time) () ([]byte, error) {
:= make([]byte, 0, len(RFC3339Nano))
, := .appendStrictRFC3339()
if != nil {
return nil, errors.New("Time.MarshalText: " + .Error())
}
return , nil
}
// UnmarshalText implements the [encoding.TextUnmarshaler] interface.
// The time must be in the RFC 3339 format.
func ( *Time) ( []byte) error {
var error
*, = parseStrictRFC3339()
return
}
// Unix returns the local Time corresponding to the given Unix time,
// sec seconds and nsec nanoseconds since January 1, 1970 UTC.
// It is valid to pass nsec outside the range [0, 999999999].
// Not all sec values have a corresponding time value. One such
// value is 1<<63-1 (the largest int64 value).
func ( int64, int64) Time {
if < 0 || >= 1e9 {
:= / 1e9
+=
-= * 1e9
if < 0 {
+= 1e9
--
}
}
return unixTime(, int32())
}
// UnixMilli returns the local Time corresponding to the given Unix time,
// msec milliseconds since January 1, 1970 UTC.
func ( int64) Time {
return Unix(/1e3, (%1e3)*1e6)
}
// UnixMicro returns the local Time corresponding to the given Unix time,
// usec microseconds since January 1, 1970 UTC.
func ( int64) Time {
return Unix(/1e6, (%1e6)*1e3)
}
// IsDST reports whether the time in the configured location is in Daylight Savings Time.
func ( Time) () bool {
, , , , := .loc.lookup(.Unix())
return
}
func isLeap( int) bool {
return %4 == 0 && (%100 != 0 || %400 == 0)
}
// norm returns nhi, nlo such that
//
// hi * base + lo == nhi * base + nlo
// 0 <= nlo < base
func norm(, , int) (, int) {
if < 0 {
:= (--1)/ + 1
-=
+= *
}
if >= {
:= /
+=
-= *
}
return ,
}
// Date returns the Time corresponding to
//
// yyyy-mm-dd hh:mm:ss + nsec nanoseconds
//
// in the appropriate zone for that time in the given location.
//
// The month, day, hour, min, sec, and nsec values may be outside
// their usual ranges and will be normalized during the conversion.
// For example, October 32 converts to November 1.
//
// A daylight savings time transition skips or repeats times.
// For example, in the United States, March 13, 2011 2:15am never occurred,
// while November 6, 2011 1:15am occurred twice. In such cases, the
// choice of time zone, and therefore the time, is not well-defined.
// Date returns a time that is correct in one of the two zones involved
// in the transition, but it does not guarantee which.
//
// Date panics if loc is nil.
func ( int, Month, , , , , int, *Location) Time {
if == nil {
panic("time: missing Location in call to Date")
}
// Normalize month, overflowing into year.
:= int() - 1
, = norm(, , 12)
= Month() + 1
// Normalize nsec, sec, min, hour, overflowing into day.
, = norm(, , 1e9)
, = norm(, , 60)
, = norm(, , 60)
, = norm(, , 24)
// Compute days since the absolute epoch.
:= daysSinceEpoch()
// Add in days before this month.
+= uint64(daysBefore[-1])
if isLeap() && >= March {
++ // February 29
}
// Add in days before today.
+= uint64( - 1)
// Add in time elapsed today.
:= * secondsPerDay
+= uint64(*secondsPerHour + *secondsPerMinute + )
:= int64() + (absoluteToInternal + internalToUnix)
// Look for zone offset for expected time, so we can adjust to UTC.
// The lookup function expects UTC, so first we pass unix in the
// hope that it will not be too close to a zone transition,
// and then adjust if it is.
, , , , := .lookup()
if != 0 {
:= - int64()
// If utc is valid for the time zone we found, then we have the right offset.
// If not, we get the correct offset by looking up utc in the location.
if < || >= {
_, , _, _, _ = .lookup()
}
-= int64()
}
:= unixTime(, int32())
.setLoc()
return
}
// Truncate returns the result of rounding t down to a multiple of d (since the zero time).
// If d <= 0, Truncate returns t stripped of any monotonic clock reading but otherwise unchanged.
//
// Truncate operates on the time as an absolute duration since the
// zero time; it does not operate on the presentation form of the
// time. Thus, Truncate(Hour) may return a time with a non-zero
// minute, depending on the time's Location.
func ( Time) ( Duration) Time {
.stripMono()
if <= 0 {
return
}
, := div(, )
return .Add(-)
}
// Round returns the result of rounding t to the nearest multiple of d (since the zero time).
// The rounding behavior for halfway values is to round up.
// If d <= 0, Round returns t stripped of any monotonic clock reading but otherwise unchanged.
//
// Round operates on the time as an absolute duration since the
// zero time; it does not operate on the presentation form of the
// time. Thus, Round(Hour) may return a time with a non-zero
// minute, depending on the time's Location.
func ( Time) ( Duration) Time {
.stripMono()
if <= 0 {
return
}
, := div(, )
if lessThanHalf(, ) {
return .Add(-)
}
return .Add( - )
}
// div divides t by d and returns the quotient parity and remainder.
// We don't use the quotient parity anymore (round half up instead of round to even)
// but it's still here in case we change our minds.
func div( Time, Duration) ( int, Duration) {
:= false
:= .nsec()
:= .sec()
if < 0 {
// Operate on absolute value.
= true
= -
= -
if < 0 {
+= 1e9
-- // sec >= 1 before the -- so safe
}
}
switch {
// Special case: 2d divides 1 second.
case < Second && Second%(+) == 0:
= int(/int32()) & 1
= Duration( % int32())
// Special case: d is a multiple of 1 second.
case %Second == 0:
:= int64( / Second)
= int(/) & 1
= Duration(%)*Second + Duration()
// General case.
// This could be faster if more cleverness were applied,
// but it's really only here to avoid special case restrictions in the API.
// No one will care about these cases.
default:
// Compute nanoseconds as 128-bit number.
:= uint64()
:= ( >> 32) * 1e9
:= >> 32
:= << 32
= ( & 0xFFFFFFFF) * 1e9
, := , +
if < {
++
}
, = , +uint64()
if < {
++
}
// Compute remainder by subtracting r<<k for decreasing k.
// Quotient parity is whether we subtract on last round.
:= uint64()
for >>63 != 1 {
<<= 1
}
:= uint64(0)
for {
= 0
if > || == && >= {
// subtract
= 1
, = , -
if > {
--
}
-=
}
if == 0 && == uint64() {
break
}
>>= 1
|= ( & 1) << 63
>>= 1
}
= Duration()
}
if && != 0 {
// If input was negative and not an exact multiple of d, we computed q, r such that
// q*d + r = -t
// But the right answers are given by -(q-1), d-r:
// q*d + r = -t
// -q*d - r = t
// -(q-1)*d + (d - r) = t
^= 1
= -
}
return
}
The pages are generated with Golds v0.6.9-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |