Введение в работу с датами и временем в Go
Работа с датами и временем — одна из ключевых задач в любом языке программирования. Язык Go (Golang) предоставляет мощный и интуитивно понятный пакет time, который позволяет выполнять все основные операции: получение текущего времени, парсинг строк, форматирование, вычисление разницы, создание таймеров и многое другое. В отличие от некоторых других языков, Go использует уникальный эталонный формат времени, что делает код более читаемым и предсказуемым. В этой статье мы подробно разберём основные возможности пакета time на практических примерах.
Основные типы и получение текущего времени
Тип time.Time
Центральным типом в пакете time является структура time.Time. Она хранит информацию о секундах, наносекундах, часовом поясе и монотонном счётчике (для точных измерений).
Получение текущего момента
Для получения текущего времени используется функция time.Now(). Она возвращает локальное время на основе системных настроек.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println("Текущее время:", now)
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.Nanosecond())
fmt.Println("День недели:", now.Weekday())
}
Создание времени вручную
Вы можете создать конкретный момент времени с помощью функции time.Date(). Она принимает год, месяц, день, час, минуту, секунду, наносекунду и часовой пояс.
package main
import (
"fmt"
"time"
)
func main() {
// 15 марта 2025 года, 14:30:00, UTC
specificDate := time.Date(2025, time.March, 15, 14, 30, 0, 0, time.UTC)
fmt.Println("Созданная дата:", specificDate)
}
Парсинг и форматирование дат
Эталонный формат Go
Go использует уникальный подход к форматированию: вместо кодов типа YYYY-MM-DD используется эталонная дата Mon Jan 2 15:04:05 MST 2006 (или сокращённо 2006-01-02T15:04:05Z07:00). Это значит, что для указания года вы пишете 2006, для месяца — 01, для дня — 02, для часа — 15 (или 03 для 12-часового формата), для минуты — 04, для секунды — 05.
Форматирование времени в строку
Метод Format() преобразует time.Time в строку по заданному шаблону.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println("Стандартный формат:", now.Format("2006-01-02 15:04:05"))
fmt.Println("Русский формат:", now.Format("02.01.2006 15:04"))
fmt.Println("Только дата:", now.Format("02 Jan 2006"))
fmt.Println("12-часовой формат:", now.Format("03:04:05 PM"))
}
Парсинг строки в дату
Функция time.Parse() преобразует строку в time.Time. Важно, чтобы строка соответствовала шаблону.
package main
import (
"fmt"
"time"
)
func main() {
dateStr := "2025-03-15 14:30:00"
layout := "2006-01-02 15:04:05"
parsedTime, err := time.Parse(layout, dateStr)
if err != nil {
fmt.Println("Ошибка парсинга:", err)
return
}
fmt.Println("Распарсенное время:", parsedTime)
fmt.Println("День недели:", parsedTime.Weekday())
}
Парсинг с часовым поясом
Для строк с часовым поясом используйте time.ParseInLocation() или укажите смещение в шаблоне (Z07:00).
package main
import (
"fmt"
"time"
)
func main() {
dateStr := "2025-03-15 14:30:00 +0300"
layout := "2006-01-02 15:04:05 -0700"
parsedTime, _ := time.Parse(layout, dateStr)
fmt.Println("Время с зоной:", parsedTime)
fmt.Println("Часовой пояс:", parsedTime.Location())
}
Арифметика времени и сравнение
Сложение и вычитание
Пакет time позволяет легко манипулировать временем с помощью методов Add() и Sub().
package main
import (
"fmt"
"time"
)
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("7 дней назад:", past)
// Разница между двумя моментами
diff := future.Sub(past)
fmt.Println("Разница (часы):", diff.Hours())
fmt.Println("Разница (минуты):", diff.Minutes())
}
Сравнение дат
Для сравнения моментов времени используются методы Before(), After() и Equal().
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
future := now.Add(1 * time.Hour)
past := now.Add(-1 * time.Hour)
fmt.Println("now.Before(future):", now.Before(future)) // true
fmt.Println("now.After(past):", now.After(past)) // true
fmt.Println("now.Equal(now):", now.Equal(now)) // true
}
Тип time.Duration
Duration представляет собой интервал времени в наносекундах. Константы: Nanosecond, Microsecond, Millisecond, Second, Minute