Как работать с датой и временем в Go

Отслеживание времени в коде уже давно стало кошмаром разработчика. Хотя ни один язык или пакет не управляет временем идеально, я считаю, что Golang делает это довольно хорошо. Это полное руководство призвано ответить на ~90% вопросов, которые у вас возникнут по поводу управления временем в Go.

Обзор - Как хранятся даты и время в Go

Первое, что следует знать, - это то, что для управления временем и датами в Go вам, скорее всего, не понадобятся никакие сторонние программные пакеты. Пакет time стандартной библиотеки Go очень надежен и может делать практически все, что вы захотите.
Тип time.Time по умолчанию представляет мгновение времени с точностью до наносекунды. Это структура, не имеющая экспортируемых полей, что означает, что вам никогда не придется использовать оператор точки для доступа к различным полям. Вместо этого доступны различные методы для получения нужных данных. Например, time.Year() возвращает год (в виде целого числа) рассматриваемого объекта time.
Два наиболее распространенных способа создания нового объекта времени - это использование текущего времени или ввод даты.

Получение текущего времени с помощью функции time.Now()

Функция time.Now() возвращает текущее местное время. Если вы работаете в бэкенде, то, скорее всего, вам также потребуется немедленно преобразовать его в UTC.

Как работать с датой и временем в Go

Создание объекта времени для определенной даты

Если вместо этого требуется создать объект времени для определенной даты, можно воспользоваться функцией time.Date().

Как работать с датой и временем в Go

Печать, анализ и форматирование времени в Go

While dates and times are typically stored as time.Time objects within Go programs, we frequently need to save them to databases, marshal them to JSON, or just print them to the console. It’s nice that Go provides functions to format and parse dates easily. That said, the way it’s handled is unique compared to most coding languages.

Let’s say we have a time object and we want to be able to print in a specific format. The Go formatting engine takes a layout of specific constants, and uses that as an example for how to format the time.

The reference time is defined in the docs as:

Как работать с датой и временем в Go

Поэтому, если мы хотим оформить наш временной объект определенным образом, мы можем просто использовать константы из эталонного времени, но переставить их так, как нам нужно.

Как работать с датой и временем в Go

Функция time.Parse() работает аналогичным образом, но принимает на вход строку времени и макет и пытается создать новый объект времени.

Как работать с датой и временем в Go

Как я уже упоминал выше в комментарии, по умолчанию для Go используется схема разбора и форматирования rfc3339. По возможности, если ваша команда работает преимущественно на Go, я бы рекомендовал использовать форматирование по умолчанию, ведь оно используется не просто так.

Периоды времени

Моим бичом в программировании является ситуация, когда разработчики не указывают единицы измерения в своих вычислениях. Неизбежно кто-то из разработчиков считает, что переменная timeElapsed (int) представляет секунды, а на самом деле она представляет миллисекунды. В Go это не является проблемой, если все придерживаются стандарта типа time.Duration.
Duration - это просто особый вид int64. Они представляют прошедшее время между двумя моментами в виде счета наносекунд. Единственным недостатком является то, что наибольшая представляемая длительность составляет ~290 лет, но для меня это пока не является проблемой. Существует несколько констант, определенных пакетом time для представления некоторых распространенных длительностей.

Как работать с датой и временем в Go

Конвертация между различными часовыми поясами и местоположениями

Каждый объект time.Time связан с местоположением, которое, по сути, является часовым поясом. Время в 5 часов не имеет смысла, если вы не знаете, в каком часовом поясе оно находится. Местоположение определяется типом time.Location, который, как и тип time.Time, представляет собой структуру без экспортируемых полей.

Получение часового пояса из существующего объекта времени

Как работать с датой и временем в Go

Создайте новый объект time.Location

Как работать с датой и временем в Go

Преобразование времени из одной точки в другую

Как работать с датой и временем в Go

Пользовательское название часового пояса

Часовой пояс - это, по сути, просто имя и смещение продолжительности относительно UTC. Если вам нужен определенный часовой пояс, но вы хотите изменить его название, вы можете сделать это.

Как работать с датой и временем в Go

Сложение, вычитание и сравнение времен

Времена и длительности, естественно, хорошо сочетаются друг с другом, и для выполнения основных арифметических действий и сравнений времени имеется несколько вспомогательных функций.

Добавление времени и продолжительности

Существуют две основные функции для добавления времени к существующему времени. Следует помнить, что эти функции работают и для вычитания времени, просто вы добавляете отрицательную длительность.
time.Add()

Как работать с датой и временем в Go
Как работать с датой и временем в Go

Получите разницу между двумя временами

Функция sub() получает разность между двумя временами. Следует помнить, что функция sub не вычитает длительность из времени. Для этого, как ни странно, необходимо использовать функцию add().

Как работать с датой и временем в Go

Сравните два времени, чтобы увидеть, какое из них идет после другого
Есть две функции, которые должны удовлетворить большинство ваших потребностей в сравнении времени.
time.After()

Как работать с датой и временем в Go

Экономия памяти с помощью TinyDate и TinyTime

Типичное значение time.Time занимает ~24 байта в памяти. Иногда вы не можете позволить себе использовать так много. Если вы находитесь в такой ситуации, то обратите внимание на мои библиотеки TinyTime и TinyDate на GitHub. Они используют всего по 4 байта!

11
Начать дискуссию