Класс datetime. Работа с датой и временем в Python
Класс datetime
, входящий в одноименный ему модуль datetime
стандартной библиотеки Python, по большей части реализует совокупность тех возможностей, которые есть по отдельности в ранее рассмотренных нами классах date
и time
.
В случае необходимости экземпляр datetime
разбирается на дату и время. Также можно выполнить обратное – собрать экземпляры date
и time
в один. В первом случае вызываются методы date()
и time()
экземпляра datetime
. Во втором случае – метод combine(…)
класса.
from datetime import datetime, date, time, timezone, timedelta a = datetime(2023, 5, 19, 21, 49, tzinfo=timezone(timedelta(hours=3))) print(a) # 2023-05-19 21:49:00+03:00 print(a.date()) # 2023-05-19 print(a.time()) # 21:49:00 print(a.timetz()) # 21:49:00+03:00 d = date(2023, 5, 20) t = time(10, 50, 34) dt = datetime.combine(d, t) # если бы в t был timezone, здесь он был бы также dt_tz = datetime.combine(d, t, timezone(timedelta(hours=2))) print(dt) # 2023-05-20 10:50:34 print(dt_tz) # 2023-05-20 10:50:34+02:00
Чтобы получить текущее время, используются классовые методы today
и now
. Первый возвращает местное время как наивное. Второй позволяет указать часовой пояс.
from datetime import datetime, timezone, timedelta a = datetime.today() print(a.strftime("%d %b %Y, %A, %H:%M")) print(a.strftime("%d %b %Y, %A, %I:%M %p")) b = datetime.now(timezone(timedelta(hours=3))) print(b.strftime("%d %b %Y, %A, %H:%M %Z")) c = datetime.now(timezone.utc) print(c.strftime("%d %b %Y, %A, %H:%M %Z"))
Пример выполнения:
19 May 2023, Friday, 23:12 19 May 2023, Friday, 11:12 PM 19 May 2023, Friday, 23:12 UTC+03:00 19 May 2023, Friday, 20:12 UTC
В примере при создании третьего экземпляра datetime
используется константа timezone.utc
, которая содержит экземпляр timezone
с нулевой таймдельтой.
Если вы хотите локальное время перевести в UTC или время какого-то другого часового пояса (выполнить корректировку часового пояса – time zone adjustments), то сделать это можно с помощью метода astimezone
.
from datetime import datetime, timezone, timedelta moscow = timezone(timedelta(hours=3), "Moscow") new_york = timezone(timedelta(hours=-4), "New York") a = datetime.now(moscow) b = a.astimezone(new_york) print(a.strftime("%H:%M:%S %Z")) print(b.strftime("%H:%M:%S %Z")) c = b.astimezone(timezone.utc) print(c.strftime("\n%H:%M:%S %Z"))
Пример выполнения:
16:40:29 Moscow 09:40:29 New York 13:40:29 UTC
Если в astimezone
не передать часовой пояс, тогда из времени экземпляра, к которому применяется метод, вы получите ваше локальное время. Оно определяется из данных операционной системы.
from datetime import datetime, timedelta, timezone a = datetime(2023, 5, 26, 20, 30) b = datetime.now(timezone(timedelta(hours=-4))) print(b, end='\n\n') a2 = a.astimezone() b2 = b.astimezone() print(a2, a2.tzname()) print(b2, b2.tzname())
Пример выполнения:
2023-05-21 10:01:17.873329-04:00 2023-05-26 20:30:00+03:00 MSK 2023-05-21 17:01:17.873329+03:00 MSK
В коде выше, применив astimezone
без аргументов к наивному времени, мы получили это же самое время, но уже осведомленное. В данном случае – с указанием местного часового пояса.
Если надо не переводить время, а только изменить часовой пояс при сохранении тех же значений времени, используется метод replace
. С его помощью также превращают осведомленное время в наивное.
from datetime import datetime, timedelta, timezone a = datetime(2023, 5, 26, 20, 30, tzinfo=timezone(timedelta(hours=3))) b = a.replace(tzinfo=timezone(timedelta(hours=-4))) c = a.replace(tzinfo=None) # наивное время print(a.timetz()) # 20:30:00+03:00 print(b.timetz()) # 20:30:00-04:00 print(c.timetz()) # 20:30:00
Подобно date
экземпляры datetime
поддерживают следующие операции:
- Сравнение объектов между собой. Результат –
True
илиFalse
. - Вычитание из одного объекта другого. Результат – экземпляр
timedelta
. - Вычитание и прибавление таймдельты. Результат – экземпляр
datetime
.
Однако, в связи с появлением свойства tzinfo
, для сравнений действуют те же правила, что и для time
.
Кроме того, вычисление разницы между двумя datetime
возможно, когда обе даты с временем являются либо наивными, либо обе – осведомленными. Во втором случае при различных часовых поясах за кулисами выполняется приведение времени к UTC.
from datetime import datetime a = datetime.fromisoformat("2023-05-21 19:05:23 +03:00") b = datetime.fromisoformat("2023-05-22 00:05:23 +01:00") ba = b - a print(ba) # 7:00:00 print(ba.__repr__()) # datetime.timedelta(seconds=25200)
В примере первое время соответствует 16-ти часам в зоне UTC, второе 23-м. Разница между моментами времени составляет 7 часов.
Обратите внимание, здесь не важно, какая будет таймзона у результата, потому что у таймдельты (отрезка времени) нет такого параметра.
В то же время при сложении/вычитании datetime
с timedelta
у первого сохраняется его часовой пояс.
from datetime import datetime, timedelta a = datetime.fromisoformat("2023-05-21 19:05:23 +03:00") delta = timedelta(days=1, hours=5, minutes=30) print(a + delta) # 2023-05-23 00:35:23+03:00 print(a - delta) # 2023-05-20 13:35:23+03:00
Атрибуты класса datetime
(подчеркнуты не упомянутые в уроке):
- данные, хранимые в классе (свойства класса):
min
,max
,resolution
- методы класса:
strptime
,today
,now
,utcnow
,combine
,fromisoformat
,fromisocalendar
,fromtimestamp
,utcfromtimestamp
,fromordinal
- свойства экземпляра:
year
,month
,day
,hour
,minute
,second
,microsecond
,tzinfo
,fold
- методы экземпляра:
date
,time
,timetz
,replace
,astimezone
,isoformat
,strftime
,utcoffset
,dst
,tzname
,timetuple
,utctimetuple
,toordinal
,timestamp
,weekday
,isoweekday
,isocalendar
,ctime