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

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

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

Начать курс

Введение в работу с датами и временем в Go

Работа с датами и временем — одна из ключевых задач в любом серьёзном приложении. Будь то логирование событий, расчёт тайм-аутов, работа с расписаниями или анализ временных рядов, язык Go предоставляет мощный и элегантный инструментарий в стандартном пакете time. В этой статье мы разберём работу с датами и временем в Go от А до Я: от создания объектов времени до сложных операций с часовыми поясами и таймерами.

Основы: структура time.Time и создание дат

Центральный элемент пакета time — структура time.Time. Она представляет момент времени с наносекундной точностью и информацией о часовом поясе.

Получение текущего времени

Самый частый сценарий — получить текущий момент:

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    fmt.Println("Текущее время:", now)
}

Создание конкретной даты

Для создания даты используется функция time.Date(). Обратите внимание: в Go месяцы задаются через константы (time.January, time.February и т.д.) или числом от 1 до 12.

func main() {
    // 15 марта 2025 года, 14:30:00, UTC
    specificDate := time.Date(2025, time.March, 15, 14, 30, 0, 0, time.UTC)
    fmt.Println("Конкретная дата:", specificDate)
    
    // Создание с наносекундами
    preciseDate := time.Date(2025, 3, 15, 14, 30, 0, 123456789, time.UTC)
    fmt.Println("Точная дата:", preciseDate)
}

Форматирование и парсинг дат

В Go используется уникальный подход к форматированию: вместо кодов типа %Y-%m-%d вы используете эталонное время Mon Jan 2 15:04:05 MST 2006 (которое читается как 01 02 03 04 05 06 07 — год, месяц, день, час, минута, секунда, год).

Форматирование (time → строка)

Метод Format() преобразует время в строку по заданному шаблону:

func main() {
    now := time.Now()
    
    // Стандартные форматы
    fmt.Println("RFC3339:", now.Format(time.RFC3339))
    fmt.Println("Дата:", now.Format("2006-01-02"))
    fmt.Println("Время:", now.Format("15:04:05"))
    fmt.Println("Полный формат:", now.Format("02.01.2006 15:04:05"))
    fmt.Println("С днём недели:", now.Format("Mon, 02 Jan 2006"))
}

Парсинг (строка → time.Time)

Функция time.Parse() разбирает строку в структуру времени. Важно: шаблон должен точно соответствовать формату входной строки.

func main() {
    // Парсинг с известным форматом
    dateStr := "2025-03-15 14:30:00"
    parsed, err := time.Parse("2006-01-02 15:04:05", dateStr)
    if err != nil {
        panic(err)
    }
    fmt.Println("Распарсено:", parsed)
    
    // Парсинг с часовым поясом
    dateWithZone := "2025-03-15T14:30:00+03:00"
    parsedWithZone, _ := time.Parse(time.RFC3339, dateWithZone)
    fmt.Println("С часовым поясом:", parsedWithZone)
}

Арифметика времени: интервалы и сравнения

Пакет time предоставляет тип Duration для представления интервалов времени и методы для арифметических операций.

Сложение и вычитание

func main() {
    now := time.Now()
    
    // Добавление 2 часов 30 минут
    future := now.Add(2*time.Hour + 30*time.Minute)
    fmt.Println("Через 2.5 часа:", future)
    
    // Вычитание 7 дней
    past := now.Add(-7 * 24 * time.Hour)
    fmt.Println("Неделю назад:", past)
    
    // Использование AddDate для работы с календарными датами
    nextMonth := now.AddDate(0, 1, 0)
    fmt.Println("Через месяц:", nextMonth)
}

Вычисление разницы между датами

Метод Sub() возвращает Duration:

func main() {
    start := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)
    end := time.Date(2025, 12, 31, 23, 59, 59, 0, time.UTC)
    
    diff := end.Sub(start)
    fmt.Printf("Разница: %v часов\n", diff.Hours())
    fmt.Printf("Разница: %v минут\n", diff.Minutes())
    fmt.Printf("Разница: %v секунд\n", diff.Seconds())
    
    // Более удобный способ
    fmt.Println("Длительность:", diff)
}

Сравнение дат

func main() {
    a := time.Date(2025, 3, 15, 0, 0, 0, 0, time.UTC)
    b := time.Date(2025, 6, 20, 0, 0, 0, 0, time.UTC)
    
    fmt.Println("a до b?", a.Before(b))   // true
    fmt.Println("a после b?", a.After(b)) // false
    fmt.Println("a равно b?", a.Equal(b)) // false
    
    // Проверка, находится ли дата в интервале
    if a.Before(b) && b.After(a) {
        fmt.Println("b находится после a")
    }
}

Таймеры, тикеры и работа с задержками

Go предоставляет удобные примитивы для работы с временными событиями в конкурентной среде.

time.Sleep — простая задержка

func main() {
    fmt.Println("Начало работы...")
    time.Sleep(2 * time.Second)
    fmt.Println("Прошло 2 секунды")
}

time.Timer — однократное событие

func main() {
    timer := time.NewTimer(3 * time.Second)
    
    select {
    case <-timer.C:
        fmt.Println("Таймер сработал через 3 секунды")
    }
    
    // Сброс таймера
    timer.Reset(1 * time.Second)
    <-timer.C
    fmt.Println("Таймер сб                

Блоги

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