5 уровней работы с датами и временем в Python
Обработка дат и времени является частой задачей при разработке ПО. Однако, так как даты и время являются специальными типами данных, операции с ними могут быть запутанными и подвержены ошибкам, например, при преобразовании между различными форматами дат или часовых поясов.
Верите или нет, но многие программисты, независимо от того, сколько лет они работают, продолжают сталкиваться с проблемами, связанными с датами или временем. Поэтому эта статья обязательна к прочтению.
В этой статье будут объяснены 5 важных операций с датами и временем от простых до сложных. После прочтения работы с датами и временем в Python будет для вас просто пустяком. 🍰
Уровень 0: знание 3 основных объектов в модуле datetime
Все объекты, связанные со временем в Python, могут быть построены с помощью трех основных классов модуля datetime:
datetime: объект для работы с информациейгод-месяц-день-час-минута-секунда.date: объект для работы с информациейгод-месяц-день.time: объект для работы с информациейчас-минута-секунда.
Давайте посмотрим, как их использовать на простых примерах:
Получение информацию о текущем времени
Мы можем получить текущее время или дату сегодняшнего дня с помощью методов класса без создания объекта date или datetime.
from datetime import datetime from datetime import date print(datetime.now()) # 2023-08-30 15:53:35.520076 print(date.today()) # 2023-08-30
Создание и работа с объектом
Мы можем создавать экземпляры трёх классов и использовать их в соответствии с конкретными потребностями. Следующий пример демонстрирует, как использовать объект date. Использование объектов time и datetime выполняется аналогичным образом.
from datetime import date # создаем объект date(year, month, day) my_birthday = date(1991, 8, 30) print(my_birthday.year) # 1991 print(my_birthday.month) # 8 print(my_birthday.day) # 30 print(my_birthday.weekday()) # 8 new_birth = my_birthday.replace(year=2023) print(my_birthday) # 1991-08-30 print(new_birth) # 2023-08-30
Уровень 1: знакомство с временными расчётами
Благодаря классу timedelta, расчеты с датами и временем в Python реализуются довольно просто.
from datetime import datetime, timedelta now = datetime.now() print(now) # 2023-08-30 15:57:07.020609 tomorrow = now + timedelta(days=1) print(tomorrow) # 2023-08-31 15:57:07.020609 later = now + timedelta(seconds=10) print(later) # 2023-08-30 15:57:17.020609 last_week_day = now - timedelta(weeks=1) print(last_week_day) # 2023-08-23 15:57:07.020609
Уровень 2: умение работать с часовыми поясами
Есть общеиспользуемый модуль под названием pytz, который упрощает переключение между часовыми поясами. Поскольку это не встроенный модуль, мы должны установить его перед использованием:
Теперь работа с часовыми поясами становится простой:
from datetime import datetime
import pytz
local = datetime.now()
print(local.strftime("%d/%m/%Y, %H:%M:%S"))
# 30/08/2023, 16:00:05
NY = pytz.timezone('America/New_York')
datetime_NY = datetime.now(NY)
print(datetime_NY.strftime("%d/%m/%Y, %H:%M:%S"))
# 30/08/2023, 12:00:05
Tokyo = pytz.timezone('Asia/Tokyo')
datetime_Tokyo = datetime.now(Tokyo)
print(datetime_Tokyo.strftime("%d/%m/%Y, %H:%M:%S"))
# 30/08/2023, 01:00:05Мы также можем вывести на экран полный список часовых поясов:
print(pytz.all_timezones)
Уровень 3: четко понимайте временные метки
Время в компьютерах на самом деле представлено числами. Мы можем просто определить особое время, которое представлено 0, и вычислять другое время на его основе.
В этом и заключается идея временной метки. 🕐
Время UTC в 1970-01-01 00:00:00 записывается как 0 и называется эпохальным временем или временем Unix. Временная метка — это количество секунд относительно времени Unix.
Временная метка до эпохального времени — это отрицательное число.
Временная метка после эпохального времени — это положительное число.
Например, временная метка 1970-01-01 01:00:00 равна 3600. Потому что это на один час позже Unix-времени и это равно 3600 секунд.
Переключение между датами и временными метками в Python выполняется просто:
from datetime import datetime # получаем временную метку из объекта datetime now = datetime.now() print(now.timestamp()) # 1665936327.409766 # конвертация временной метки в timestamp a_timestampe = 3600 print(datetime.utcfromtimestamp(a_timestampe)) # 1970-01-01 01:00:00
Как показано в примере выше, метод datetime.timestamp() преобразует datetime в timestamp, а метод datetime.utcfromtimestamp() преобразует timestamp в datetime.
Можно увидеть, что временная метка не имеет ничего общего с часовыми поясами, потому что как только определяется временная метка, определяется и её время UTC.
Однако datetime определяется относительно часовых поясов. Когда мы преобразуем временную метку в datetime, есть два варианта:
- Использовать метод
datetime.utcfromtimestamp(), чтобы преобразовать её во время UTC. - Использовать метод
datetime.fromtimestamp(), чтобы преобразовать её в местное время.
Например, если ваше местное время на один час позже времени UTC то, как показано в примере ниже, если преобразовать временную метку 0 в такое местное время, то это будет 1970-01-01 01:00:00.
# utcfromtimestamp() VS fromtimestamp() print(datetime.utcfromtimestamp(0)) # 1970-01-01 00:00:00 print(datetime.fromtimestamp(0)) # 1970-01-01 01:00:00
Уровень 4: правильный перевод между строками и datetime
Переключение между датами и строками является распространённой задачей. Есть две функции, которые могут помочь нам:
datetime.strptime(): преобразует строку в объектdatetime.datetime.strftime(): преобразует объектdatetimeв строку.
from datetime import datetime
# Конвертация строки в datetime
string_time = '2023-08-30 20:20:20'
t = datetime.strptime(string_time, '%Y-%m-%d %H:%M:%S')
print(t)
# 2023-08-30 20:20:20
print(type(t))
# <class 'datetime.datetime'>
# Конвертация datetime в строку
now = datetime.now()
string_now = now.strftime('%a, %d/%m/%Y %H:%M:%S')
print(string_now)
# Wed, 30/08/2023 16:12:45
print(type(string_now))
# <class 'str'>Примечание: Шаблоны форматирования, такие как %Y-%m-%d или %a, основаны на стандарте Представления дат и времён от ISO.
Работа с датами и временем — одна из распространенных задач в программировании. Стоит потратить немного времени, чтобы ознакомиться с ней :)