Работа с датой и временем

Работа с датой и временем

В этом курсе вы узнаете, как использовать класс Time, чтобы представлять время, дату и продолжительность временных интервалов.

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

Для начала давайте посмотрим как получить объект Time содержащий информацию о текущем либо произвольном времени:

# Получение информации о текущей дате и времени
now = Time.now # = 2023-03- 15:43:20 +0200
# Альернативный споосб получения текущего даты и времени
now = Time.new # = 2018-10-19 15:43:20 +0200
# Получение объекта с информацией о времени за конкретный день
# формат Time.new(год, месяц, день)
custom = Time.new(2018, 1, 1) # = 2018-01-01 00:00:00 +0100
# формат Time.new(год, месяц, день, час, минута, секунда, отступ часового пояса по UTC)
custom = Time.new(2002, 10, 31, 2, 2, 2, "+02:00") # = 2002-10-31 02:02:02 +0200
zone = timezone("Europe/Moscow") # Московский часовой пояс, UTC+3
# формат Time.new(год, месяц, день, час, минута, секунда, часовой пояс по UTC)
custom = Time.new(2002, 10, 31, 2, 2, 2, zone)  # = 2002-10-31 02:02:02 +0300
# Поучение объекта Time прозводный от Timestamp (POSIX-время, количество секунд прошедшее с 00:00:00 UTC 1 января, 1970 года)
custom = Time.at(15000000000) # = 2017-07-14 04:40:00 +0200

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

За частую, во время работы со временем нам нужно превращать его в строку, либо наборот, превращать строку в метку времени.

Для того, чтобы перевести Time в строковое представление используется метод .strftime(format) в который передается формат записи времени. Так как форматов записи может быть огромное множество, то был создан способ описания формата времени:

  • %Y - год в формате с 4-мя цифрами (например, 2022)

  • %m - номер месяца с предваряющим нулем (например, 01 для января)

  • %d - день месяца с предваряющим нулем (например, 01)

  • %H - часы в 24-часовом формате с предваряющим нулем (например, 02 для 2 часов утра или 2 часов дня)

  • %M - минуты с предваряющим нулем

  • %S - секунды с предваряющим нулем

  • %z - Часов

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

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

time = Time.new(2022, 1, 1, 11, 20, 35)
puts time.strftime("%d/%m/%Y - %H:%M") # = 01/01/2022 - 11:20
puts time.strftime("%m.%y %H:%M:S") # = 01.2022 11:20:35

Для того, чтобы нам теперь перевести строку в метку времени нам необходимо расширить возможности класса Time с помощью добавления require 'time' в самом начале нашего .rb файла, после чего мы сможем воспользоваться конструкцией Time.strptime(str, format). В качестве первого аргумента мы передаем строкове представление метки времени (например "01/01/2022 - 11:20"), а в качестве формата мы передаем формат записи (например %d/%m/%Y - %H:%M).

require 'time'

time = Time.new(2022, 1, 1, 11, 20, 35)
date_format = "%d/%m/%Y - %H:%M"
str_time = time.strftime(date_format) # метод возвращает строковое представление 
puts str_time # = "01/01/2022 - 11:20"
decoded_dtime = Time.strptime(str_time, date_format) # метод возвращает метку времени 
p decoded_dtime # = Time ( 2022-01-01 11:20:00 +0300 )

Помимо прочего существует конструкция Time.parse(str), которая автоматически подбирает формат из предстановленных спецификаций RFC, но во первых, далеко не любой формат так можно распарсить, а во вторых, этот метод парсит строку с помощью перебоора формата: попробовал распарсить - не получилось - пробует еще раз с другим форматом и так до тех пора, пока не получится. Указывая формат напрямую мы избавляемся от лишних действий6 которые за нас сделает сам язык.

Арифметические операции со временем

Хорошо, мы научились создавать метку времени, научились превращать ее в строку, теперь стоит изучить способы манипуляции со временем.

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

time = Time.new(2022, 1, 1, 11, 20, 35)
puts time.strftime("%%d/m/%y %H:%M:S") # = "01/01/2022 - 11:20:35"
# альтернатвная запись выражения time = time + 5
time += 5
puts time.strftime("%%d/m/%y %H:%M:S") # = "01/01/2022 - 11:20:40"
# альтернатвная запись выражения time = time - 2
time -= 2
puts time.strftime("%%d/m/%y %H:%M:S") # = "01/01/2022 - 11:20:38"

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

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

start = Time.new(2022, 1, 1, 11, 20, 35)
finish = Time.new(2022, 1, 1, 11, 20, 40)

puts finish - start # 5

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

start = Time.now
sleep(5) # заставляем программу 'засыпать' на 5 секунд
finish = Time.now
puts finish - start # = 5.0... секунд

Задание birthdays

Реализуйте метод collect_birthdays(year, month, day), который будет печатать в консоль ваш возраст, дата дня рождения и день недели вашего дня рождения

Как это должно выглядеть:

  collect_birthdays(1997, 12, 1)

  # 0 - 01.12.1997 - Monday
  # 1 - 01.12.1998 - Tuesday
  # 2 - 01.12.1999 - Wednesday
  # ...
  # 25 - 01.12.2022 - Thursday

Дополнительный материал

Last updated