Работа с датами и временем в Go: полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с датами и временем в Go: от основ до продвинутых техник

Язык программирования Go (Golang) предлагает мощный и интуитивно понятный пакет time для работы с датами и временем. В отличие от многих других языков, Go использует уникальный подход к форматированию, основанный на эталонной дате (Mon Jan 2 15:04:05 MST 2006). В этой статье мы подробно разберём все ключевые аспекты: от создания объектов времени до работы с таймерами и временными зонами. Материал будет полезен как новичкам, так и опытным разработчикам, переходящим на Go.

1. Основы: создание, получение и вывод времени

Центральный тип для работы — time.Time. Получить текущий момент можно с помощью time.Now(). Для создания конкретной даты используется time.Date().

package main

import (
    "fmt"
    "time"
)

func main() {
    // Текущее время
    now := time.Now()
    fmt.Println("Сейчас:", now)

    // Создание конкретной даты (год, месяц, день, час, мин, сек, наносек, Location)
    specific := time.Date(2025, time.January, 15, 10, 30, 0, 0, time.UTC)
    fmt.Println("Конкретная дата:", specific)

    // Извлечение компонентов
    fmt.Println("Год:", now.Year())
    fmt.Println("Месяц:", now.Month())
    fmt.Println("День:", now.Day())
    fmt.Println("Час:", now.Hour())
    fmt.Println("Минута:", now.Minute())
    fmt.Println("Секунда:", now.Second())
    fmt.Println("День недели:", now.Weekday())
}

Вывод программы покажет текущее время и его компоненты. Обратите внимание: time.Now() возвращает время в локальной временной зоне системы.

2. Форматирование и парсинг: отличительная особенность Go

В Go форматирование дат происходит не через символы типа YYYY-MM-DD, а через эталонную дату: Mon Jan 2 15:04:05 MST 2006 (или 01/02 03:04:05PM '06 -0700). Запомните эту магическую строку — она выглядит как 1 2 3 4 5 6 -7.

  • 1 — месяц (01, Jan, January)
  • 2 — день (02, 2)
  • 3 — час в 12-часовом формате (03, 3)
  • 4 — минута (04, 4)
  • 5 — секунда (05, 5)
  • 6 — год (06, 2006)
  • -7 — часовой пояс (MST, -0700, -07:00)

Форматирование (Time → String)

now := time.Now()

// Стандартные форматы
fmt.Println(now.Format("2006-01-02 15:04:05"))   // 2025-01-15 10:30:45
fmt.Println(now.Format("02.01.2006"))              // 15.01.2025
fmt.Println(now.Format(time.RFC3339))              // 2025-01-15T10:30:45Z
fmt.Println(now.Format("Mon, 02 Jan 2006 15:04:05 MST")) // Wed, 15 Jan 2025 10:30:45 UTC

Парсинг (String → Time)

// Парсинг строки в time.Time
dateStr := "2025-01-15 10:30:45"
layout := "2006-01-02 15:04:05"
parsedTime, err := time.Parse(layout, dateStr)
if err != nil {
    panic(err)
}
fmt.Println("Распарсено:", parsedTime)

// Парсинг с часовым поясом
dateWithZone := "2025-01-15T10:30:45+03:00"
parsedWithZone, _ := time.Parse(time.RFC3339, dateWithZone)
fmt.Println("С зоной:", parsedWithZone)

Если вам нужно распарсить дату в определённой временной зоне, используйте time.ParseInLocation().

3. Операции с датами: Duration, Add, Sub и сравнение

Тип time.Duration представляет интервал времени. Go предоставляет константы: Nanosecond, Microsecond, Millisecond, Second, Minute, Hour.

now := time.Now()

// Добавление времени
future := now.Add(72 * time.Hour) // +3 дня
fmt.Println("Через 72 часа:", future)

// Вычитание времени
past := now.Add(-30 * time.Minute) // 30 минут назад
fmt.Println("30 минут назад:", past)

// Разница между датами
diff := future.Sub(now)
fmt.Printf("Разница: %v (часов: %.0f)\n", diff, diff.Hours())

// Сравнение дат
if future.After(now) {
    fmt.Println("future позже now")
}
if now.Before(future) {
    fmt.Println("now раньше future")
}
if now.Equal(now) {
    fmt.Println("now равно самому себе")
}

Также доступны методы AddDate(years, months, days int) для календарных операций и Truncate()/Round() для округления времени.

4. Таймеры, тикеры и работа с временными зонами

Go предоставляет встроенные механизмы для работы с событиями по времени.

Таймер (Timer) — однократное событие

timer := time.NewTimer(2 * time.Second)
fmt.Println("Таймер запущен, ждём 2 секунды...")
<-timer.C // Блокируется до срабатывания
fmt.Println("Таймер сработал!")
timer.Stop() // Остановить до срабатывания

Тикер (Ticker) — периодические события

ticker := time.NewTicker(1 * time.Second)
done := make(chan bool)

go func() {
    for i := 0; i < 5; i++ {
        fmt.Println("Тик:", <-ticker.C)
    }
    done <- true
}()

<-done
ticker.Stop()
fmt.Println("Тикер остановлен")

Временные зоны (Location)

// Загрузка временной зоны
loc, err := time.LoadLocation("Europe/Moscow")
if err != nil {
    panic(err)
}

now := time.Now()
fmt.Println("Локальное:",                

Блоги

Рекомендаций по книгам