Datetime в Python — работа со временем и датой
Для работы с датой и временем в Python 2 и 3 есть отдельный модуль datetime. В отличие от других языков, таких как SQL, в Python нет встроенного типа данных для работы с датой и временем — это достигается путем импорта модуля и созданием объекта. Модуль datetime входит в пакет Python и его не нужно отдельно устанавливать.
Импорт модуля осуществляется следующим путем:
import datetime
Навигация по посту
- Получение текущей даты и времени
- Форматирование и перевод в строку
- Получения дня недели и название месяца
- Создание из строк
- Разница между датами
Получение текущей даты и времени
Для вывода даты и времени нужно выполнить следующее:
import datetime day_time = datetime.datetime.now() print(day_time)
Как видно мы получаем для создания объекта даты и времени используется класс с тем же именем что и модуль datetime.
Когда нужно получить только дату используется класс date:
import datetime day = datetime.date.today() print(day)
Получение только времени выполняется через метод time():
import datetime date_time = datetime.datetime.now().time() print(date_time, type(date_time))
Каждый из описываемых классов можно импортировать следующим способом:
from datetime import date from datetime import datetime print(datetime.now()) print(date.today())
Форматирование и перевод в строку
Для получение части даты или времени можно использовать следующие атрибуты:
import datetime # Получение дня от даты date = datetime.date.today() print(date.day) date_time = datetime.datetime.now() # Получение часа суток от времени print(date_time.hour)
Так же есть метод strftime, который форматирует даты в нужном формате в строку. Например так мы получим дату в формате, который используется у нас:
import datetime date = datetime.datetime.today() print(date.strftime('%d-%m-%Y %H:%M'))
- %d — день месяца с 1 по 31;
- %m — месяц с 1 по 12;
- %Y — год;
- %H — час в формате 0-24;
- %M — минуты;
- %S — секунды.
Таким же способом можно получить время и дату:
- %c — время и дата;
- %x — дата;
- %X — время.
date = datetime.datetime.today() print(date.strftime('%x'))
Обратите внимание, что таким способом мы преобразуем объект класса datetime в строку и мы больше не сможем использовать методы по работе с датой (например сравнение):
import datetime date = datetime.datetime.today() local_date = date.strftime('%d-%m-%Y %H:%M') print('Объект класса datetime: ', type(date)) print('Дата преобразованная в строку: ', type(local_date)) print(local_date.day)
Мы получим ошибку так как уже работаем со строкой:
- AttributeError: ‘str’ object has no attribute ‘day’
Выше описаны основные возможности форматирования используя метод strftime(), но их, конечно, больше.
Получения дня недели и название месяца
Можно получить название дня недели или название. Численный вариант эквивалентен следующим значениям:
- 0 — Monday (Понедельник);
- 1 — Tuesday (Вторник);
- 2 — Wednesday (Среда);
- 3 — Thursday (Четверг);
- 4 — Friday (Пятница);
- 5 — Saturday (Суббота);
- 6 — Sunday (Воскресенье).
Следующий пример вернет день недели в виде числа:
date = datetime.datetime.today() print(date.weekday())
Или получить название:
date = datetime.datetime.today() print(date.strftime('%A')) print(date.strftime('%a'))- %A — полное название дня недели;
- %a — сокращенное название дня недели;
- %s — представление в виде числа.
Такой же принцип по работе с месяцами, где:
- %B — полное название месяца;
- %b — сокращенное название месяца;
- %m — месяц в виде числа.
Создание объекта даты и времени
Для создания даты используется класс с аргументами date(год, месяц, число):
date = datetime.date(2019, 1, 13) print(date, type(date))
Можно создать дату и время. В обоих случаях мы можем использовать именованные аргументы если так удобнее:
date_time = datetime.datetime(year = 2019, month = 2, day = 4, hour = 7, minute = 9, second = 13 ) print(date_time, type(date_time))
Каждый аргумент времени, по умолчанию, имеет значение 0. Мы так же можем использовать подход выше для получения, например, только года или времени:
date_time = datetime.datetime(year = 2019, month = 2, day = 4, second = 13 ) # Получаем только время time = date_time.strftime('%X') print(time, type(time)) date = datetime.date( year = 2018, month = 5, day = 3 ) # Получаем только год year = date.year print(year, type(year))
Если вы не укажете год, месяц или день, то получите ошибку т.к. они по умолчанию равны None:
- TypeError: Required argument ‘year’ (pos 1) not found
Есть отдельный класс для создания времени time:
time = datetime.time(12, 33, second=33, microsecond=122) print(time, type(time)) print(time.hour)
Создание из строк
Используя strptime() можно создавать объект datetime из строки:
date_string = '21 September. 1999' date_object = datetime.strptime(date_string, '%d %B. %Y') print(date_object, type(date_object))
Продолжительность времени с timedelta
timedelta — это класс с помощью которого можно установить не дату, как в примерах выше, а продолжительность. Так мы создадим объект с 12 днями и 33 секундами:
duration_time = datetime.timedelta(days = 12, seconds = 33) print(duration_time, type(duration_time))
Все атрибуты, которые мы можем указывать для этого класса:
- days
- seconds
- microseconds
- milliseconds
- minutes
- hours
Кроме этого мы можем преобразовывать эти объекты в секунды:
duration_time = datetime.timedelta(minutes = 1, seconds = 10) # Преобразуем в секунды seconds = duration_time.total_seconds() print(seconds, type(seconds))
Разница между датами
Мы можем искать разницу между датами получая объект timedelta:
date_now = datetime.datetime.now() date_tomorrow = datetime.datetime(2019, 12, 29) # Вычисляем разницу между датами difference = date_tomorrow - date_now print(difference, type(difference)) print('Разница только в днях: ', difference.days)
Изменение объектов
Каждый их объектов выше можно изменить. Так мы изменим объект timedelta прибавив часы к минутам:
duration_hours = datetime.timedelta(hours = 1) duration_minutes = datetime.timedelta(minutes = 10) result = duration_hours + duration_minutes print(result, type(result))
С помощью timedelta изменяется и дата. Пример ниже изменяет текущую дату прибавляя к ней 1 день и 1 час:
date_now = datetime.datetime.now() duration_minutes = datetime.timedelta(days=1, minutes=10) result = date_now + duration_minutes print(result, type(result))
Сравнение и условия
Каких либо хитростей в сравнении объектов нет. В следующем примере идет сравнение двух дат с разницей в день:
date_one = datetime.datetime(2017,12,1) date_two = datetime.datetime(2017,12,2) if date_two > date_one: print(' больше чем '.format(date_two, date_one))
При этом стоит проверять, что объекты относятся к классу datetime, а не являются строками. В следующем примере мы сравниваем года, но они уже относятся к численным:
date_one = datetime.datetime(2017,12,1) date_two = datetime.datetime(2017,12,2) if date_two.year == date_one.year: print('Год одинаковый. Тип данных: ', type(date_two.year))
Объект timedelta тоже можно сравнивать:
time_one = datetime.timedelta(seconds=2) time_two = datetime.timedelta(minutes=1) if time_one < time_two: print('Pass')
Работа с метками (штампами) timestamp
При работе с API или в Unix системах мы можем увидеть отображение времени в таком формате:
1578238360Данные числа обозначают количество секунд с 1 января 1970 года. Мы можем конвертировать данное число в понятный формат используя datetime:
timestamp = date.fromtimestamp(1578238360) print(timestamp)
Так же сработает если мы хотим получить и время:
timestamp = datetime.fromtimestamp(1578238360) print(timestamp)
Для конвертирования в timestamp используется метод с аналогичным названием:
from datetime import datetime date_now = datetime.now() print(date_now.timestamp)
Работа с часовыми поясами
К сожалению у меня нет большого опыта работы с часовыми поясами и примеры ниже не стоит рассматривать как лучшие практики.
Библиотека datetime не хранит часовые пояса, данные о переводах часов (летнее и зимнее время) и високосных секундах. К тому же, некоторые страны, могут изменить время опираясь на локальные ситуации. Эти ситуации опасны, когда идет запись в базу данных. Для вывода в GUI, можно использовать datetime.datetime.now() или высчитывать часовой пояс из базы.
Для записи в базу данных мы можем использовать время UTC и отдельно считать часовой пояс:
utc = datetime.datetime.utcnow() print(utc)
Следующий пример вычислит разницу времени между UTC и локальным. Насколько я знаю он может не сработать на версиях Python < 3.3:
gmt = datetime.today() - datetime.utcnow() print(gmt)
Для вычисления других часовых поясов можно использовать стороннюю библиотеку pytz, которая их хранит:
pip install pytzВывести все часовые пояса мы можем так:
import pytz for tz in pytz.all_timezones: print(tz)
На примере ниже я перевожу локальное время в часовой пояс Киева:
import pytz from datetime import datetime tz_kiev = pytz.timezone('Europe/Kiev') time_kiev = datetime.now(tz_kiev) print(time_kiev)Класс 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
X Скрыть Наверх
Даты и время в Python. Курс
Классы time и timezone модуля datetime. Работа со временем в Python
Экземпляры, создаваемые от класса time модуля datetime , предназначены для хранения времени суток (без даты).
Вызов конструктора time без передачи аргументов создает объект времени полуночи (начала суток), а не текущего момента.

В конструктор можно передать час, минуту, секунду и микросекунду (одна миллионная секунды) фиксируемого момента. Все аргументы являются опциональными.
from datetime import time a = time(10, 30) print(a.strftime("%H:%M")) # 10:30 b = time(minute=3, second=37) print(b) # 00:03:37 c = time(microsecond=830_000) print(c.microsecond) # 830000 print(c.__repr__()) # datetime.time(0, 0, 0, 830000)
Класс time модуля datetime не выполняет автоматическое преобразование значений, превышающих 59 минут в часы и секунд в минуты, больше 23 часа – в сутки, а значение в один миллион микросекунд – в секунду. Поэтому числовые параметры hour , minute , second , microsecond имеют соответствующие им ограничения.

По аналогии с date , объект time можно получить из строки соответствующего ISO-формата, используя классовый метод fromisoformat .
from datetime import time a = time.fromisoformat("20:18:30") print("A:", a) print(repr(a)) b = time.fromisoformat("00:02:09:004000") print("\nB:", b) print(repr(b)) c = time.fromisoformat("11:00+03:00") print("\nC:", c) print(repr(c))
A: 20:18:30 datetime.time(20, 18, 30) B: 00:02:09.004000 datetime.time(0, 2, 9, 4000) C: 11:00:00+03:00 datetime.time(11, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=10800)))
В примере при создании третьего объекта мы указываем смещение времени от UTC (всемирного времени – это примерно то же самое, что по Гринвичу – GMT). При этом у объекта свойство tzinfo оказывается связанным с экземпляром timezone .
Хотя в литерале "11:00+03:00" пишется плюс, если в часовом поясе, отстоящем от UTC на три часа на восток, 11 часов утра, то в этот самый момент в часовом поясе, где непосредственно действует UTC, будет 8 часов утра, то есть на три часа меньше. Если переместиться от UTC на один часовой пояс на запад, там будет 7 часов утра: "07:00-01:00" .
from datetime import time utc = time.fromisoformat("08:00+00:00") east3 = time.fromisoformat("11:00+03:00") west1 = time.fromisoformat("07:00-01:00") print(east3 == utc) # True print(east3 == west1) # True
Из примера мы видим, что в Python объекты времени можно сравнивать между собой. Однако лучше этого не делать, если одним операндом является "осведомленное" (aware) время, а другим – "наивное" (naive), то есть время без часового пояса. В таких случаях оператор == всегда возвращает False , != всегда True , а сравнения > , , >= , недопустимы (выбрасывается TypeError ). Поэтому следует сравнивать либо только экземпляры времени с часовым поясом, либо только без него.

Выбор между осведомленным и наивным временем зависит от ситуации. Если, например, важны отрезки времени, измеряется продолжительность какой-либо активности, то часовые пояса ни к чему. Если планируется онлайн-мероприятие для людей из разных часовых поясов, придется учитывать, что в конкретный момент времени у них будет разное время на часах.
Вернемся к получению объекта через конструктор и рассмотрим параметр tzinfo , которому присваивается экземпляр timezone , который создается через передачу в его конструктор экземпляра timedelta .
from datetime import time, timezone, timedelta tz = timezone(timedelta(hours=10, minutes=50)) a = time(12, 35, 28, tzinfo=tz) b = time(11, 40, tzinfo=timezone(timedelta(hours=-5))) print(a) # 12:35:28+10:50 print(b) # 11:40:00-05:00
В данном случае на таймдельту накладываются ограничения. Задаваемый промежуток времени должен быть по модулю меньше длины одних суток.
С помощью метода utcoffset можно получить смещение времени относительно UTC. Если быть точнее, метод просто возвращает ссылку на объект таймдельты.
from datetime import time, timezone, timedelta a = time(12, tzinfo=timezone(timedelta(hours=3))) b = time(11, tzinfo=timezone(timedelta(hours=-1))) a_offset = a.utcoffset() b_offset = b.utcoffset() print(a_offset) print(a_offset.__repr__(), end="\n\n") print(b_offset) print(b_offset.__repr__()) print("\nРазница в часовых поясах:") print(abs(b_offset - a_offset))
3:00:00 datetime.timedelta(seconds=10800) -1 day, 23:00:00 datetime.timedelta(days=-1, seconds=82800) Разница в часовых поясах: 4:00:00
Такое странное представление смещения от UTC на 1 час меньше (минус 1 день плюс 23 часа) связано с внутренним устройством объектов timedelta . У них нет свойства hours , поэтому часы конвертируются в секунды. Кроме того свойство seconds не может хранить отрицательных значений.
Узнать смещение можно не только через метод utcoffset экземпляра time . Также можно обратиться к полю tzinfo этого же экземпляра. Однако следует иметь в виду, что последнее связано с экземпляром timezone , который имеет свой метод utcoffset . И в данном случае в него надо передавать None .
from datetime import time, timezone, timedelta a = time(12, tzinfo=timezone(timedelta(hours=3))) print(a.tzinfo) # UTC+03:00 offset = a.tzinfo.utcoffset(None) # экземпляр timedelta print(offset) # 3:00:00 zn = a.tzinfo.tzname(None) # экзепляр str print(zn) # UTC+03:00
Метод tzname есть и у time . Он также возвращает строку в формате UTC±HH:MM, если только не было задано произвольное наименование часового пояса.
from datetime import time, timezone, timedelta a = time(12, tzinfo=timezone(timedelta(hours=3), name="Moscow")) b = time(8, tzinfo=timezone(timedelta(hours=0))) print(a.tzname()) # Moscow print(b.tzname()) # UTC
В мире существуют не только разные часовые пояса. Также в ряде стран переходят на так называемое летнее время (daylight saving time – DST), когда в течение полугода к стандартному смещению часового пояса от UTC добавляется еще один час. Обычно это делают в последнее воскресенье марта, а возвращаются к стандартному поясному времени в последнее воскресенье октября.
Класс timezone не позволяет учитывать DST. Однако на самом деле не обязательно передавать параметру tzinfo объект типа timezone . Самое главное передавать туда экземпляр, созданный от любого подкласса класса tzinfo . Класс timezone является одним из подклассов этого класса.
Другими словами, вы можете написать свой класс, который будет работать с DST.
Обратим внимание, что есть параметр tzinfo конструктора time , есть соответствующее ему свойство объекта, а есть абстрактный класс tzinfo модуля datetime .
При создании экземпляров от datetime не обязательно разрабатывать свой подкласс от tzinfo , чтобы учитывать не только часовые пояса, но и переход на летнее время. В Python есть готовое решение в виде модуля zoneinfo , который подключается к внешней базе данных часовых поясов (есть в системе или устанавливается отдельно). Класс ZoneInfo из модуля zoneinfo является наследником класса tzinfo из модуля datetime .
Атрибуты класса time (подчеркнуты не упомянутые в уроке):
- данные, хранимые в классе (свойства класса): min , max , resolution
- методы класса: fromisoformat
- свойства экземпляра: hour , minute , second , microsecond , tzinfo , fold
- методы экземпляра: replace , isoformat , strftime , utcoffset , dst , tzname
X Скрыть Наверх
Даты и время в Python. Курс
Работа с датами и временем в Python
У нас есть описание модуля time, продолжим изучать работу с временем.
Datetime — важный элемент любой программы, написанной на Python. Этот модуль позволяет управлять датами и временем, представляя их в таком виде, в котором пользователи смогут их понимать.
datetime включает различные компоненты. Так, он состоит из объектов следующих типов:
- date — хранит дату
- time — хранит время
- datetime — хранит дату и время
Класс date
Для работы с датами воспользуемся классом date, который определен в модуле datetime. Для создания объекта date мы можем использовать конструктор date, который последовательно принимает три параметра: год, месяц и день.date(year, month, day)
Например, создадим какую-либо дату:
yesterday = datetime.date(2017,5, 2)
print(yesterday) # 2017-05-02Если необходимо получить текущую дату, то можно воспользоваться методом today():
from datetime import date
today = date.today()
print(today) # 2017-05-03
print(“<>.<>.<>”.format(today.day, today.month, today.year)) # 2.5.2017С помощью свойств day, month, year можно получить соответственно день, месяц и год/
Класс time
За работу с временем отвечает класс time. Используя его конструктор, можно создать объект времени:time([hour] [, min] [, sec] [, microsec])
Конструктор последовательно принимает часы, минуты, секунды и микросекунды. Все параметры необязательные, и если мы какой-то параметр не передадим, то соответствующее значение будет инициализироваться нулем.
from datetime import time
current_time = time()
print(current_time) # 00:00:00current_time = time(16, 25)
print(current_time) # 16:25:00current_time = time(16, 25, 45)
print(current_time) # 16:25:45Класс datetime
Класс datetime из одноименного модуля объединяет возможности работы с датой и временем. Для создания объекта datetime можно использовать следующий конструктор:datetime(year, month, day [, hour] [, min] [, sec] [, microsec])
Первые три параметра, представляющие год, месяц и день, являются обязательными. Остальные необязательные, и если мы не укажем для них значения, то по умолчанию они инициализируются нулем.
from datetime import datetime
deadline = datetime(2017, 5, 10)
print(deadline) # 2017-05-10 00:00:00deadline = datetime(2017, 5, 10, 4, 30)
print(deadline) # 2017-05-10 04:30:00Для получения текущих даты и времени можно вызвать метод now():
from datetime import datetime
now = datetime.now()
print(now) # 2017-05-03 11:18:56.239443print(“<>.<>.<> <>:<>”.format(now.day, now.month, now.year, now.hour, now.minute)) # 3.5.2017 11:21
С помощью свойств day, month, year, hour, minute, second можно получить отдельные значения даты и времени. А через методы date() и time() можно получить отдельно дату и время соответственно.
Преобразование из строки в дату
Из функциональности класса datetime следует отметить метод strptime(), который позволяет распарсить строку и преобразовать ее в дату. Этот метод принимает два параметра:Первый параметр str представляет строковое определение даты и времени, а второй параметр – формат, который определяет, как различные части даты и времени расположены в этой строке.
Для определения формата мы можем использовать следующие коды:
%d: день месяца в виде числа
%m: порядковый номер месяца
%y: год в виде 2-х чисел
%Y: год в виде 4-х чисел
%H: час в 24-х часовом формате
Применим различные форматы:
from datetime import datetime
deadline = datetime.strptime(“22/05/2017”, “%d/%m/%Y”)
print(deadline) # 2017-05-22 00:00:00deadline = datetime.strptime(“22/05/2017 12:30”, “%d/%m/%Y %H:%M”)
print(deadline) # 2017-05-22 12:30:00deadline = datetime.strptime(“05-22-2017 12:30”, “%m-%d-%Y %H:%M”)
print(deadline) # 2017-05-22 12:30:00С помощью модуля Python это сделать очень просто. Сначала нужно импортировать класс datetime из модуля datetime , после чего создать объект datetime . Модуль предоставляет метод now() , который возвращает текущие дату и время с учетом локальных настроек.
import datetime dt_now = datetime.datetime.now() print(dt_now)А вот результат:
Получить текущую дату в Python
Класс date можно использовать для получения или изменения объектов даты. Например, для получения текущей с учетом настроек подойдет следующее:
from datetime import date current_date = date.today() print(current_date)Текущая дата — 2020-11-14 в формате год-месяц-день соответственно.
Получить текущее время
Для получения текущего локального времени сперва нужно получить текущие дату и время, а затем достать из этого объекта только время с помощью метода time() :
import datetime current_date_time = datetime.datetime.now() current_time = current_date_time.time() print(current_time)Компоненты datetime в Python
Модуль datetime в Python может использоваться для получения разных версий времени. Для этого нужно ознакомиться с атрибутами модуля. Используем для этого функцию dir() .
import datetime attr = dir(datetime) print(attr) # ['MAXYEAR', 'MINYEAR', '__doc__', '__name__', '__package__', 'date', 'datetime', # 'datetime_CAPI', 'time', 'timedelta', 'tzinfo']В этом руководстве речь пойдет о следующих элементах:
- date — объекты даты
- datetime — объекты даты и времени
- time — объекты времени
- timedelta — этот атрибут покрывает интервалы и используется для определения прошлых или будущих событий
- Tzinfo — этот атрибут отвечает за часовые пояса
Как создавать объекты даты и времени
Для создания объекта времени используется класс time из модуля datetime в Python. Синтаксис следующий: datetime.time(hour, minutes, seconds) .
В этом примере создается объект времени представленный следующим образом (8, 48, 45).
import datetime timeobj= datetime.time(8,48,45) print(timeobj)Сначала импортируется модуль datetime . После этого создается экземпляр класса (объект time ). Затем ему присваивается значение datetime.time(8, 48, 45) , где параметры 8, 48 и 45 представляют собой часы, минуты и секунды соответственно.
Для создания объекта даты нужно передать дату с использованием следующего синтаксиса:
datetime.datetime(year,month,day))
import datetime date_obj = datetime.datetime(2020,10,17) print(date_obj)Вернет вот такой результат:
Timedelta
timedelta представляет длительность (даты или времени). Модуль datetime включает атрибут timedelta() , который используется для управления датой в Python. Объект timedelta выглядит следующим образом:
td_object =timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) td_object datetime.timedelta(0)Все аргументы опциональные и их значения по умолчанию равно 0. Они могут быть целыми или числами с плавающей точкой, как положительными, так и отрицательными. Благодаря этому можно выполнять математические операции, такие как сложение, вычитание и умножение.
Как вычислить разницу для двух дат
Посмотрим на несколько примеров вычисления разницы во времени. Предположим, есть два объекта datetime :
first_date = date(2020, 10, 2)
second_date = date(2020, 10, 30)
Для получения разницы нужно лишь вычесть значение одного объекта из второго:
from datetime import date first_date = date(2020, 10, 2) second_date = date(2020, 10, 30) delta = second_date - first_date print(delta)Таким образом между 2 и 30 октября 2020 года 28 дней.
Как вычислить разницу двух объектов datetime.time
С помощью timedelta нельзя выполнять манипуляции над объектами time . Например:
from datetime import datetime, timedelta current_datetime = datetime.now() current_time = current_datetime.time() print("Текущее время:", current_time) tm_after_1_hr = current_time + timedelta(hours=1) print(tm_after_1_hr)Такой код вернет следующую ошибку:
Traceback (most recent call last): File “C:\Users\alex\AppData\Local\Programs\Python\Python38\sg_verify.py”, line 6, in tm_after_1_hr = current_time + timedelta(hours=1) TypeError: unsupported operand type(s) for +: ‘datetime.time’ and ‘datetime.timedelta’
Как получать прошлые и будущие даты с помощью timedelta
Поскольку timedelta — это длительность, то для получения прошлой или будущей даты нужно добавить объект timedelta к существующему или вычесть из него же. Вот пример нескольких уравнений, где n — это целое число, представляющее количество дней:
import datetime current_date = datetime.datetime.today() past_date = datetime.datetime.today() – datetime.timedelta(days=n) future_date = datetime.datetime.today() – datetime.timedelta(days=n)Если нужно, например, получить дату за прошлые две недели, то достаточно вычесть 14 дней из текущей даты:
import datetime past_date = datetime.datetime.today() - datetime.timedelta(days=14) print(past_date)Предположим, вы задумали практиковать определенный навык в течение 21 дня. Для получения будущей даты нужно добавить 21 день к текущей дате:
import datetime future_date = datetime.datetime.today() + datetime.timedelta(days=21) print(future_date)Другие арифметические операции с timedelta
Значения даты и времени могут сравниваться для определения того, какая из них была раньше или позже. Например:
import datetime now = datetime.time(9, 31, 0) next_hour = datetime.time(10, 31, 0) print('now < next_hour:', now < next_hour) today = datetime.date.today() next_week = datetime.date.today() + datetime.timedelta(days=7) print('today >next_week:', today > next_week)today > next_week: False
Часовые пояса
Пока что мы работали с datetime без учета часовых поясов и летнего времени. Но прежде чем переходить к следующим пунктам, нужно разобраться с разницей в абсолютных (naive) и относительных (aware) датах.
Абсолютные даты не содержат информацию, которая бы могла определить часовой пояс или летнее время. Однако с такими намного проще работать.
Относительные же содержат достаточно информации для определения часового пояса или отслеживания изменений из-за летнего времени.
Разница между DST, GMT и UTC
- GMT
Официальный часовой пояс, используемый в некоторых странах Европы и Африки. Он может быть представлен как в 24, так и в 12-часовом форматах. GMT используется для того, чтобы задавать местное время. Например, местное время для Берлина 2020–10–17 09:40:33.614581+02:00 GMT. Для Найроби же это — 2020–10–17 10:40:33.592608+03:00 GMT. - DST (летнее время)
Страны, которые переходят на летнее время, делают это для того, чтобы дневное время длилось как можно дольше. Во время летнего времени они переводят стрелки своих часов на час вперед и возвращаются обратно осенью. - UTC (всемирное координированное время)
Временной стандарт для часовых поясов во всем мире. Он позволяет синхронизировать время во всем мире и служит отправной точкой для остальных.
Как работать с часовыми поясами
Рассмотрим, как создать простой относительный объект datetime :
import datetime dt_now = datetime.datetime.utcnow() print(dt_now)Эта программа возвращает объект с абсолютным значением datetime . Если же нужно сделать его абсолютным, то нужно явно указать часовой пояс. Как это сделать? В библиотеке datetime в Python нет модуля для работы с часовыми поясами. Для этого нужно использовать другие библиотеки. Одна из таких — pytz.
Предположим, нужно получить текущее время для Найроби. Для этого нужно использовать конкретный часовой пояс. Для начала можно с помощью pytz получить все существующие часовые пояса.
import pytz pytz.all_timezonesВот некоторые из них:
[‘Africa/Abidjan’, ‘Africa/Accra’, ‘Africa/Addis_Ababa’, ‘Africa/Nairobi’]
Для получения времени в Найроби:
import pytz import datetime tz_nairobi = pytz.timezone("Africa/Nairobi") dt_nairobi =datetime.datetime.now(tz_nairobi) print(dt_nairobi)А вот так можно получить время Берлина:
import pytz import datetime tz_berlin = pytz.timezone("Europe/Berlin") dt_berlin =datetime.datetime.now(tz_berlin) print(dt_berlin)Здесь можно увидеть разницу в часовых поясах разных городов, хотя сама дата одна и та же.
Конвертация часовых поясов
При конвертации часовых поясов в первую очередь нужно помнить о том, что все атрибуты представлены в UTC. Допустим, нужно конвертировать это значение в America/New_York :
import datetime import pytz timezone_berlin = '2019-06-29 17:08:00' tz_ber_obj = datetime.datetime.strptime(timezone_berlin, '%Y-%m-%d %H:%M:%S') timezone_newyork = pytz.timezone('America/New_York') timezone_newyork_obj = timezone_newyork.localize(tz_ber_obj) print(timezone_newyork_obj) print(timezone_newyork_obj.tzinfo)2019-06-29 17:08:00-04:00 America/New_York
Другие практические примеры
Всегда храните даты в UTC. Вот примеры:
import datetime import pytz time_now = datetime.datetime.now(pytz.utc) print(time_now)Результат для этого кода — 2020-11-14 14:38:46.462397+00:00 , хотя локальное время может быть, например, таким 2020-11-14 16:38:46.462397+00:00 . А уже при демонстрации даты пользователю стоит использовать метод localize с местными настройками:
import datetime import pytz now = datetime.datetime.today() now_utc = pytz.utc.localize(now)Вернет текущее локальное время — 2020-11-14 16:42:38.228528+00:00 .
Как конвертировать строки в datetime
strptime() в Python — это метод из модуля datetime. Вот его синтаксис:
dateobj = datetime.strptime(date_string, format)
Аргументы формата необязательные и являются строками. Предположим, нужно извлечь текущие дату и время:
import datetime current_dt = datetime.datetime.now() print(current_dt)Результат будет в формате ISO 8601, то есть YYYY-MM-DDTHH:MM:SS.mmmmmm — формат по умолчанию, что позволяет получать строки в едином формате.
Символ Описание Пример %a День недели, короткий вариант Wed %A Будний день, полный вариант Wednesday %w День недели числом 0-6, 0 — воскресенье 3 %d День месяца 01-31 31 %b Название месяца, короткий вариант Dec %B Название месяца, полное название December %m Месяц числом 01-12 12 %y Год, короткий вариант, без века 18 %Y Год, полный вариант 2018 %H Час 00-23 17 %I Час 00-12 05 %p AM/PM PM %M Минута 00-59 41 %S Секунда 00-59 08 %f Микросекунда 000000-999999 548513 %z Разница UTC +0100 %Z Часовой пояс CST %j День в году 001-366 365 %U Неделя числом в году, Воскресенье первый день недели, 00-53 52 %W Неделя числом в году, Понедельник первый день недели, 00-53 52 %c Локальная версия даты и времени Mon Dec 31 17:41:00 2018 %x Локальная версия даты 12/31/18 %X Локальная версия времени 17:41:00 %% Символ “%” %
import datetime date_string = "11/17/20" date_obj = datetime.datetime.strptime(date_string, '%m/%d/%y') print(date_obj)Примеры конвертации строки в объект datetime с помощью strptime
Предположим, что есть следующая строка с датой: «11/17/20 15:02:34», и ее нужно конвертировать в объект datetime .
from datetime import datetime datetime_string = "11/17/20 15:02:34" datetime_obj = datetime.strptime(datetime_string, '%m/%d/%y %H:%M:%S') print(datetime_obj)Даты могут быть записаны в разных форматах. Например, следующие даты отличаются лишь представлением:
- Friday, November 17, 2020;
- 11/17/20;
- 11–17–2020.
Вот как это работает:
from datetime import datetime # создадим даты как строки ds1 = 'Friday, November 17, 2020' ds2 = '11/17/20' ds3 = '11-17-2020' # Конвертируем строки в объекты datetime и сохраним dt1 = datetime.strptime(ds1, '%A, %B %d, %Y') dt2 = datetime.strptime(ds2, '%m/%d/%y') dt3 = datetime.strptime(ds3, '%m-%d-%Y') print(dt1) print(dt2) print(dt3)Результат будет одинаковым для всех форматов:
Практические примеры
Если строка представлена в формате «Oct 17 2020 9:00PM», то ее можно конвертировать следующим образом:
date_string = 'Oct 17 2020 9:00PM' date_object = datetime.strptime(date_string, '%b %d %Y %I:%M%p') print(date_object)Результат — 2020-10-17 21:00:00 .
Функцию strptime() можно использовать для конвертации строки в объект даты:
from datetime import datetime date_string = '10-17-2020' date_object = datetime.strptime(date_string, '%m-%d-%Y').date() print(type(date_object)) print(date_object)Как конвертировать объект datetime в строку
Модуль datetime в Python содержит метод strftime() , который делает обратное (то есть, конвертирует объект datetime и time в строки). Вот его синтаксис:
datetime_string = datetime_object.strftime(format_string) time_string = datetime_object.strftime(format_string[,time_object])
Примеры конвертации datetime в строку с помощью strftime()
Предположим, нужно конвертировать текущий объект datetime в строку. Сначала нужно получить представление объекта datetime и вызвать на нем метод strftime() .
import datetime current_date = datetime.datetime.now() current_date_string = current_date.strftime('%m/%d/%y %H:%M:%S') print(current_date_string)Результат — 11/14/20 17:15:03 .
Как получить строковое представление даты и времени с помощью функции format()
Пример №1. Конвертация текущей временной метки в объекте datetime в строку в формате «DD-MMM-YYYY (HH:MM:SS:MICROS)»
import datetime dt_obj =datetime.datetime.now() dt_string = dt_obj.strftime("%d-%b-%Y (%H:%M:%S.%f)") print('Текущее время : ', dt_string)Текущее время : 14-Nov-2020 (17:18:09.890960)
Пример №2.
Конвертация текущей временной метки объекта datetime в строку в формате «HH:MM:SS.MICROS – MMM DD YYYY».
import datetime dt_obj =datetime.datetime.now() dt_string = dt_obj.strftime("%H:%M:%S.%f - %b %d %Y") print('Текущее время : ', dt_string)Текущее время : 17:20:28.841390 – Nov 14 2020
Другие datetime-библиотеки в Python
В Python есть и другие библиотеки, которые упрощают процесс манипуляций с объектами datetime. В некоторых из них есть поддержка часовых поясов.
Arrow
Arrow — еще один популярный модуль, который делает более простым процесс создания, управления и форматирования дат и времени. Получить его можно с помощью pip. Для установки достаточно ввести pip install arrow .
Arrow можно использовать для получения текущего времени по аналогии с модулем datetime:
import arrow current_time = arrow.now() print(current_time) print(current_time.to('UTC'))Maya
Maya упрощает процесс парсинга строк и конвертации часовых поясов. Например:
import maya dt = maya.parse('2019-10-17T17:45:25Z').datetime() print(dt.date()) print(dt) print(dt.time())Dateutil
Dateutil — это мощная библиотека, которая используется для парсинга дат и времени в разных форматах. Вот некоторые примеры.
from dateutil import parser dt_obj = parser.parse('Thu Oct 17 17:10:28 2019') print(dt_obj) dt_obj1=parser.parse('Thursday, 17. October 2019 5:10PM') print(dt_obj1) dt_obj2=parser.parse('10/17/2019 17:10:28') print(dt_obj2) t_obj=parser.parse('10/17/2019') print(t_obj)Важно, что в этом случае не нужны регулярные выражения при определении формата. Парсер ищет узнаваемые токены и либо возвращает корректный результат, либо выдает ошибку.
Важные нюансы
Вот о чем важно помнить при работе с datetime в Python:
- Рекомендуется всегда работать с UTC. Это позволяет не думать о часовых поясах, что часто приводит к ошибкам из-за разницы во времени в разных регионах.
- Дату и время стоит конвертировать в локальную только при выводе пользователю.
Выводы
Есть масса сценариев работы с датой и временем в реальных приложениях. Например:
- Запланировать работу скрипта на определенное время.
- Отфильтровать даты.
- Извлечь дату из определенных API каждый день, в определенное время.
- Приложения для отслеживания событий, записей, бронирования и так далее.
Особенности, которые заметил:
1. Не допускается прописывать нули перед номерами дней, месяцев, часов и пр.
как собственно и перед простыми целыми числами
yesterday = datetime.date(2021, 07, 01) # не сработает
но в методе strptime() это допускается, т.к. дата и время прописываются как строка2. классы реализуют проверку корректности введенных дат и времени
(например проконтролирует 29 февраля для високосного года)Почему вот так не работает?
import datetime
today = datetime.today()
print(today)В классе datetime нет метода today().
вы должны вызвать класс datetime затем подкласс datetime or date и затем метод.
т.е. today = datetime.date.today() or datetime.datetime.today()
