Истории успеха наших клиентов — лучшие проекты
Вход/ Регистрация

Работа с датой и временем в Go с помощью пакета time

2952
21 минута чтения
Средний рейтинг статьи: 5

Язык программирования Go (Golang), как и многие другие, имеет встроенный пакет time, который предоставляет специальные типы и методы для работы с датой и временем.

Полную и исчерпывающую информацию о пакете time можно найти на специальной странице официальной документации.

В этом руководстве мы рассмотрим базовые аспекты работы со временем в языке программирования Go.

Все показанные примеры запускались на облачном сервере Timeweb Cloud под управлением операционной системы Ubuntu 22.04 с использованием интерпретатора Go версии 1.21.3.

Предполагается, что вы уже знакомы с основами языка Go и знаете, как запускать созданные скрипты через соответствующую команду интерпретатора:

    

Также стоит упомянуть несколько отдельных руководств, опубликованных в официальном блоге Timeweb Cloud, которые подробно описывают установку Golang на популярные операционные системы:

Парсинг, форматирование и создание

Прежде чем переходить к работе с временем, важно понять важную особенность форматирования времени в Go.

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

Однако в языке Go все иначе. Вместо специальных символом используются значения даты и времени по умолчанию, представляющие собой возрастающую последовательность значений — 01-02-03-04-05-06.

Этот набор чисел означает следующее:

  • 1-й месяц в году (Январь)
  • 2-е число в месяце
  • 3-й час в 12-часовом формате (p.m.)
  • 4-я минута в 12-часовом формате (p.m.)
  • 5-я секунда в 12-часовом формате (p.m.)
  • 6-й год 21 века

Таким образом получается 2 января 15:04:05 2006 года, или 2 января 03:04:05 PM 2006 года, или 02.01.2006 03:04:05 PM.

Важно помнить, что это значение — ничто иное, как обычная возрастающая последовательность чисел. В ней нет особого сакрального смысла.

Таким образом, эти дата и время являются предопределенным макетом для работы с любыми явно указываемыми значениями даты и времени.

Например, можно привести абстрактный (синтаксически не связанный с Go) пример псевдокода:

    

И тогда в нашей псевдоконсоли появится следующий псевдовывод:

    

Именно так устроено форматирование даты и времени в большинстве языков программирования.

В случае же с Go псевдокод выглядел бы так:

    

При этом консольный вывод был бы аналогичным.

То есть стандартные значения шаблона даты и времени автоматически заменяются на конкретные значения даты и времени.

При этом значения шаблона имеют определенную вариативность Например, 01 месяц можно также указывать в виде слова Jan.

Благодаря этому язык Go позволяет задавать шаблоны в более понятном и человекочитаемом виде.

Облачные серверы

Масштабируемые вычислительные ресурсы
по всему миру с почасовой оплатой.

Парсинг

Использование времени в Go начинается с его явного задания. Сделать это можно через функцию парсинга времени:

    

В терминале появится вывод с результатом работы скрипта:

    

Обратите внимание, что после парсинга создается переменная типа time.Time, которая содержит указанное во время парсинга значение времени в своем внутреннем формате.

В показанном примере шаблон и значение времени можно было бы заменить на другую равнозначную запись:

    

Итоговый результат остался бы таким же.

Во время парсинга в качестве дополнительного параметра можно указать временную зону, которую также именуют часовым поясом:

    

Консольный вывод этого скрипта будет таким:

    

При этом вместо явно созданной переменной часового пояса можно использовать предопределенную константу:

    

В этом случае полные значения даты и времени в обоих вариантах будут идентичными:

    

Полный список существующих временных зон можно посмотреть в так называемой «Базе данных временных зон» (tz database).

Идентификатор временной зоны указываются с помощью названий двух регионов, записанных через косую черту. Например, так:

  • Europe/Moscow
  • Asia/Dubai
  • US/Alaska

Image1

Карта всех часовых поясов на основе tz database версии 2023 года. Автор: Evansiroky2, лицензия CC BY 4.0. Источник: Wikipedia.

Форматирование

Уже созданную переменную времени можно отформатировать, чтобы представить ее значение в определенном текстовом виде.

Таким образом, переменная типа time.Time имеет встроенные методы для преобразования даты и времени в переменную типа string:

    

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

    

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

time.Layout

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

time.ANSIC

Mon Jan _2 15:04:05 2006

time.UnixDate

Mon Jan _2 15:04:05 MST 2006

time.RubyDate

Mon Jan 02 15:04:05 -0700 2006

time.RFC822

02 Jan 06 15:04 MST

time.RFC822Z

02 Jan 06 15:04 -0700

time.RFC850

Monday, 02-Jan-06 15:04:05 MST

time.RFC1123

Mon, 02 Jan 2006 15:04:05 MST

time.RFC1123Z

Mon, 02 Jan 2006 15:04:05 -0700

time.RFC3339

2006-01-02T15:04:05Z07:00

time.RFC3339Nano

2006-01-02T15:04:05.999999999Z07:00

time.Kitchen

3:04PM

time.Stamp

Jan _2 15:04:05

time.StampMilli

Jan _2 15:04:05.000

time.StampMicro

Jan _2 15:04:05.000000

time.StampNano

Jan _2 15:04:05.000000000

time.DateTime

2006-01-02 15:04:05

time.DateOnly

2006-01-02

time.TimeOnly

15:04:05

Еще один способ отформатировать дату и время — конвертация в Unix:

    

После запуска этого скрипта в терминале появится следующий вывод:

    

Обратите внимание, что переменная, созданная для хранения UNIX-значения времени, имеет тип int64, а не time.Time.

Таким образом с помощью форматирования можно выполнять конвертацию из строкового времени в Unix и обратно:

    

Консольным выводом этого скрипта станут результаты конвертаций в Unix и из него:

    

Создание

В языке Go есть более тривиальный способ создания переменной time.Time через явное задание параметров даты и времени:

    

После запуска скрипта в терминале появится следующий вывод:

    

Текущие дата и время

Помимо ручной установки произвольных даты и времени можно установить текущие дату и время:

    

После запуска этого скрипта в терминале появится следующий вывод:

    

Как видно, в результате выполнения функции time.Now() создается уже знакомая переменная time.Time, значения которой можно произвольно форматировать.

Извлечение параметров

Переменная time.Time состоит из набор параметров, которые в совокупности образуют дату и время:

  • Год
  • Месяц
  • Число
  • День недели
  • Час
  • Минута
  • Секунда
  • Наносекунда
  • Часовой пояс

Соответственно, язык Go обладает набором методов для извлечения и изменения каждого из этих параметров.

Чаще всего необходимо просто узнать конкретные параметры уже созданной переменной времени:

    

Консольный вывод этого скрипта будет таким:

    

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

Обратите внимание на типы полученных переменных — все они имеют тип int за исключением нескольких:

  • Месяц (time.Month)
  • День недели (time.Weekday)
  • Часовой пояс (*time.Location)

При этом последний (часовой пояс) является указателем.

Изменение, сложение и вычитание 

Изменение

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

    

Запустив этот скрипт можно наблюдать следующий вывод:

    

В этом примере было добавлено 14 часов к параметру текущему времени. Таким образом можно избирательно обновлять значения времени в уже имеющейся переменной time.Time.

Изменение по часовому поясу

Иногда необходимо узнать, какими будут заданные дата и время в другой временной зоне. Для этого в языке Go есть специальный метод:

    

Результатом работы скрипта станет следующий консольный вывод:

    

Таким образом получаются новые значения даты и времени, обновленные исходя из повторно указанной временной зоны.

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

В языке Go нет отдельных методов для операции сложения даты и времени. Вместо этого можно добавлять временные промежутки к уже созданной переменной time.Time:

    

В результате работы этого скрипта в терминале появится следующий вывод:

    

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

При этом переменная time.Hour на самом деле имеет специальный тип time.Duration:

    

После запуска этого скрипта в терминале появится такой вывод:

    

Тем не менее, изменение даты и времени через добавление или удаление большого количества часов ненаглядно. В некоторых случаях лучше воспользоваться более продвинутыми методами изменения времени:

    

После запуска этого скрипта в терминале появится такой вывод:

    

Нахождение разницы

В отличие от сложения, в языке Go есть специализированные методы для вычитания одной переменной time.Time из другой:

    

Консольный вывод этого примера будет таким:

    

Как можно заметить, результатом вычитания является уже знакомая переменная типа time.Duration.

На самом деле основной функцией для нахождения разницы является лишь time.Time.Sub(), а остальные две лишь ее производные:

    

После запуска этого скрипта в терминале появится такой вывод:

    

Таким образом, можно наблюдать идентичность результатов описанных функций:

  • time.Time.Since() = time.Now().Sub(timeVariable)

  • time.Time.Until() = timeVariable.Sub(time.Now())

Временные продолжительности

Отдельные промежутки времени (продолжительности) в пакете time представляются в виде специальной переменной типа time.Duration. В отличие от time.Time, они хранят не полноценные дату и время, а временные интервалы.

С продолжительностями можно выполнять некоторые базовые операции, изменяющие их временные параметры.

Парсинг продолжительностей

Продолжительность в явном виде задается с помощью строки, содержащей значения временных параметров:

    

Результатом работы этого скрипта будет следующий вывод:

    

Обратите внимание на последнюю продолжительность, которая содержит все возможные временные параметры в порядке убывания размерности — часы, минуты, секунды, миллисекунды, микросекунды, наносекунды.

Во время парсинга каждый из параметров задается с помощью следующих ключевых слов:

  • Часы — h
  • Минуты — m
  • Секунды — s
  • Миллисекунды — ms
  • Микросекунды — µs
  • Наносекунды— ns

Более того, различный порядок указания параметров продолжительности не оказывает на нее никакого влияния:

    

После запуска скрипта в терминале будет такой вывод:

    

Форматирование продолжительностей

В языке Go одну и ту же продолжительность можно представлять в виде разных единиц измерения:

    

После запуска скрипта в терминале появится такой вывод:

    

Как видно, параметры часов, минут и секунд имеют вещественный тип (float64), а все остальные — целочисленный (int).

Выгодные тарифы на облако в Timeweb Cloud

Cloud MSK 15

477 ₽/мес

Процессор
1 x 3.3 ГГц
Память
1 ГБ
NVMe
15 ГБ
Канал
1 Гбит/с
Публичный IP
Cloud MSK 30

657 ₽/мес

Процессор
1 x 3.3 ГГц
Память
2 ГБ
NVMe
30 ГБ
Канал
1 Гбит/с
Публичный IP

Заключение

В этом руководстве были рассмотрены основные функции работы с датой и временем в языке программирования Go — все они содержатся во встроенном пакете time.

Таким образом, язык Go позволяет:

  • Форматировать дату и время
  • Конвертировать дату и время
  • Устанавливать часовые пояса
  • Извлекать конкретные параметры даты и времени
  • Устанавливать конкретные параметры даты и времени
  • Складывать и вычитать дату и время
  • Выполнять код исходя из определенных временных установок

Дополнительную информацию об особенностях работы с пакетом time можно найти на специальной странице официальной документации языка Go.

2952
21 минута чтения
Средний рейтинг статьи: 5
Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server