Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.

Вернуться к обычному просмотру страницы.

Пакет time языка программирования Go

Пакет time предоставляет функции для измерения и отображения времени.

    Календарные вычисления всегда основаны на григорианском календаре без учета високосных секунд.

    Монотонные часы

    Операционные системы предоставляют как “системные часы” (которые могут корректироваться для синхронизации времени), так и “монотонные часы” (которые не подвержены таким изменениям). Общее правило гласит: системные часы используются для определения текущего времени, а монотонные часы - для измерения временных интервалов. Вместо разделения API, в данном пакете Time, возвращаемый функцией time.Now, содержит показания как системных, так и монотонных часов. Последующие операции определения времени используют показания системных часов, тогда как операции измерения времени (в частности, сравнения и вычитания) используют показания монотонных часов.

    Например, следующий код всегда вычисляет положительный интервал времени около 20 миллисекунд, даже если системные часы были изменены во время выполнения измеряемой операции:

    start := time.Now()
    ... operation that takes 20 milliseconds ...
    t := time.Now()
    elapsed := t.Sub(start)
    

    Другие идиомы, такие как time.Since(start), time.Until(deadline) и time.Now().Before(deadline), также устойчивы к сбросам системных часов.

    Остальная часть этого раздела содержит точные детали использования монотонных часов в операциях, но для работы с пакетом понимание этих деталей не требуется.

    Особенности работы с монотонными часами

    1. Функция time.Now()
      Возвращаемое значение Time содержит показания монотонных часов. Если время t включает монотонные часы:

      • t.Add добавляет длительность как к системным, так и к монотонным часам
      • t.AddDate, t.Round и t.Truncate работают только с системным временем и удаляют монотонные показания
      • t.In, t.Local и t.UTC также удаляют монотонные показания
      • Стандартный способ удалить монотонные показания: t = t.Round(0)
    2. Сравнение времен
      Если оба значения t и u содержат монотонные показания:

      • t.After(u), t.Before(u), t.Equal(u), t.Compare(u) и t.Sub(u) используют только монотонные часы
      • Если одно из значений не имеет монотонных показаний, используются системные часы
    3. Особые случаи

      • На некоторых системах монотонные часы останавливаются при переходе в спящий режим
      • В таких случаях t.Sub(u) и аналогичные операции могут давать неточные результаты
      • Иногда требуется удалить монотонные показания для получения точных данных
    4. Сериализация и форматирование
      Монотонные показания:

      • Не включаются при сериализации (GobEncode, MarshalJSON и др.)
      • Не имеют формата вывода в t.Format
      • Не создаются конструкторами (Date, Parse, Unix и др.)
    5. Особенности реализации

      • Монотонные показания существуют только в значениях Time
      • Не входят в Duration или Unix-время (t.Unix)
      • Оператор == сравнивает Location и монотонные показания
    6. Отладка

      • t.String() показывает монотонные показания при их наличии
      • Различия в монотонных показаниях видны при выводе

    Разрешение таймеров ¶

    Разрешение таймеров зависит от:

    • Версии Go
    • Операционной системы
    • Аппаратного обеспечения

    Типичные значения:

    • Unix: ~1 мс
    • Windows 1803+: ~0.5 мс
    • Старые версии Windows: ~16 мс (можно улучшить через windows.TimeBeginPeriod)

    Константы

    const (
    	Layout = «01/02 03:04:05PM '06 -0700» // Время отсчета, в числовом порядке.
    	ANSIC = «Mon Jan _2 15:04:05 2006»
    	UnixDate = «Mon Jan _2 15:04:05 MST 2006»
    	RubyDate = «Mon Jan 02 15:04:05 -0700 2006»
    	RFC822 = «02 Jan 06 15:04 MST»
    	RFC822Z = «02 Jan 06 15:04 -0700» // RFC822 с числовой зоной
    	RFC850 = «Monday, 02-Jan-06 15:04:05 MST»
    	RFC1123 = «Mon, 02 Jan 2006 15:04:05 MST»
    	RFC1123Z = «Mon, 02 Jan 2006 15:04:05 -0700» // RFC1123 с числовой зоной
    	RFC3339 = «2006-01-02T15:04:05Z07:00»
    	RFC3339Nano = «2006-01-02T15:04:05.9999999Z07:00»
    	Kitchen = «3:04PM»
    	// Удобные временные метки.
    	Stamp = «Jan _2 15:04:05»
    	StampMilli = «Jan _2 15:04:05.000»
    	StampMicro = «Jan _2 15:04:05.000000»
    	StampNano = «Jan _2 15:04:05.000000000»
    	DateTime = «2006-01-02 15:04:05»
    	DateOnly = «2006-01-02»
    	TimeOnly = «15:04:05»
    )
    

    Это предопределенные макеты для использования в Time.Format и time.Parse. В качестве опорного времени в этих макетах используется конкретная временная метка:

    01/02 03:04:05PM '06 -0700
    

    (2 января, 15:04:05, 2006, в часовом поясе на семь часов западнее GMT). Это значение записывается как константа с именем Layout, приведенным ниже. В качестве времени Unix это 1136239445. Поскольку MST - это GMT-0700, команда Unix date выведет ссылку в виде:

    Mon Jan 2 15:04:05 MST 2006.
    

    Досадная историческая ошибка заключается в том, что в дате используется американская конвенция, согласно которой числовой месяц ставится перед днем.

    Пример Time.Format подробно демонстрирует работу со строкой компоновки и является хорошей ссылкой.

    Обратите внимание, что форматы RFC822, RFC850 и RFC1123 следует применять только к местному времени. При их использовании для времени UTC в качестве сокращения часового пояса будет использоваться «UTC», в то время как, строго говоря, эти RFC требуют использовать «GMT» в этом случае. При использовании форматов RFC1123 или RFC1123Z для разбора, обратите внимание, что эти форматы определяют ведущий ноль для части «день-месяц», что строго не разрешено RFC 1123. Это приведет к ошибке при разборе строк дат, которые приходятся на первые 9 дней данного месяца. В общем случае RFC1123Z следует использовать вместо RFC1123 для серверов, которые настаивают на этом формате, а RFC3339 следует предпочесть для новых протоколов. RFC3339, RFC822, RFC822Z, RFC1123 и RFC1123Z полезны для форматирования; при использовании с time.Parse они принимают не все форматы времени, разрешенные RFC, и принимают форматы времени, не определенные формально. Формат RFC3339Nano удаляет нули в конце поля секунд, поэтому после форматирования он может сортироваться некорректно.

    Большинство программ могут использовать одну из определенных констант в качестве макета, передаваемого в Format или Parse. Остальную часть этого комментария можно игнорировать, если только вы не создаете собственную строку макета.

    Чтобы определить свой собственный формат, запишите, как будет выглядеть эталонное время, отформатированное вашим способом; в качестве примера можно посмотреть значения таких констант, как ANSIC, StampMicro или Kitchen. Модель призвана продемонстрировать, как выглядит эталонное время, чтобы методы Format и Parse могли применить то же преобразование к общему значению времени.

    Ниже приводится краткое описание компонентов строки макета. Каждый элемент показывает на примере форматирование элемента эталонного времени. Распознаются только эти значения. Текст в компоновочной строке, который не распознается как часть эталонного времени, дословно повторяется во время Format и, как ожидается, дословно отображается на входе в Parse.

    Year: "2006" "06"
    Month: "Jan" "January" "01" "1"
    Day of the week: "Mon" "Monday"
    Day of the month: "2" "_2" "02"
    Day of the year: "__2" "002"
    Hour: "15" "3" "03" (PM or AM)
    Minute: "4" "04"
    Second: "5" "05"
    AM/PM mark: "PM"
    

    Числовые смещения часовых поясов форматируются следующим образом:

    "-0700"     ±hhmm
    "-07:00"    ±hh:mm
    "-07"       ±hh
    "-070000"   ±hhmmss
    "-07:00:00" ±hh:mm:ss
    

    Если в формате заменить знак на Z, это включит режим ISO 8601, где для UTC отображается Z вместо указания смещения. Например:

    "Z0700"      Z or ±hhmm
    "Z07:00"     Z or ±hh:mm
    "Z07"        Z or ±hh
    "Z070000"    Z or ±hhmmss
    "Z07:00:00"  Z or ±hh:mm:ss
    

    В строке формата подчёркивания в "_2" и "__2" обозначают пробелы, которые могут заменяться цифрами, если следующее число состоит из нескольких цифр, для совместимости с фиксированными форматами времени Unix. Ноль в начале означает дополнение нулями.

    Форматы __2 и 002 обозначают день года, дополненный пробелами или нулями до трёх символов; формата без дополнения для дня года не существует.

    Запятая или точка, за которыми следуют один или несколько нулей, обозначают долю секунды, выводимую с указанным количеством знаков после запятой. Запятая или точка, за которыми следуют одна или несколько девяток, обозначают долю секунды, выводимую с указанным количеством знаков после запятой, но с удалением завершающих нулей. Например, форматы "15:04:05,000" или "15:04:05.000" форматируют или парсят время с миллисекундной точностью.

    Некоторые допустимые форматы являются недопустимыми значениями времени для time.Parse, из-за элементов вроде _ (пробельного дополнения) или Z (информации о временной зоне).

    const (
    	Nanosecond  Duration = 1
    	Microsecond          = 1000 * Nanosecond
    	Millisecond          = 1000 * Microsecond
    	Second               = 1000 * Millisecond
    	Minute               = 60 * Second
    	Hour                 = 60 * Minute
    )
    

    Стандартные длительности (Common durations)

    Не существует определения для единиц измерения “День” или больше, чтобы избежать путаницы из-за перехода на летнее/зимнее время в разных часовых поясах.

    Чтобы подсчитать количество единиц в Duration (длительности), выполните деление:

    second := time.Second
    fmt.Print(int64(second/time.Millisecond)) // prints 1000
    

    Чтобы преобразовать целое количество единиц в Duration (длительность), выполните умножение:

    seconds := 10
    fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
    

    func After

    func After(d Duration) <-chan Time
    

    After ожидает истечения указанной длительности d, после чего отправляет текущее время в возвращаемом канале. Эквивалентно NewTimer(d).C.

    Изменения в Go 1.23:
    В ранних версиях документация предупреждала, что таймер не освобождался сборщиком мусора до срабатывания, и рекомендовала использовать NewTimer с ручным вызовом Timer.Stop для оптимизации. Начиная с Go 1.23, сборщик мусора может освобождать неиспользуемые таймеры, даже если они не остановлены. Нет необходимости использовать NewTimer вместо After.

    Пример использования:

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    var c chan int
    
    func handle(int) {}
    
    func main() {
    	select {
    	case m := <-c:
    		handle(m)
    	case <-time.After(10 * time.Second):
    		fmt.Println("timed out")
    	}
    }
    

    func Sleep

    func Sleep(d Duration)
    

    Sleep приостанавливает выполнение текущей горутины как минимум на указанную длительность d. Отрицательное или нулевое значение приводит к немедленному возврату.

    Пример:

    package main
    
    import (
        "time"
    )
    
    func main() {
        time.Sleep(100 * time.Millisecond) // Пауза на 100 мс
    }
    

    func Tick

    func Tick(d Duration) <-chan Time
    

    Tick — это удобная обёртка над NewTicker, предоставляющая только канал с тиками. В отличие от NewTicker, возвращает nil при d <= 0.

    Изменения в Go 1.23:
    Ранее документация указывала, что сборщик мусора не освобождает неостановленные тикеры, и рекомендовала использовать NewTicker с Ticker.Stop. В Go 1.23 сборщик может освобождать неиспользуемые тикеры, даже без вызова Stop. Нет причин предпочитать NewTicker, если достаточно Tick.

    Пример использования:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func statusUpdate() string { return "" }
    
    func main() {
        c := time.Tick(5 * time.Second) // Тикер каждые 5 секунд
        for next := range c {
            fmt.Printf("%v %s\n", next, statusUpdate())
        }
    }
    

    Вот перевод технической документации пакета time на русский язык:

    Типы

    type Duration

    type Duration int64
    

    Тип Duration представляет промежуток времени между двумя моментами в виде количества наносекунд int64. Представление ограничивает максимальную продолжительность примерно 290 годами.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func expensiveCall() {}
    
    func main() {
    	t0 := time.Now()
    	expensiveCall()
    	t1 := time.Now()
    	fmt.Printf("The call took %v to run.\n", t1.Sub(t0))
    }

    func ParseDuration

    func ParseDuration(s string) (Duration, error)
    

    ParseDuration разбирает строку продолжительности. Строка продолжительности - это возможно знаковая последовательность десятичных чисел, каждое с необязательной дробной частью и суффиксом единицы, например “300ms”, “-1.5h” или “2h45m”. Допустимые единицы времени: “ns”, “us” (или “µs”), “ms”, “s”, “m”, “h”.

    Пример
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	hours, _ := time.ParseDuration("10h")
    	complex, _ := time.ParseDuration("1h10m10s")
    	micro, _ := time.ParseDuration("1µs")
    	// The package also accepts the incorrect but common prefix u for micro.
    	micro2, _ := time.ParseDuration("1us")
    
    	fmt.Println(hours)
    	fmt.Println(complex)
    	fmt.Printf("There are %.0f seconds in %v.\n", complex.Seconds(), complex)
    	fmt.Printf("There are %d nanoseconds in %v.\n", micro.Nanoseconds(), micro)
    	fmt.Printf("There are %6.2e seconds in %v.\n", micro2.Seconds(), micro2)
    }
    
    Output:
    
    10h0m0s
    1h10m10s
    There are 4210 seconds in 1h10m10s.
    There are 1000 nanoseconds in 1µs.
    There are 1.00e-06 seconds in 1µs.

    func Since

    func Since(t Time) Duration
    

    Since возвращает время, прошедшее с момента t. Это сокращение для time.Now().Sub(t).

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func expensiveCall() {}
    
    func main() {
    	start := time.Now()
    	expensiveCall()
    	elapsed := time.Since(start)
    	fmt.Printf("The call took %v to run.\n", elapsed)
    }

    func Until

    func Until(t Time) Duration
    

    Until возвращает продолжительность до момента t. Это сокращение для t.Sub(time.Now()).

    Пример
    package main
    
    import (
    	"fmt"
    	"math"
    	"time"
    )
    
    func main() {
    	futureTime := time.Now().Add(5 * time.Second)
    	durationUntil := time.Until(futureTime)
    	fmt.Printf("Duration until future time: %.0f seconds", math.Ceil(durationUntil.Seconds()))
    }
    
    Output:
    
    Duration until future time: 5 seconds

    func (Duration) Abs

    func (d Duration) Abs() Duration
    

    Abs возвращает абсолютное значение d. В особом случае Duration(math.MinInt64) преобразуется в Duration(math.MaxInt64), уменьшая его величину на 1 наносекунду.

    Пример
    package main
    
    import (
    	"fmt"
    	"math"
    	"time"
    )
    
    func main() {
    	positiveDuration := 5 * time.Second
    	negativeDuration := -3 * time.Second
    	minInt64CaseDuration := time.Duration(math.MinInt64)
    
    	absPositive := positiveDuration.Abs()
    	absNegative := negativeDuration.Abs()
    	absSpecial := minInt64CaseDuration.Abs() == time.Duration(math.MaxInt64)
    
    	fmt.Printf("Absolute value of positive duration: %v\n", absPositive)
    	fmt.Printf("Absolute value of negative duration: %v\n", absNegative)
    	fmt.Printf("Absolute value of MinInt64 equal to MaxInt64: %t\n", absSpecial)
    
    }
    
    Output:
    
    Absolute value of positive duration: 5s
    Absolute value of negative duration: 3s
    Absolute value of MinInt64 equal to MaxInt64: true

    func (Duration) Hours

    func (d Duration) Hours() float64
    

    Hours возвращает продолжительность как число часов с плавающей точкой.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	h, _ := time.ParseDuration("4h30m")
    	fmt.Printf("I've got %.1f hours of work left.", h.Hours())
    }
    Output:
    
    I've got 4.5 hours of work left.

    func (Duration) Microseconds

    func (d Duration) Microseconds() int64
    

    Microseconds возвращает продолжительность как целое количество микросекунд.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	u, _ := time.ParseDuration("1s")
    	fmt.Printf("One second is %d microseconds.\n", u.Microseconds())
    }
    
    Output:
    
    One second is 1000000 microseconds.

    func (Duration) Milliseconds

    func (d Duration) Milliseconds() int64
    

    Milliseconds возвращает продолжительность как целое количество миллисекунд.

    func (Duration) Minutes

    func (d Duration) Minutes() float64
    

    Minutes возвращает продолжительность как число минут с плавающей точкой.

    func (Duration) Nanoseconds

    func (d Duration) Nanoseconds() int64
    

    Nanoseconds возвращает продолжительность как целое количество наносекунд.

    func (Duration) Round

    func (d Duration) Round(m Duration) Duration
    

    Round возвращает результат округления d до ближайшего кратного m. При округлении половинных значений округление выполняется от нуля. Если результат превышает максимальное (или минимальное) значение, которое может храниться в Duration, возвращается максимальная (или минимальная) продолжительность. Если m <= 0, Round возвращает d без изменений.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	d, err := time.ParseDuration("1h15m30.918273645s")
    	if err != nil {
    		panic(err)
    	}
    
    	round := []time.Duration{
    		time.Nanosecond,
    		time.Microsecond,
    		time.Millisecond,
    		time.Second,
    		2 * time.Second,
    		time.Minute,
    		10 * time.Minute,
    		time.Hour,
    	}
    
    	for _, r := range round {
    		fmt.Printf("d.Round(%6s) = %s\n", r, d.Round(r).String())
    	}
    }
    
    d.Round(   1ns) = 1h15m30.918273645s
    d.Round(   1µs) = 1h15m30.918274s
    d.Round(   1ms) = 1h15m30.918s
    d.Round(    1s) = 1h15m31s
    d.Round(    2s) = 1h15m30s
    d.Round(  1m0s) = 1h16m0s
    d.Round( 10m0s) = 1h20m0s
    d.Round(1h0m0s) = 1h0m0s

    func (Duration) Seconds

    func (d Duration) Seconds() float64
    

    Seconds возвращает продолжительность как число секунд с плавающей точкой.

    func (Duration) String

    func (d Duration) String() string
    

    String возвращает строковое представление продолжительности в виде “72h3m0.5s”. Ведущие нулевые единицы опускаются. В особом случае продолжительности менее одной секунды используют меньшие единицы (милли-, микро- или наносекунды), чтобы ведущая цифра была не нулевой. Нулевая продолжительность форматируется как “0s”.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	fmt.Println(1*time.Hour + 2*time.Minute + 300*time.Millisecond)
    	fmt.Println(300 * time.Millisecond)
    }
    
    Output:
    
    1h2m0.3s
    300ms

    func (Duration) Truncate

    func (d Duration) Truncate(m Duration) Duration
    

    Truncate возвращает результат округления d к нулю до кратного m. Если m <= 0, Truncate возвращает d без изменений.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	d, err := time.ParseDuration("1h15m30.918273645s")
    	if err != nil {
    		panic(err)
    	}
    
    	trunc := []time.Duration{
    		time.Nanosecond,
    		time.Microsecond,
    		time.Millisecond,
    		time.Second,
    		2 * time.Second,
    		time.Minute,
    		10 * time.Minute,
    		time.Hour,
    	}
    
    	for _, t := range trunc {
    		fmt.Printf("d.Truncate(%6s) = %s\n", t, d.Truncate(t).String())
    	}
    }
    
    Output:
    
    d.Truncate(   1ns) = 1h15m30.918273645s
    d.Truncate(   1µs) = 1h15m30.918273s
    d.Truncate(   1ms) = 1h15m30.918s
    d.Truncate(    1s) = 1h15m30s
    d.Truncate(    2s) = 1h15m30s
    d.Truncate(  1m0s) = 1h15m0s
    d.Truncate( 10m0s) = 1h10m0s
    d.Truncate(1h0m0s) = 1h0m0s

    type Location

    type Location struct {
    	// содержит неэкспортируемые поля
    }
    

    Тип Location отображает моменты времени в часовом поясе, используемом в этот момент. Обычно Location представляет набор смещений времени, используемых в географическом регионе. Для многих Location смещение времени варьируется в зависимости от того, действует ли летнее время в данный момент.

    Location используется для предоставления часового пояса в печатном значении Time и для вычислений, включающих интервалы, которые могут пересекать границы перехода на летнее время.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	// China doesn't have daylight saving. It uses a fixed 8 hour offset from UTC.
    	secondsEastOfUTC := int((8 * time.Hour).Seconds())
    	beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
    
    	// If the system has a timezone database present, it's possible to load a location
    	// from that, e.g.:
    	//    newYork, err := time.LoadLocation("America/New_York")
    
    	// Creating a time requires a location. Common locations are time.Local and time.UTC.
    	timeInUTC := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
    	sameTimeInBeijing := time.Date(2009, 1, 1, 20, 0, 0, 0, beijing)
    
    	// Although the UTC clock time is 1200 and the Beijing clock time is 2000, Beijing is
    	// 8 hours ahead so the two dates actually represent the same instant.
    	timesAreEqual := timeInUTC.Equal(sameTimeInBeijing)
    	fmt.Println(timesAreEqual)
    
    }
    
    Output:
    
    true
    var Local *Location = &localLoc
    

    Local представляет локальный часовой пояс системы. В Unix-системах Local обращается к переменной окружения TZ для определения используемого часового пояса. Отсутствие TZ означает использование системного значения по умолчанию /etc/localtime. TZ="" означает использование UTC. TZ=“foo” означает использование файла foo в системном каталоге часовых поясов.

    var UTC *Location = &utcLoc
    

    UTC представляет Универсальное Координированное Время (UTC).

    func FixedZone

    func FixedZone(name string, offset int) *Location
    

    FixedZone возвращает Location, который всегда использует заданное имя пояса и смещение (в секундах к востоку от UTC).

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	loc := time.FixedZone("UTC-8", -8*60*60)
    	t := time.Date(2009, time.November, 10, 23, 0, 0, 0, loc)
    	fmt.Println("The time is:", t.Format(time.RFC822))
    }
    
    Output:
    
    The time is: 10 Nov 09 23:00 UTC-8

    func LoadLocation

    func LoadLocation(name string) (*Location, error)
    

    LoadLocation возвращает Location с заданным именем.

    Если имя "" или “UTC”, LoadLocation возвращает UTC. Если имя “Local”, LoadLocation возвращает Local.

    В противном случае имя считается именем местоположения, соответствующим файлу в базе данных часовых поясов IANA, например “America/New_York”.

    LoadLocation ищет базу данных часовых поясов IANA в следующих местах по порядку:

    1. Каталог или распакованный zip-файл, указанный переменной окружения ZONEINFO
    2. В Unix-системах - стандартное системное местоположение установки
    3. $GOROOT/lib/time/zoneinfo.zip
    4. Пакет time/tzdata, если он был импортирован
    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	location, err := time.LoadLocation("America/Los_Angeles")
    	if err != nil {
    		panic(err)
    	}
    
    	timeInUTC := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC)
    	fmt.Println(timeInUTC.In(location))
    }
    
    Output:
    
    2018-08-30 05:00:00 -0700 PDT

    func LoadLocationFromTZData

    func LoadLocationFromTZData(name string, data []byte) (*Location, error)
    

    LoadLocationFromTZData возвращает Location с заданным именем, инициализированный из данных в формате базы данных часовых поясов IANA. Данные должны быть в формате стандартного файла часового пояса IANA (например, содержимое /etc/localtime в Unix-системах).

    func (*Location) String

    func (l *Location) String() string
    

    String возвращает описательное имя для информации о часовом поясе, соответствующее аргументу name для LoadLocation или FixedZone.

    type Month

    type Month int
    

    Month определяет месяц года (January = 1, …).

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	_, month, day := time.Now().Date()
    	if month == time.November && day == 10 {
    		fmt.Println("Happy Go day!")
    	}
    }
    

    Константы:

    const (
    	January Month = 1 + iota
    	February
    	March
    	April
    	May
    	June
    	July
    	August
    	September
    	October
    	November
    	December
    )
    

    func (Month) String

    func (m Month) String() string
    

    String возвращает английское название месяца (“January”, “February”, …).

    type ParseError

    type ParseError struct {
    	Layout     string
    	Value      string
    	LayoutElem string
    	ValueElem  string
    	Message    string
    }
    

    ParseError описывает проблему при разборе строки времени.

    func (*ParseError) Error

    func (e *ParseError) Error() string
    

    Error возвращает строковое представление ParseError.

    type Ticker

    type Ticker struct {
    	C <-chan Time // Канал, по которому доставляются "тики"
    	// содержит неэкспортируемые поля
    }
    

    Ticker содержит канал, который доставляет “тики” часов с заданными интервалами.

    func NewTicker

    func NewTicker(d Duration) *Ticker
    

    NewTicker создает новый Ticker, содержащий канал, который будет отправлять текущее время на канал после каждого тика. Период тиков задается аргументом duration. Ticker будет корректировать интервал времени или пропускать тики для компенсации медленных получателей. Длительность d должна быть больше нуля; в противном случае NewTicker вызовет панику.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	ticker := time.NewTicker(time.Second)
    	defer ticker.Stop()
    	done := make(chan bool)
    	go func() {
    		time.Sleep(10 * time.Second)
    		done <- true
    	}()
    	for {
    		select {
    		case <-done:
    			fmt.Println("Done!")
    			return
    		case t := <-ticker.C:
    			fmt.Println("Current time: ", t)
    		}
    	}
    }
    

    func (*Ticker) Reset

    func (t *Ticker) Reset(d Duration)
    

    Reset останавливает тикер и устанавливает его период в заданную продолжительность. Следующий тик придет после истечения нового периода. Длительность d должна быть больше нуля; в противном случае Reset вызовет панику.

    func (*Ticker) Stop

    func (t *Ticker) Stop()
    

    Stop выключает тикер. После Stop больше не будет отправляться тиков. Stop не закрывает канал, чтобы предотвратить ошибочное чтение “тика” параллельной горутиной.

    type Time

    type Time struct {
    	// содержит неэкспортируемые поля
    }
    

    Time представляет момент времени с наносекундной точностью.

    Программы, использующие время, обычно должны хранить и передавать его как значения, а не указатели. То есть переменные времени и поля структур должны быть типа time.Time, а не *time.Time.

    Значение Time может использоваться несколькими горутинами одновременно, за исключением того, что методы Time.GobDecode, Time.UnmarshalBinary, Time.UnmarshalJSON и Time.UnmarshalText не являются безопасными для конкурентного использования.

    Моменты времени можно сравнивать с помощью методов Time.Before, Time.After и Time.Equal. Метод Time.Sub вычитает два момента, производя Duration. Метод Time.Add добавляет Time и Duration, производя Time.

    Нулевое значение типа Time - January 1, year 1, 00:00:00.000000000 UTC. Поскольку это время вряд ли встретится на практике, метод Time.IsZero дает простой способ обнаружения времени, которое не было инициализировано явно.

    Каждое время имеет связанный Location. Методы Time.Local, Time.UTC и Time.In возвращают Time с конкретным Location. Изменение Location значения Time с помощью этих методов не изменяет фактический момент, который оно представляет, только часовой пояс, в котором оно интерпретируется.

    func Date

    func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
    

    Date возвращает Time, соответствующее

    yyyy-mm-dd hh:mm:ss + nsec наносекунд
    

    в соответствующем часовом поясе для этого времени в заданном местоположении.

    Значения month, day, hour, min, sec и nsec могут быть вне их обычных диапазонов и будут нормализованы во время преобразования. Например, 32 октября преобразуется в 1 ноября.

    Переход на летнее время пропускает или повторяет моменты времени. Например, в США March 13, 2011 2:15am никогда не происходило, а November 6, 2011 1:15am произошло дважды. В таких случаях выбор часового пояса, а следовательно и времени, не определен однозначно. Date возвращает время, которое корректно в одном из двух участвующих в переходе часовых поясов, но не гарантирует, в каком именно.

    Date вызывает панику, если loc равен nil.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
    	fmt.Printf("Go launched at %s\n", t.Local())
    }
    
    Output:
    
    Go launched at 2009-11-10 15:00:00 -0800 PST

    func Now

    func Now() Time
    

    Now возвращает текущее локальное время.

    func Parse

    func Parse(layout, value string) (Time, error)
    

    Parse разбирает форматированную строку и возвращает значение времени, которое она представляет. Смотрите документацию для константы Layout, чтобы понять, как представить формат. Второй аргумент должен быть разбираемым с использованием строки формата (layout), предоставленной в качестве первого аргумента.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	// Пример с Time.Format содержит подробное описание того, как
    	// определять строку формата для разбора значения time.Time;
    	// Parse и Format используют одну и ту же модель для описания
    	// входных и выходных данных.
    
    	// longForm демонстрирует на примере, как эталонное время будет представлено
    	// в желаемом формате.
    	const longForm = "Jan 2, 2006 at 3:04pm (MST)"
    	t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
    	fmt.Println(t)
    
    	// shortForm - это альтернативный способ представления эталонного времени
    	// в желаемом формате; он не содержит информации о часовом поясе.
    	// Примечание: без явного указания пояса возвращает время в UTC.
    	const shortForm = "2006-Jan-02"
    	t, _ = time.Parse(shortForm, "2013-Feb-03")
    	fmt.Println(t)
    
    	// Некоторые допустимые форматы могут быть недопустимыми значениями времени,
    	// из-за спецификаторов формата, таких как _ для заполнения пробелами
    	// и Z для информации о часовом поясе.
    	// Например, формат RFC3339 2006-01-02T15:04:05Z07:00
    	// содержит как Z, так и смещение часового пояса, чтобы обрабатывать оба варианта:
    	// 2006-01-02T15:04:05Z
    	// 2006-01-02T15:04:05+07:00
    	t, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
    	fmt.Println(t)
    	t, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05+07:00")
    	fmt.Println(t)
    	_, err := time.Parse(time.RFC3339, time.RFC3339)
    	fmt.Println("ошибка", err) // Возвращает ошибку, так как формат не является допустимым значением времени
    }
    Output:
    
    2013-02-03 19:54:00 -0800 PST
    2013-02-03 00:00:00 +0000 UTC
    2006-01-02 15:04:05 +0000 UTC
    2006-01-02 15:04:05 +0700 +0700
    error parsing time "2006-01-02T15:04:05Z07:00": extra text: "07:00"

    func ParseInLocation

    func ParseInLocation(layout, value string, loc *Location) (Time, error)
    

    ParseInLocation похож на Parse, но отличается в двух важных аспектах. Во-первых, при отсутствии информации о часовом поясе Parse интерпретирует время как UTC; ParseInLocation интерпретирует время как в заданном местоположении. Во-вторых, при заданном смещении или аббревиатуре часового пояса Parse пытается сопоставить его с местоположением Local; ParseInLocation использует заданное местоположение.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	loc, _ := time.LoadLocation("Europe/Berlin")
    
    	// This will look for the name CEST in the Europe/Berlin time zone.
    	const longForm = "Jan 2, 2006 at 3:04pm (MST)"
    	t, _ := time.ParseInLocation(longForm, "Jul 9, 2012 at 5:02am (CEST)", loc)
    	fmt.Println(t)
    
    	// Note: without explicit zone, returns time in given location.
    	const shortForm = "2006-Jan-02"
    	t, _ = time.ParseInLocation(shortForm, "2012-Jul-09", loc)
    	fmt.Println(t)
    
    }
    
    Output:
    
    2012-07-09 05:02:00 +0200 CEST
    2012-07-09 00:00:00 +0200 CEST

    func Unix

    func Unix(sec int64, nsec int64) Time
    

    Unix возвращает локальное Time, соответствующее заданному Unix-времени, sec секунд и nsec наносекунд с 1 января 1970 UTC. Допустимо передавать nsec вне диапазона [0, 999999999]. Не все значения sec имеют соответствующее значение времени. Одним из таких значений является 1«63-1 (максимальное значение int64).

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	unixTime := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
    	fmt.Println(unixTime.Unix())
    	t := time.Unix(unixTime.Unix(), 0).UTC()
    	fmt.Println(t)
    
    }
    Output:
    
    1257894000
    2009-11-10 23:00:00 +0000 UTC

    func UnixMicro

    func UnixMicro(usec int64) Time
    

    UnixMicro возвращает локальное Time, соответствующее заданному Unix-времени, usec микросекунд с 1 января 1970 UTC.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	umt := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
    	fmt.Println(umt.UnixMicro())
    	t := time.UnixMicro(umt.UnixMicro()).UTC()
    	fmt.Println(t)
    
    }
    
    Output:
    
    1257894000000000
    2009-11-10 23:00:00 +0000 UTC

    func UnixMilli

    func UnixMilli(msec int64) Time
    

    UnixMilli возвращает локальное Time, соответствующее заданному Unix-времени, msec миллисекунд с 1 января 1970 UTC.

    func (Time) Add

    func (t Time) Add(d Duration) Time
    

    Add возвращает время t+d.

    Пример
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	start := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
    	afterTenSeconds := start.Add(time.Second * 10)
    	afterTenMinutes := start.Add(time.Minute * 10)
    	afterTenHours := start.Add(time.Hour * 10)
    	afterTenDays := start.Add(time.Hour * 24 * 10)
    
    	fmt.Printf("start = %v\n", start)
    	fmt.Printf("start.Add(time.Second * 10) = %v\n", afterTenSeconds)
    	fmt.Printf("start.Add(time.Minute * 10) = %v\n", afterTenMinutes)
    	fmt.Printf("start.Add(time.Hour * 10) = %v\n", afterTenHours)
    	fmt.Printf("start.Add(time.Hour * 24 * 10) = %v\n", afterTenDays)
    
    }
    Output:
    
    start = 2009-01-01 12:00:00 +0000 UTC
    start.Add(time.Second * 10) = 2009-01-01 12:00:10 +0000 UTC
    start.Add(time.Minute * 10) = 2009-01-01 12:10:00 +0000 UTC
    start.Add(time.Hour * 10) = 2009-01-01 22:00:00 +0000 UTC
    start.Add(time.Hour * 24 * 10) = 2009-01-11 12:00:00 +0000 UTC

    func (Time) AddDate

    func (t Time) AddDate(years int, months int, days int) Time
    

    AddDate возвращает время, соответствующее добавлению заданного количества лет, месяцев и дней к t. Например, AddDate(-1, 2, 3), примененное к 1 января 2011, возвращает 4 марта 2010.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	start := time.Date(2023, 03, 25, 12, 0, 0, 0, time.UTC)
    	oneDayLater := start.AddDate(0, 0, 1)
    	dayDuration := oneDayLater.Sub(start)
    	oneMonthLater := start.AddDate(0, 1, 0)
    	oneYearLater := start.AddDate(1, 0, 0)
    
    	zurich, err := time.LoadLocation("Europe/Zurich")
    	if err != nil {
    		panic(err)
    	}
    	// This was the day before a daylight saving time transition in Zürich.
    	startZurich := time.Date(2023, 03, 25, 12, 0, 0, 0, zurich)
    	oneDayLaterZurich := startZurich.AddDate(0, 0, 1)
    	dayDurationZurich := oneDayLaterZurich.Sub(startZurich)
    
    	fmt.Printf("oneDayLater: start.AddDate(0, 0, 1) = %v\n", oneDayLater)
    	fmt.Printf("oneMonthLater: start.AddDate(0, 1, 0) = %v\n", oneMonthLater)
    	fmt.Printf("oneYearLater: start.AddDate(1, 0, 0) = %v\n", oneYearLater)
    	fmt.Printf("oneDayLaterZurich: startZurich.AddDate(0, 0, 1) = %v\n", oneDayLaterZurich)
    	fmt.Printf("Day duration in UTC: %v | Day duration in Zürich: %v\n", dayDuration, dayDurationZurich)
    
    }
    
    
    Output:
    
    oneDayLater: start.AddDate(0, 0, 1) = 2023-03-26 12:00:00 +0000 UTC
    oneMonthLater: start.AddDate(0, 1, 0) = 2023-04-25 12:00:00 +0000 UTC
    oneYearLater: start.AddDate(1, 0, 0) = 2024-03-25 12:00:00 +0000 UTC
    oneDayLaterZurich: startZurich.AddDate(0, 0, 1) = 2023-03-26 12:00:00 +0200 CEST
    Day duration in UTC: 24h0m0s | Day duration in Zürich: 23h0m0s

    func (Time) After

    func (t Time) After(u Time) bool
    

    After сообщает, является ли момент времени t после u.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	year2000 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
    	year3000 := time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)
    
    	isYear3000AfterYear2000 := year3000.After(year2000) // True
    	isYear2000AfterYear3000 := year2000.After(year3000) // False
    
    	fmt.Printf("year3000.After(year2000) = %v\n", isYear3000AfterYear2000)
    	fmt.Printf("year2000.After(year3000) = %v\n", isYear2000AfterYear3000)
    
    }
    
    Output:
    
    year3000.After(year2000) = true
    year2000.After(year3000) = false

    func (Time) AppendBinary

    func (t Time) AppendBinary(b []byte) ([]byte, error)
    

    AppendBinary реализует интерфейс encoding.BinaryAppender. Добавляет бинарное представление времени в срез байт b и возвращает расширенный буфер.

    func (Time) AppendFormat

    func (t Time) AppendFormat(b []byte, layout string) []byte
    

    AppendFormat аналогичен Time.Format, но добавляет текстовое представление времени в буфер b и возвращает расширенный буфер. Формат определяется параметром layout.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	t := time.Date(2017, time.November, 4, 11, 0, 0, 0, time.UTC)
    	text := []byte("Time: ")
    
    	text = t.AppendFormat(text, time.Kitchen)
    	fmt.Println(string(text))
    
    }
    Output:
    
    Time: 11:00AM

    func (Time) AppendText

    func (t Time) AppendText(b []byte) ([]byte, error)
    

    AppendText реализует интерфейс encoding.TextAppender. Форматирует время в формате RFC 3339 с субсекундной точностью и добавляет в буфер b. Возвращает ошибку, если время невозможно представить в корректном формате RFC 3339 (например, при выходе года за допустимый диапазон).

    func (Time) Before

    func (t Time) Before(u Time) bool
    

    Before сообщает, является ли момент времени t до u.

    Пример
    ackage main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	year2000 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
    	year3000 := time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)
    
    	isYear2000BeforeYear3000 := year2000.Before(year3000) // True
    	isYear3000BeforeYear2000 := year3000.Before(year2000) // False
    
    	fmt.Printf("year2000.Before(year3000) = %v\n", isYear2000BeforeYear3000)
    	fmt.Printf("year3000.Before(year2000) = %v\n", isYear3000BeforeYear2000)
    
    }
    
    Output:
    
    year2000.Before(year3000) = true
    year3000.Before(year2000) = false

    func (Time) Clock

    func (t Time) Clock() (hour, min, sec int)
    

    Clock возвращает час, минуту и секунду в пределах дня, указанного t.

    func (Time) Compare

    func (t Time) Compare(u Time) int
    

    Compare сравнивает момент времени t с u. Если t до u, возвращает -1; если t после u, возвращает +1; если они одинаковы, возвращает 0.

    func (Time) Date

    func (t Time) Date() (year int, month Month, day int)
    

    Date возвращает год, месяц и день, в которые происходит t.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	d := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
    	year, month, day := d.Date()
    
    	fmt.Printf("year = %v\n", year)
    	fmt.Printf("month = %v\n", month)
    	fmt.Printf("day = %v\n", day)
    
    }
    Output:
    
    year = 2000
    month = February
    day = 1

    func (Time) Day

    func (t Time) Day() int
    

    Day возвращает день месяца, указанный t.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	d := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
    	day := d.Day()
    
    	fmt.Printf("day = %v\n", day)
    
    }
    
    Output:
    
    day = 1

    func (Time) Equal

    func (t Time) Equal(u Time) bool
    

    Equal сообщает, представляют ли t и u один и тот же момент времени. Два времени могут быть равны, даже если они находятся в разных местоположениях. Например, 6:00 +0200 и 4:00 UTC равны.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	secondsEastOfUTC := int((8 * time.Hour).Seconds())
    	beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
    
    	// Unlike the equal operator, Equal is aware that d1 and d2 are the
    	// same instant but in different time zones.
    	d1 := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
    	d2 := time.Date(2000, 2, 1, 20, 30, 0, 0, beijing)
    
    	datesEqualUsingEqualOperator := d1 == d2
    	datesEqualUsingFunction := d1.Equal(d2)
    
    	fmt.Printf("datesEqualUsingEqualOperator = %v\n", datesEqualUsingEqualOperator)
    	fmt.Printf("datesEqualUsingFunction = %v\n", datesEqualUsingFunction)
    
    }
    
    Output:
    
    datesEqualUsingEqualOperator = false
    datesEqualUsingFunction = true

    func (Time) Format

    func (t Time) Format(layout string) string
    

    Format возвращает текстовое представление значения времени, отформатированное согласно layout. Смотрите документацию для константы Layout, чтобы понять, как представить формат.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	// Разбираем строку времени в стандартном Unix формате
    	t, err := time.Parse(time.UnixDate, "Wed Feb 25 11:06:39 PST 2015")
    	if err != nil { // Всегда проверяем ошибки, даже если они не должны возникать
    		panic(err)
    	}
    
    	tz, err := time.LoadLocation("Asia/Shanghai")
    	if err != nil { // Всегда проверяем ошибки
    		panic(err)
    	}
    
    	// Метод Stringer типа time.Time удобен для вывода без указания формата
    	fmt.Println("формат по умолчанию:", t)
    
    	// Предопределенные константы пакета реализуют распространенные форматы
    	fmt.Println("Unix формат:", t.Format(time.UnixDate))
    
    	// Часовой пояс, связанный со значением времени, влияет на его вывод
    	fmt.Println("То же время в UTC:", t.UTC().Format(time.UnixDate))
    
    	fmt.Println("в Шанхае с секундами:", t.In(tz).Format("2006-01-02T15:04:05 -070000"))
    
    	fmt.Println("в Шанхае с секундами и двоеточиями:", t.In(tz).Format("2006-01-02T15:04:05 -07:00:00"))
    
    	// Оставшаяся часть функции демонстрирует свойства
    	// строки формата, используемой в Format
    
    	// Строка формата, используемая функциями Parse и Format,
    	// на примере показывает, как должно быть представлено эталонное время.
    	// Важно подчеркнуть, что нужно показывать, как форматируется именно эталонное время,
    	// а не произвольное время пользователя. Таким образом, каждая строка формата -
    	// это представление временной метки:
    	//	Jan 2 15:04:05 2006 MST
    	// Простой способ запомнить это значение - заметить, что при таком порядке
    	// оно содержит следующие значения (соответствующие элементам выше):
    	//	  1 2  3  4  5    6  -7
    	// Ниже показаны некоторые особенности.
    
    	// Большинство использований Format и Parse применяют константные строки формата,
    	// такие как определенные в этом пакете, но интерфейс гибкий,
    	// как показывают следующие примеры.
    
    	// Вспомогательная функция для красивого вывода примеров
    	do := func(name, layout, want string) {
    		got := t.Format(layout)
    		if want != got {
    			fmt.Printf("ошибка: для %q получено %q; ожидалось %q\n", layout, got, want)
    			return
    		}
    		fmt.Printf("%-16s %q дает %q\n", name, layout, got)
    	}
    
    	// Заголовок для вывода
    	fmt.Printf("\nФорматы:\n\n")
    
    	// Простые начальные примеры
    	do("Полная дата", "Mon Jan 2 15:04:05 MST 2006", "Wed Feb 25 11:06:39 PST 2015")
    	do("Краткая дата", "2006/01/02", "2015/02/25")
    
    	// Час эталонного времени - 15 (3PM). Формат может выражать это
    	// любым способом, и так как наше значение утреннее, мы должны видеть его
    	// в AM-формате. Покажем оба варианта в одной строке формата. И в нижнем регистре.
    	do("AM/PM", "3PM==3pm==15h", "11AM==11am==11h")
    
    	// При разборе, если за секундами следует точка
    	// и цифры, это воспринимается как доля секунды, даже если
    	// строка формата не включает представление долей секунды.
    	// Добавим доли секунды к нашему значению времени
    	t, err = time.Parse(time.UnixDate, "Wed Feb 25 11:06:39.1234 PST 2015")
    	if err != nil {
    		panic(err)
    	}
    	// Доли секунды не отображаются, если строка формата не содержит
    	// их представления
    	do("Без долей секунды", time.UnixDate, "Wed Feb 25 11:06:39 PST 2015")
    
    	// Доли секунды можно вывести, добавив последовательность 0 или 9
    	// после точки в значении секунд в строке формата.
    	// Если используются 0, выводится указанное количество знаков.
    	// Обратите внимание, что вывод содержит завершающий ноль.
    	do("0 для долей секунды", "15:04:05.00000", "11:06:39.12340")
    
    	// Если используются 9, завершающие нули отбрасываются.
    	do("9 для долей секунды", "15:04:05.99999999", "11:06:39.1234")
    }
    формат по умолчанию: 2015-02-25 11:06:39 -0800 PST
    Unix формат: Wed Feb 25 11:06:39 PST 2015
    То же время в UTC: Wed Feb 25 19:06:39 UTC 2015
    в Шанхае с секундами: 2015-02-26T03:06:39 +080000
    в Шанхае с секундами и двоеточиями: 2015-02-26T03:06:39 +08:00:00
    
    Форматы:
    
    Полная дата       "Mon Jan 2 15:04:05 MST 2006" дает "Wed Feb 25 11:06:39 PST 2015"
    Краткая дата      "2006/01/02" дает "2015/02/25"
    AM/PM             "3PM==3pm==15h" дает "11AM==11am==11h"
    Без долей секунды "Mon Jan _2 15:04:05 MST 2006" дает "Wed Feb 25 11:06:39 PST 2015"
    0 для долей секунды "15:04:05.00000" дает "11:06:39.12340"
    9 для долей секунды "15:04:05.99999999" дает "11:06:39.1234"
    Пример (Pad)
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	// Разбор строки времени в стандартном Unix формате
    	t, err := time.Parse(time.UnixDate, "Sat Mar 7 11:06:39 PST 2015")
    	if err != nil { // Всегда проверяем ошибки, даже если они маловероятны
    		panic(err)
    	}
    
    	// Вспомогательная функция для форматированного вывода примеров
    	do := func(name, layout, want string) {
    		got := t.Format(layout)
    		if want != got {
    			fmt.Printf("ошибка: для формата %q получено %q; ожидалось %q\n", layout, got, want)
    			return
    		}
    		fmt.Printf("%-16s %q → %q\n", name, layout, got)
    	}
    
    	// Предопределенная константа Unix использует подчеркивание для выравнивания дня
    	do("Unix формат", time.UnixDate, "Sat Mar  7 11:06:39 PST 2015")
    
    	// Для выравнивания значений переменной ширины (например, дня месяца)
    	// используйте _ вместо пробела в строке формата
    	do("Без выравнивания", "<2>", "<7>")
    
    	// Подчеркивание добавляет пробел для однозначных чисел
    	do("С пробелом", "<_2>", "< 7>")
    
    	// "0" добавляет нулевое заполнение для однозначных чисел
    	do("С нулями", "<02>", "<07>")
    
    	// Если значение уже имеет нужную ширину, заполнение не применяется
    	// Например, секунды (39) не требуют заполнения, а минуты (06) - требуют
    	do("Пропуск заполнения", "04:05", "06:39")
    }
    Unix формат       "Mon Jan _2 15:04:05 MST 2006""Sat Mar  7 11:06:39 PST 2015"
    Без выравнивания "<2>""<7>"
    С пробелом       "<_2>""< 7>"
    С нулями         "<02>""<07>"
    Пропуск заполнения "04:05""06:39"

    func (Time) GoString

    func (t Time) GoString() string
    

    GoString реализует fmt.GoStringer и форматирует t для вывода в исходном коде Go.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
    	fmt.Println(t.GoString())
    	t = t.Add(1 * time.Minute)
    	fmt.Println(t.GoString())
    	t = t.AddDate(0, 1, 0)
    	fmt.Println(t.GoString())
    	t, _ = time.Parse("Jan 2, 2006 at 3:04pm (MST)", "Feb 3, 2013 at 7:54pm (UTC)")
    	fmt.Println(t.GoString())
    
    }
    
    Output:
    
    time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
    time.Date(2009, time.November, 10, 23, 1, 0, 0, time.UTC)
    time.Date(2009, time.December, 10, 23, 1, 0, 0, time.UTC)
    time.Date(2013, time.February, 3, 19, 54, 0, 0, time.UTC)

    func (*Time) GobDecode

    func (t *Time) GobDecode(data []byte) error
    

    GobDecode реализует интерфейс gob.GobDecoder.

    func (Time) GobEncode

    func (t Time) GobEncode() ([]byte, error)
    

    GobEncode реализует интерфейс gob.GobEncoder.

    func (Time) Hour

    func (t Time) Hour() int
    

    Hour возвращает час в пределах дня, указанного t, в диапазоне [0, 23].

    func (Time) ISOWeek

    func (t Time) ISOWeek() (year, week int)
    

    ISOWeek возвращает год и номер недели ISO 8601, в которые происходит t. Неделя находится в диапазоне от 1 до 53. 1-3 января года n могут принадлежать 52 или 53 неделе года n-1, а 29-31 декабря могут принадлежать 1 неделе года n+1.

    func (Time) In

    func (t Time) In(loc *Location) Time
    

    In возвращает копию t, представляющую тот же момент времени, но с информацией о местоположении, установленной в loc для целей отображения.

    In вызывает панику, если loc равен nil.

    func (Time) IsDST

    func (t Time) IsDST() bool
    

    IsDST сообщает, находится ли время в настроенном местоположении в летнем времени.

    func (Time) IsZero

    func (t Time) IsZero() bool
    

    IsZero сообщает, представляет ли t нулевой момент времени, 1 января, год 1, 00:00:00 UTC.

    func (Time) Local

    func (t Time) Local() Time
    

    Local возвращает t с местоположением, установленным в локальное время.

    func (Time) Location

    func (t Time) Location() *Location
    

    Location возвращает информацию о часовом поясе, связанную с t.

    func (Time) MarshalBinary

    func (t Time) MarshalBinary() ([]byte, error)
    

    MarshalBinary реализует интерфейс encoding.BinaryMarshaler.

    func (Time) MarshalJSON

    func (t Time) MarshalJSON() ([]byte, error)
    

    MarshalJSON реализует интерфейс encoding/json.Marshaler. Время — это строка в формате RFC 3339 с точностью до секунды. Если временная метка не может быть представлена ​​как допустимая RFC 3339 (например, год выходит за пределы диапазона), то выдается сообщение об ошибке.

    func (Time) MarshalText

    func (t Time) MarshalText() ([]byte, error)
    

    MarshalText реализует интерфейс encoding.TextMarshaler. Вывод соответствует вызову метода Time.AppendText.

    См. Time.AppendText для получения дополнительной информации.

    func (Time) Minute

    func (t Time) Minute() int
    

    Minute возвращает минуту в пределах часа, указанного t, в диапазоне [0, 59].

    func (Time) Month

    func (t Time) Month() Month
    

    Month возвращает месяц года, указанный t.

    func (Time) Nanosecond

    func (t Time) Nanosecond() int
    

    Nanosecond возвращает наносекунду в пределах секунды, указанной t, в диапазоне [0, 999999999].

    func (Time) Round

    func (t Time) Round(d Duration) Time
    

    Round возвращает результат округления t до ближайшего кратного d (с нулевого времени). При округлении половинных значений округление выполняется от нуля. Если d <= 0, Round возвращает t, лишенное любого монотонного показания часов, но в остальном неизменное.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	t := time.Date(0, 0, 0, 12, 15, 30, 918273645, time.UTC)
    	round := []time.Duration{
    		time.Nanosecond,
    		time.Microsecond,
    		time.Millisecond,
    		time.Second,
    		2 * time.Second,
    		time.Minute,
    		10 * time.Minute,
    		time.Hour,
    	}
    
    	for _, d := range round {
    		fmt.Printf("t.Round(%6s) = %s\n", d, t.Round(d).Format("15:04:05.999999999"))
    	}
    }
    
    Output:
    
    t.Round(   1ns) = 12:15:30.918273645
    t.Round(   1µs) = 12:15:30.918274
    t.Round(   1ms) = 12:15:30.918
    t.Round(    1s) = 12:15:31
    t.Round(    2s) = 12:15:30
    t.Round(  1m0s) = 12:16:00
    t.Round( 10m0s) = 12:20:00
    t.Round(1h0m0s) = 12:00:00

    func (Time) Second

    func (t Time) Second() int
    

    Second возвращает секунду в пределах минуты, указанной t, в диапазоне [0, 59].

    func (Time) String

    func (t Time) String() string
    

    String возвращает время, отформатированное с использованием строки формата

    "2006-01-02 15:04:05.999999999 -0700 MST"
    

    Если время имеет монотонное показание часов, возвращаемая строка включает конечное поле “m=±”, где value - монотонное показание часов, отформатированное как десятичное число секунд.

    Пример
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	timeWithNanoseconds := time.Date(2000, 2, 1, 12, 13, 14, 15, time.UTC)
    	withNanoseconds := timeWithNanoseconds.String()
    
    	timeWithoutNanoseconds := time.Date(2000, 2, 1, 12, 13, 14, 0, time.UTC)
    	withoutNanoseconds := timeWithoutNanoseconds.String()
    
    	fmt.Printf("withNanoseconds = %v\n", string(withNanoseconds))
    	fmt.Printf("withoutNanoseconds = %v\n", string(withoutNanoseconds))
    
    }
    Output:
    
    withNanoseconds = 2000-02-01 12:13:14.000000015 +0000 UTC
    withoutNanoseconds = 2000-02-01 12:13:14 +0000 UTC

    func (Time) Sub

    func (t Time) Sub(u Time) Duration
    

    Sub возвращает продолжительность t-u. Если результат превышает максимальное (или минимальное) значение, которое может храниться в Duration, будет возвращена максимальная (или минимальная) продолжительность.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	start := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
    	end := time.Date(2000, 1, 1, 12, 0, 0, 0, time.UTC)
    
    	difference := end.Sub(start)
    	fmt.Printf("difference = %v\n", difference)
    
    }
    
    Output:
    
    difference = 12h0m0s

    func (Time) Truncate

    func (t Time) Truncate(d Duration) Time
    

    Truncate возвращает результат округления t вниз до кратного d (с нулевого времени). Если d <= 0, Truncate возвращает t, лишенное любого монотонного показания часов, но в остальном неизменное.

    Пример
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	t, _ := time.Parse("2006 Jan 02 15:04:05", "2012 Dec 07 12:15:30.918273645")
    	trunc := []time.Duration{
    		time.Nanosecond,
    		time.Microsecond,
    		time.Millisecond,
    		time.Second,
    		2 * time.Second,
    		time.Minute,
    		10 * time.Minute,
    	}
    
    	for _, d := range trunc {
    		fmt.Printf("t.Truncate(%5s) = %s\n", d, t.Truncate(d).Format("15:04:05.999999999"))
    	}
    	// To round to the last midnight in the local timezone, create a new Date.
    	midnight := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.Local)
    	_ = midnight
    
    }
    Output:
    
    t.Truncate(  1ns) = 12:15:30.918273645
    t.Truncate(  1µs) = 12:15:30.918273
    t.Truncate(  1ms) = 12:15:30.918
    t.Truncate(   1s) = 12:15:30
    t.Truncate(   2s) = 12:15:30
    t.Truncate( 1m0s) = 12:15:00
    t.Truncate(10m0s) = 12:10:00

    func (Time) UTC

    func (t Time) UTC() Time
    

    UTC возвращает t с местоположением, установленным в UTC.

    func (Time) Unix

    func (t Time) Unix() int64
    

    Unix возвращает t как Unix-время, количество секунд, прошедших с 1 января 1970 UTC. Результат не зависит от местоположения, связанного с t.

    Пример
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	// 1 billion seconds of Unix, three ways.
    	fmt.Println(time.Unix(1e9, 0).UTC())     // 1e9 seconds
    	fmt.Println(time.Unix(0, 1e18).UTC())    // 1e18 nanoseconds
    	fmt.Println(time.Unix(2e9, -1e18).UTC()) // 2e9 seconds - 1e18 nanoseconds
    
    	t := time.Date(2001, time.September, 9, 1, 46, 40, 0, time.UTC)
    	fmt.Println(t.Unix())     // seconds since 1970
    	fmt.Println(t.UnixNano()) // nanoseconds since 1970
    
    }
    Output:
    
    2001-09-09 01:46:40 +0000 UTC
    2001-09-09 01:46:40 +0000 UTC
    2001-09-09 01:46:40 +0000 UTC
    1000000000
    1000000000000000000

    func (Time) UnixMicro

    func (t Time) UnixMicro() int64
    

    UnixMicro возвращает t как Unix-время, количество микросекунд, прошедших с 1 января 1970 UTC.

    func (Time) UnixMilli

    func (t Time) UnixMilli() int64
    

    UnixMilli возвращает t как Unix-время, количество миллисекунд, прошедших с 1 января 1970 UTC.

    func (Time) UnixNano

    func (t Time) UnixNano() int64
    

    UnixNano возвращает t как Unix-время, количество наносекунд, прошедших с 1 января 1970 UTC.

    func (*Time) UnmarshalBinary

    func (t *Time) UnmarshalBinary(data []byte) error
    

    UnmarshalBinary реализует интерфейс encoding.BinaryUnmarshaler.

    func (*Time) UnmarshalJSON

    func (t *Time) UnmarshalJSON(data []byte) error
    

    UnmarshalJSON реализует интерфейс encoding/json.Unmarshaler. Время должно быть строкой в ​​кавычках в формате RFC 3339.

    func (*Time) UnmarshalText

    func (t *Time) UnmarshalText(data []byte) error
    

    UnmarshalText реализует интерфейс encoding.TextUnmarshaler. Время должно быть в формате RFC 3339.

    func (Time) Weekday

    func (t Time) Weekday() Weekday
    

    Weekday возвращает день недели, указанный t.

    func (Time) Year

    func (t Time) Year() int
    

    Year возвращает год, в который происходит t.

    func (Time) YearDay

    func (t Time) YearDay() int
    

    YearDay возвращает день года, указанный t, в диапазоне [1,365] для невисокосных лет и [1,366] в високосных годах.

    func (Time) Zone

    func (t Time) Zone() (name string, offset int)
    

    Zone вычисляет часовой пояс, действующий в момент времени t, возвращая сокращенное название пояса (например, “CET”) и его смещение в секундах к востоку от UTC.

    func (Time) ZoneBounds

    func (t Time) ZoneBounds() (start, end Time)
    

    ZoneBounds возвращает границы часового пояса, действующего в момент времени t. Пояс начинается в start, а следующий пояс начинается в end. Если пояс начинается в начале времен, start будет возвращен как нулевое Time. Если пояс продолжается вечно, end будет возвращен как нулевое Time. Местоположение возвращаемых времен будет таким же, как у t.

    type Timer

    type Timer struct {
    	C <-chan Time
    	// содержит неэкспортируемые поля
    }
    

    Timer представляет единичное событие. Когда Timer истекает, текущее время будет отправлено на C, если только Timer не был создан с помощью AfterFunc. Timer должен быть создан с помощью NewTimer или AfterFunc.

    func AfterFunc

    func AfterFunc(d Duration, f func()) *Timer
    

    AfterFunc ждет истечения продолжительности, а затем вызывает f в своей собственной горутине. Возвращает Timer, который можно использовать для отмены вызова с помощью его метода Stop. Поле C возвращаемого Timer не используется и будет nil.

    func NewTimer

    func NewTimer(d Duration) *Timer
    

    NewTimer создает новый Timer, который отправит текущее время на свой канал после как минимум продолжительности d.

    func (*Timer) Reset

    func (t *Timer) Reset(d Duration) bool
    

    Reset изменяет таймер на истечение после продолжительности d. Возвращает true, если таймер был активен, false, если таймер уже истек или был остановлен.

    func (t *Timer) Reset(d Duration) bool
    

    Reset изменяет таймер для срабатывания через интервал d. Возвращает true, если таймер был активен, и false, если таймер уже сработал или был остановлен.

    Для функционального таймера, созданного через AfterFunc(d, f):

    • Reset либо переносит время выполнения f (возвращает true)
    • либо планирует новое выполнение f (возвращает false)

    При возврате false:

    • Reset не ожидает завершения предыдущего выполнения f
    • Не гарантируется отсутствие конкурентного выполнения предыдущей и новой версий f
    • Для контроля завершения нужно реализовать собственную синхронизацию

    Для канального таймера (создан через NewTimer), начиная с Go 1.23:

    • Гарантируется, что после Reset канал t.C не получит значений от предыдущих настроек
    • Если программа еще не читала из t.C и таймер активен, Reset гарантированно вернет true

    До Go 1.23 безопасное использование требовало:

    1. Вызова Timer.Stop()
    2. Явного чтения из канала (если Stop вернула false)

    func (*Timer) Stop

    func (t *Timer) Stop() bool
    

    Stop предотвращает срабатывание таймера. Возвращает:

    • true - если таймер был успешно остановлен
    • false - если таймер уже сработал или был остановлен

    Для функционального таймера (AfterFunc):

    • При false функция f уже запущена в отдельной горутине
    • Stop не ожидает завершения f
    • Для контроля завершения нужна дополнительная синхронизация

    Для канального таймера (Go 1.23+):

    • После Stop чтение из t.C гарантированно блокируется
    • Не будет получено “устаревших” значений времени
    • Если таймер активен и канал не читался, Stop гарантированно вернет true

    До Go 1.23 требовалось:

    • При false выполнять дополнительное чтение <-t.C для очистки канала

    type Weekday

    type Weekday int
    

    Weekday определяет день недели (Sunday = 0, …).

    Константы:

    const (
    	Sunday Weekday = iota
    	Monday
    	Tuesday
    	Wednesday
    	Thursday
    	Friday
    	Saturday
    )
    

    func (Weekday) String

    func (d Weekday) String() string
    

    String возвращает английское название дня (“Sunday”, “Monday”, …).

    Пакет time/tzdata

    Пакет tzdata предоставляет встроенную копию базы данных часовых поясов. Если этот пакет импортируется в любое место программы, то, если пакет времени не может найти файлы tzdata в системе, он будет использовать эту встроенную информацию.

    Импорт этого пакета увеличит размер программы примерно на 450 КБ.

    Обычно этот пакет должен импортироваться основным пакетом программы, а не библиотекой. Библиотеки обычно не должны решать, включать ли базу данных часовых поясов в программу.

    Этот пакет будет автоматически импортирован, если вы построите с -tags timetzdata.