datetime — Базовые типы для представления даты и времени

Исходный код: Lib/datetime.py


Модуль datetime предоставляет классы для управления датой и временем.

Основное внимание в реализации уделяется эффективному извлечению атрибутов для форматирования и обработки вывода; арифметика даты и времени также поддерживается.

См.также

Модуль calendar
Общие календарные функции.
Модуль time
Доступ к времени и преобразования.
Пакет dateutil
Сторонняя библиотека с расширенной поддержкой часовых поясов и парсинга.

Осведомлённые и наивные объекты

Объекты даты и времени могут быть разделены на «осведомлённые» или «наивные» в зависимости от того, включают ли они информацию о часовом поясе или нет.

Обладая достаточными знаниями о применимых алгоритмических и политических настройках времени, таких как информация о часовом поясе и переходе на летнее время, осведомлённый объект может расположить себя относительно других осведомлённых объектов. Осведомлённый объект представляет собой конкретный момент времени, который не подлежит интерпретации. [1]

Наивный объект не содержит достаточно информации, чтобы однозначно расположить себя относительно других объектов даты/времени. Независимо от того, представляет ли наивный объект всемирное координированное время (UTC), местное время или время в каком-либо другом часовом поясе, зависит исключительно от программы, точно так же, как это зависит от программы, представляет ли конкретное число метры, мили или массу. Наивные объекты легко понять и с ними легче работать за счёт игнорирования некоторых аспектов реальности.

Для приложений, требующих осведомлённых объектов, объекты datetime и time имеют необязательный атрибут информации о часовом поясе, tzinfo, который может быть установлен как экземпляр подкласса абстрактного класса tzinfo. Эти объекты tzinfo собирают информацию о смещении от времени UTC, имени часового пояса и о том, действует ли летнее время.

Только один конкретный класс tzinfo, класса timezone, поставляется модулем datetime. Класс timezone может представлять простые часовые пояса с фиксированными смещениями от UTC, например, сам UTC или часовые пояса EST и EDT в Северной Америке. Поддержка часовых поясов на более глубоких уровнях детализации зависит от приложения. Правила корректировки времени во всем мире носят скорее политический, чем рациональный характер, часто меняются, и нет стандарта, подходящего для всех приложений, кроме UTC.

Константы

Модуль datetime экспортирует следующие константы:

datetime.MINYEAR

Наименьший номер года, разрешенный в объекте date или datetime. MINYEAR — это 1.

datetime.MAXYEAR

Наибольший номер года, разрешенный в объекте date или datetime. MAXYEAR — это 9999.

Доступные типы

class datetime.date

Идеализированная наивная дата, предполагающая, что текущий Григорианский календарь всегда был и всегда будет в силе. Атрибуты: year, month и day.

class datetime.time

Идеализированное время, не зависящее от какого-либо конкретного дня, при условии, что каждый день имеет ровно 24*60*60 секунд. (Здесь нет понятия «дополнительные секунды».) Атрибуты: hour, minute, second, microsecond и tzinfo.

class datetime.datetime

Комбинация даты и времени. Атрибуты: year, month, day, hour, minute, second, microsecond и tzinfo.

class datetime.timedelta

Продолжительность, выражающая разницу между двумя экземплярами date, time или datetime с точностью до микросекунд.

class datetime.tzinfo

Абстрактный базовый класс для информационных объектов часового пояса. Они используются классами datetime и time для предоставления настраиваемого понятия корректировки времени (например, для учёта часового пояса и/или перехода на летнее время).

class datetime.timezone

Класс, реализующий абстрактный базовый класс tzinfo как фиксированное смещение от UTC.

Добавлено в версии 3.2.

Объекты этих типов неизменяемы.

Отношения подклассов:

object
    timedelta
    tzinfo
        timezone
    time
    date
        datetime

Общие свойства

У типов date, datetime, time и timezone есть следующие общие особенности:

  • Объекты этих типов неизменяемы.
  • Объекты этих типов являются хешируемыми, что означает, что их можно использовать в качестве ключей словаря.
  • Объекты этих типов поддерживают эффективный пиклинг (pickling) через модуль pickle.

Определение того, является ли объект осведомлённым или наивным

Объекты типа date всегда наивны.

Объект типа time или datetime может быть осведомлённым или наивным.

Объект d datetime может быть осведомлённым, если выполняются оба следующих условия:

  1. d.tzinfo не None
  2. d.tzinfo.utcoffset(d) не возвращает None

В противном случае d наивен.

Объект time t может быть осведомлённым, если выполняются оба следующих условия:

  1. t.tzinfo не None
  2. t.tzinfo.utcoffset(None) не возвращает None.

В противном случае t наивен.

Различие между осведомлёнными и наивными не применимо к объектам timedelta.

Объекты timedelta

Объект timedelta представляет продолжительность, разницу между двумя датами или временем.

class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

Все аргументы являются необязательными и по умолчанию равны 0. Аргументы могут быть целыми числами или числами с плавающей запятой, а также могут быть положительными или отрицательными.

Внутри хранятся только days, seconds и microseconds. Аргументы преобразуются в эти единицы:

  • Миллисекунда преобразуется в 1000 микросекунд.
  • Минута конвертируется в 60 секунд.
  • Час конвертируется в 3600 секунд.
  • Неделя конвертируется в 7 дней.

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

  • 0 <= microseconds < 1000000
  • 0 <= seconds < 3600*24 (количество секунд в одном дне)
  • -999999999 <= days <= 999999999

В следующем примере показано, как любые аргументы, кроме days, seconds и microseconds, «объединяются» и нормализуются в три результирующих атрибута:

>>> from datetime import timedelta
>>> delta = timedelta(
...     days=50,
...     seconds=27,
...     microseconds=10,
...     milliseconds=29000,
...     minutes=5,
...     hours=8,
...     weeks=2
... )
>>> # Остались только дни, секунды и микросекунды
>>> delta
datetime.timedelta(days=64, seconds=29156, microseconds=10)

Если какой-либо аргумент является числом с плавающей запятой и есть дробные микросекунды, дробные микросекунды, оставшиеся от всех аргументов, объединяются, и их сумма округляется до ближайшей микросекунды с использованием разрешения конфликтов от половины до чётности. Если аргумент не является числом с плавающей запятой, процессы преобразования и нормализации точны (информация не теряется).

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

Обратите внимание, что нормализация отрицательных значений поначалу может показаться неожиданной. Например:

>>> from datetime import timedelta
>>> d = timedelta(microseconds=-1)
>>> (d.days, d.seconds, d.microseconds)
(-1, 86399, 999999)

Атрибуты класса:

timedelta.min

Самый негативный объект timedelta, timedelta(-999999999).

timedelta.max

Самый положительный объект timedelta, timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999).

timedelta.resolution

Наименьшее возможное различие между не равными объектами timedelta, timedelta(microseconds=1).

Обратите внимание, что из-за нормализации timedelta.max> -timedelta.min. -timedelta.max не может быть представлен как объект timedelta.

Атрибуты экземпляра (только для чтения):

Атрибут Значение
days От -999999999 до 999999999 включительно
seconds От 0 до 86399 включительно
microseconds От 0 до 999999 включительно

Поддерживаемые операции:

Операция Результат
t1 = t2 + t3
Сумма t2 и t3. После этого t1-t2 ==
t3 и t1-t3 == t2 являются true. (1)
t1 = t2 - t3 Разность t2 и t3. После этого t1 == t2 - t3 и t2 == t1 + t3 являются true. (1)(6)
t1 = t2 * i or t1 = i * t2 Дельта, умноженная на целое число. Впоследствии t1 // i == t2 является true, представленное i != 0.
  В общем, t1 * i == t1 * (i-1) + t1 является true. (1)
t1 = t2 * f или t1 = f * t2 Дельта, умноженная на число с плавающей точкой. Результат округляется до ближайшего кратного timedelta.resolution с использованием округления наполовину к чётному.
f = t2 / t3 Деление (3) общей длительности t2 на единицу интервала t3. Возвращает объект float.
t1 = t2 / f или t1 = t2 / i Дельта делится на число float или int. Результат округляется до ближайшего кратного timedelta.resolution с использованием округления от половины до четности.
t1 = t2 // i или t1 = t2 // t3 Целочисленное деление, а остаток (если есть) выбрасывается. Во втором случае возвращается целое число. (3)
t1 = t2 % t3 Остаток рассчитывается как timedelta объект. (3)
q, r = divmod(t1, t2) Вычисляет частное и остальное: q = t1 // t2 (3) и r = t1 % t2. q является целым числом, а r timedelta объектом.
+t1 Возвращает timedelta объект с некоторым значением. (2)
-t1 Эквивалент timedelta(-t1.days, -t1.seconds, -t1.microseconds), и t1* -1. (1)(4)
abs(t) Эквивалентно +t при t.days >= 0 и -t когда t.days < 0. (2)
str(t) Возвращает строку в форме [D day[s], ][H]H:MM:SS[.UUUUUU], где D является отрицательным для отрицательных t. (5)
repr(t) Возвращает строковое представление объекта timedelta как требование конструктора с каноническим атрибутом значения.

Примечания:

  1. Это точно, но может выходить за пределы.

  2. Это точно и не может переполниться.

  3. Деление на 0 поднимает ZeroDivisionError.

  4. -timedelta.max не может быть представлен как объект timedelta.

  5. Строковые представления объектов timedelta нормализуются аналогично их внутреннему представлению. Это приводит к несколько необычным результатам для отрицательных временных дельт. Например:

    >>> timedelta(hours=-5)
    datetime.timedelta(days=-1, seconds=68400)
    >>> print(_)
    -1 day, 19:00:00
    
  6. Выражение t2 - t3 всегда будет равно выражению t2 + (-t3), за исключением случая, когда t3 равно timedelta.max; в этом случае первое даст результат, а второе — переполнение.

В дополнение к операциям, перечисленным выше, объекты timedelta поддерживают определенные операции сложения и вычитания с объектами date и datetime (см. ниже).

Изменено в версии 3.2: Теперь поддерживаются деление с округлением вниз и истинное деление объекта timedelta на другой объект timedelta, а также операции с остатками и функция divmod(). Теперь поддерживаются истинное деление и умножение объекта timedelta на объект float.

Поддерживаются сравнения объектов timedelta с некоторыми оговорками.

Сравнение == или != всегда возвращает bool, независимо от типа сравниваемого объекта:

>>> from datetime import timedelta
>>> delta1 = timedelta(seconds=57)
>>> delta2 = timedelta(hours=25, seconds=2)
>>> delta2 != delta1
True
>>> delta2 == 5
False

Для всех других сравнений (таких как < и >), когда объект timedelta сравнивается с объектом другого типа, возникает TypeError:

>>> delta2 > delta1
True
>>> delta2 > 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'datetime.timedelta' and 'int'

В логических контекстах объект timedelta считается истинным тогда и только тогда, когда он не равен timedelta(0).

Методы экземпляра:

timedelta.total_seconds()

Возвращает общее количество секунд, содержащихся в продолжительности. Эквивалентен td / timedelta(seconds=1). Для единиц интервала, отличных от секунд, используйте форму деления напрямую (например, td / timedelta(microseconds=1)).

Обратите внимание, что для очень больших интервалов времени (более 270 лет на большинстве платформ) этот метод будет терять точность в микросекундах.

Добавлено в версии 3.2.

Примеры использования: timedelta

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

>>> # Компоненты another_year складываются ровно в 365 дней
>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
...                          minutes=50, seconds=600)
>>> year == another_year
True
>>> year.total_seconds()
31536000.0

Примеры арифметики timedelta:

>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> ten_years = 10 * year
>>> ten_years
datetime.timedelta(days=3650)
>>> ten_years.days // 365
10
>>> nine_years = ten_years - year
>>> nine_years
datetime.timedelta(days=3285)
>>> three_years = nine_years // 3
>>> three_years, three_years.days // 365
(datetime.timedelta(days=1095), 3)

Объекты date

Объект date представляет дату (год, месяц и день) в идеализированном календаре, текущий Григорианский календарь неограниченно расширен в обоих направлениях.

1 января 1 года называется днём номер 1, 2 января 1 года называется днём номер 2 и так далее. [2]

class datetime.date(year, month, day)

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

  • MINYEAR <= year <= MAXYEAR
  • 1 <= month <= 12
  • 1 <= day <= количество дней в данном месяце и году

Если указан аргумент за пределами этих диапазонов, возникает ValueError.

Остальные конструкторы, все методы класса:

classmethod date.today()

Возвращает текущую местную дату.

Это эквивалент date.fromtimestamp(time.time()).

classmethod date.fromtimestamp(timestamp)

Возвращает местную дату, соответствующую метке времени POSIX, например, возвращенную time.time().

Может вызвать OverflowError, если метка времени выходит за пределы диапазона значений, поддерживаемых функцией localtime() платформы C, и OSError при сбое localtime(). Обычно это ограничивается годами с 1970 по 2038 год. Обратите внимание, что в системах, не относящихся к POSIX, которые включают дополнительные секунды в своё понятие метки времени, секунды координации игнорируются fromtimestamp().

Изменено в версии 3.3: Поднимается OverflowError вместо ValueError, если отметка времени выходит за пределы диапазона значений, поддерживаемых функцией localtime() платформы C. Поднимается OSError вместо ValueError при ошибке localtime().

classmethod date.fromordinal(ordinal)

Возвращает дату, соответствующую Пролептическому Григорианскому порядковому номеру, где 1 января 1 года имеет порядковый номер 1.

ValueError не поднимается, если только 1 <= ordinal <= date.max.toordinal(). Для любой даты d, date.fromordinal(d.toordinal()) == d.

classmethod date.fromisoformat(date_string)

Возвращает date, соответствующий date_string в формате YYYY-MM- DD:

>>> from datetime import date
>>> date.fromisoformat('2019-12-04')
datetime.date(2019, 12, 4)

Это обратное date.isoformat(). Поддерживается только формат YYYY-MM- DD.

Добавлено в версии 3.7.

classmethod date.fromisocalendar(year, week, day)

Возвращает date, соответствующий календарной дате ISO, указанной с указанием года, недели и дня. Это функция, обратная date.isocalendar().

Добавлено в версии 3.8.

Атрибуты класса:

date.min

Самая ранняя представимая дата, date(MINYEAR, 1, 1).

date.max

Самая последняя представимая дата, date(MAXYEAR, 12, 31).

date.resolution

Наименьшее возможное различие между объектами с разными датами, timedelta(days=1).

Атрибуты экземпляра (только для чтения):

date.year

Между MINYEAR и MAXYEAR включительно.

date.month

От 1 до 12 включительно.

date.day

От 1 до количества дней в данном месяце данного года.

Поддерживаемые операции:

Операция Результат
date2 = date1 + timedelta date2 — это timedelta.days дней, удалённых из date1. (1)
date2 = date1 - timedelta Вычисляет date2 так, что date2 + timedelta == date1. (2)
timedelta = date1 - date2 (3)
date1 < date2 date1 считается меньше date2, когда date1 предшествует date2 во времени.(4)

Примечания:

  1. date2 перемещается вперед во времени, если timedelta.days > 0, или назад, если timedelta.days < 0. Потом date2 - date1 == timedelta.days. timedelta.seconds и timedelta.microseconds игнорируются. OverflowError поднимается, если date2.year будет меньше MINYEAR или больше MAXYEAR.
  2. timedelta.seconds и timedelta.microseconds игнорируются.
  3. Это точно и не может быть переполнено. timedelta.seconds и timedelta.microseconds равны 0, а date2 + timedelta == date1 после.
  4. Другими словами, date1 < date2 тогда и только тогда, когда date1.toordinal() < date2.toordinal(). Сравнение даты вызывает TypeError, если другое сравнение также не является объектом date. Однако вместо этого возвращается NotImplemented, если другой компарат содержит атрибут timetuple(). Этот хук даёт возможность другим типам объектов даты реализовать сравнение смешанного типа. В противном случае, когда объект date сравнивается с объектом другого типа, возникает TypeError, если сравнение не является == или !=. В последнем случае возвращается False или True соответственно.

В логических контекстах все объекты date считаются истинными.

Методы экземпляра:

date.replace(year=self.year, month=self.month, day=self.day)

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

Пример:

>>> from datetime import date
>>> d = date(2002, 12, 31)
>>> d.replace(day=26)
datetime.date(2002, 12, 26)
date.timetuple()

Возвращает time.struct_time, например, time.localtime().

Часы, минуты и секунды равны 0, а флаг DST — -1.

d.timetuple() эквивалентен:

time.struct_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1))

где yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1 — номер дня в текущем году, начиная с 1 для 1 января.

date.toordinal()

Возвращает Пролептический григорианский порядковый номер даты, где у 1 января 1 года порядковый номер 1. Для любого объекта date d, date.fromordinal(d.toordinal()) == d.

date.weekday()

Возвращает день недели как целое число, где понедельник — 0, а воскресенье — 6. Например, date(2002, 12, 4).weekday() == 2, среда. См. также isoweekday().

date.isoweekday()

Возвращает день недели как целое число, где понедельник — 1, а воскресенье — 7. Например, date(2002, 12, 4).isoweekday() == 3, среда. См. также weekday(), isocalendar().

date.isocalendar()

Возвращает тройку (год по ISO, номер недели по ISO, день недели по ISO).

Календарь ISO — это широко используемый вариант Григорианского календаря. [3]

Год ISO состоит из 52 или 53 полных недель, при этом неделя начинается в понедельник и заканчивается в воскресенье. Первая неделя года по ISO — это первая (по Григорианскому) календарная неделя года, содержащая четверг. Это называется неделей номер 1, и год этого четверга по ISO совпадает с его годом по Григорианскому календарю.

Например, 2004 год начинается в четверг, поэтому первая неделя 2004 года по ISO начинается в понедельник, 29 декабря 2003 года, и заканчивается в воскресенье, 4 января 2004 года:

>>> from datetime import date
>>> date(2003, 12, 29).isocalendar()
(2004, 1, 1)
>>> date(2004, 1, 4).isocalendar()
(2004, 1, 7)
date.isoformat()

Возвращает строку, представляющую дату в формате ISO 8601, YYYY-MM-DD:

>>> from datetime import date
>>> date(2002, 12, 4).isoformat()
'2002-12-04'

Это обратное date.fromisoformat().

date.__str__()

Для даты d str(d) эквивалентно d.isoformat().

date.ctime()

Возвращает строку, представляющую дату:

>>> from datetime import date
>>> date(2002, 12, 4).ctime()
'Wed Dec  4 00:00:00 2002'

d.ctime() эквивалентен:

time.ctime(time.mktime(d.timetuple()))

на платформах, где встроенная функция C ctime() (которую вызывает time.ctime(), но не вызывает date.ctime()) соответствует стандарту C.

date.strftime(format)

Возвращает строку, представляющую дату, управляемую явной строкой формата. Коды формата, относящиеся к часам, минутам или секундам, будут иметь 0 значений. Полный список директив форматирования см. в Поведение strftime() и strptime().

date.__format__(format)

То же, что и date.strftime(). Позволяет указать строку формата для объекта date в форматированных строковых литералах и при использовании str.format(). Полный список директив форматирования см. в Поведение strftime() и strptime().

Примеры использования: date

Пример подсчёта дней до события:

>>> import time
>>> from datetime import date
>>> today = date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == date.fromtimestamp(time.time())
True
>>> my_birthday = date(today.year, 6, 24)
>>> if my_birthday < today:
...     my_birthday = my_birthday.replace(year=today.year + 1)
>>> my_birthday
datetime.date(2008, 6, 24)
>>> time_to_birthday = abs(my_birthday - today)
>>> time_to_birthday.days
202

Ещё примеры работы с date:

>>> from datetime import date
>>> d = date.fromordinal(730920) # 730920 дней после 1.1.0001
>>> d
datetime.date(2002, 3, 11)

>>> # Методы, связанные с форматированием вывода строки
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'
>>> d.ctime()
'Mon Mar 11 00:00:00 2002'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
'The day is 11, the month is March.'

>>> # Методы извлечения "компонентов" под разными календарями
>>> t = d.timetuple()
>>> for i in t:     
...     print(i)
2002                # год
3                   # месяц
11                  # день
0
0
0
0                   # день недели (0 = понедельник)
70                  # 70th day in the year
-1
>>> ic = d.isocalendar()
>>> for i in ic:    
...     print(i)
2002                # ISO год
11                  # ISO номер недели
1                   # ISO номер дня ( 1 = понедельник )

>>> # Объект даты является неизменяемым; все операции создают новый объект
>>> d.replace(year=2005)
datetime.date(2005, 3, 11)

Объекты datetime

Объект datetime — это отдельный объект, содержащий всю информацию из объекта date и объекта time.

Подобно объекту date, datetime предполагает, что текущий Григорианский календарь расширен в обоих направлениях; как и объект time, datetime предполагает, что в каждом дне ровно 3600*24 секунды.

Конструктор:

class datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)

Аргументы year, month и day являются обязательными. tzinfo может быть None или экземпляром подкласса tzinfo. Остальные аргументы должны быть целыми числами в следующих диапазонах:

  • MINYEAR <= year <= MAXYEAR,
  • 1 <= month <= 12,
  • 1 <= day <= number of days in the given month and year,
  • 0 <= hour < 24,
  • 0 <= minute < 60,
  • 0 <= second < 60 ,
  • 0 <= microsecond < 1000000 ,
  • fold in [0, 1].

Если указан аргумент за пределами этих диапазонов, возникает ValueError.

Добавлено в версии 3.6: Добавлен аргумент fold.

Остальные конструкторы, все методы класса:

classmethod datetime.today()

Возвращает текущее местное значение даты и времени с tzinfo None.

Эквивалентно:

datetime.fromtimestamp(time.time())

См. также now(), fromtimestamp().

Метод функционально эквивалентен now(), но без параметра tz.

classmethod datetime.now(tz=None)

Возвращает текущую местную дату и время.

Если необязательный аргумент tz равен None или не указан, это похоже на today(), но, если возможно, обеспечивает большую точность, чем может быть получено при использовании временной метки time.time() (например, это может быть возможно на платформах, предоставляющих функцию C gettimeofday()).

Если tz не None, это должен быть экземпляр подкласса tzinfo, а текущая дата и время конвертируются в часовой пояс tz.

Эта функция предпочтительнее, чем today() и utcnow().

classmethod datetime.utcnow()

Возвращает текущую дату и время в формате UTC с tzinfo None.

Походит на now(), но возвращает текущие дату и время в формате UTC в виде наивного объекта datetime. Информацию о текущей дате и времени в формате UTC можно получить, вызывав datetime.now(timezone.utc). См. также now().

Предупреждение

Поскольку наивные объекты datetime обрабатываются многими методами datetime как местное время, для представления времени в формате UTC предпочтительно использовать осведомлённые даты. Таким образом, рекомендуемый способ создать объект, представляющий текущее время в формате UTC — это вызвать datetime.now(timezone.utc).

classmethod datetime.fromtimestamp(timestamp, tz=None)

Возвращает местную дату и время, соответствующие метке времени POSIX, например, возвращенные time.time(). Если необязательный аргумент tz равен None или не указан, метка времени преобразуется в локальные дату и время платформы, и возвращаемый объект datetime является наивным.

Если tz не None, это должен быть экземпляр подкласса tzinfo, и метка времени преобразуется в часовой пояс tz.

fromtimestamp() может вызвать OverflowError, если временная метка выходит за пределы диапазона значений, поддерживаемых функциями платформы C localtime() или gmtime(), и OSError при сбое localtime() или gmtime(). Обычно это ограничивается годами с 1970 по 2038 год. Обратите внимание, что в системах, не относящихся к POSIX, которые включают в себя секунды координации в своём понятии метки времени, секунды прыжка игнорируются fromtimestamp(), и тогда возможно иметь две метки времени, различающиеся на второй, который дает идентичные объекты datetime. Этот метод предпочтительнее utcfromtimestamp().

Изменено в версии 3.3: Поднимает OverflowError вместо ValueError, если отметка времени выходит за пределы диапазона значений, поддерживаемых функциями платформы C localtime() или gmtime(). Поднимается OSError вместо ValueError при сбое localtime() или gmtime().

Изменено в версии 3.6: fromtimestamp() может возвращать экземпляры с fold, установленным в 1.

classmethod datetime.utcfromtimestamp(timestamp)

Возвращает UTC datetime, соответствующий метке времени POSIX, с tzinfo None. (Получившийся объект наивен.)

Может поднять OverflowError, если метка времени выходит за пределы диапазона значений, поддерживаемых функцией gmtime() платформы C, и OSError при сбое gmtime(). Обычно это ограничивается годами с 1970 по 2038 год.

Чтобы получить информацию об объекте datetime, вызовите fromtimestamp():

datetime.fromtimestamp(timestamp, timezone.utc)

На платформах, совместимых с POSIX, это эквивалентно следующему выражению:

datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=timestamp)

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

Предупреждение

Поскольку наивные объекты datetime обрабатываются многими методами datetime как местное время, для представления времени в формате UTC предпочтительно использовать осведомлённые даты. Таким образом, рекомендуемый способ создать объект, представляющий конкретную метку времени в формате UTC, — это вызвать datetime.fromtimestamp(timestamp, tz=timezone.utc).

Изменено в версии 3.3: Поднимается OverflowError вместо ValueError, если отметка времени выходит за пределы диапазона значений, поддерживаемых функцией gmtime() платформы C. Поднимается OSError вместо ValueError при сбое gmtime().

classmethod datetime.fromordinal(ordinal)

Возвращает datetime, соответствующий Пролептическому григорианскому порядковому номеру, где 1 января 1 года имеет порядковый номер 1. ValueError не поднимается, если 1 <= ordinal <= datetime.max.toordinal(). Час, минута, секунда и микросекунда результата равны 0, а tzinfo — это None.

classmethod datetime.combine(date, time, tzinfo=self.tzinfo)

Возвращает новый объект datetime, компоненты даты которого равны данным объектам date, а компоненты времени равны данным объектам time. Если указан аргумент tzinfo, его значение используется для установки атрибута tzinfo результата, в противном случае используется атрибут tzinfo аргумента time.

Для любого объекта d datetime, d == datetime.combine(d.date(), d.time(), d.tzinfo). Если дата является объектом datetime, его компоненты времени и атрибуты tzinfo игнорируются.

Изменено в версии 3.6: Добавлен аргумент tzinfo.

classmethod datetime.fromisoformat(date_string)

Возвращает datetime, соответствующий date_string в одном из форматов, выдаваемых date.isoformat() и datetime.isoformat().

В частности, эта функция поддерживает строки в формате:

YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]

где * может соответствовать любому одиночному символу.

Осторожно

Он не поддерживает парсинг произвольной ISO 8601 строки - только предназначен как обратная операция datetime.isoformat(). Более полнофункциональный ISO 8601 парсер, dateutil.parser.isoparse доступен в стороннем пакете dateutil.

Примеры:

>>> from datetime import datetime
>>> datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)
>>> datetime.fromisoformat('2011-11-04T00:05:23')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('2011-11-04T00:05:23+04:00')   
datetime.datetime(2011, 11, 4, 0, 5, 23,
    tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))

Добавлено в версии 3.7.

classmethod datetime.fromisocalendar(year, week, day)

Возвращает datetime, соответствующий календарной дате ISO, указанной с указанием года, недели и дня. Компоненты datetime, не относящиеся к дате, заполняются своими обычными значениями по умолчанию. Это функция, обратная datetime.isocalendar().

Добавлено в версии 3.8.

classmethod datetime.strptime(date_string, format)

Возвращает datetime, соответствующий date_string, распарсены в соответствии с format.

Это эквивалентно:

datetime(*(time.strptime(date_string, format)[0:6]))

Поднимается ValueError, если строка date_string и format не могут быть распарсены time.strptime() или если она возвращает значение, не являющееся кортежем времени. Полный список директив форматирования см. в Поведение strftime() и strptime().

Атрибуты класса:

datetime.min

Самый ранний из представленных datetime, datetime(MINYEAR, 1, 1, tzinfo=None).

datetime.max

Последний представимый datetime, datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None).

datetime.resolution

Наименьшее возможное различие между не равными объектами datetime, timedelta(microseconds=1).

Атрибуты экземпляра (только для чтения):

datetime.year

Между MINYEAR и MAXYEAR включительно.

datetime.month

От 1 до 12 включительно.

datetime.day

От 1 до количества дней в данном месяце данного года.

datetime.hour

В range(24).

datetime.minute

В range(60).

datetime.second

В range(60).

datetime.microsecond

В range(1000000).

datetime.tzinfo

Объект передан как аргумент tzinfo конструктору datetime или None, если ничего не было передано.

datetime.fold

В [0, 1]. Используется для устранения неоднозначности настенным времени во время повторяющегося интервала. (Повторяющийся интервал происходит, когда часы откатываются в конце перехода на летнее время или когда смещение UTC для текущей зоны уменьшается по политическим причинам.) значение 0 (1) представляет собой более ранний (более поздний) из двух моментов с то же настенным изображением времени.

Добавлено в версии 3.6.

Поддерживаемые операции:

Операция Результат
datetime2 = datetime1 + timedelta (1)
datetime2 = datetime1 - timedelta (2)
timedelta = datetime1 - datetime2 (3)
datetime1 < datetime2 Сравнивание datetime с datetime. (4)
  1. datetime2 — это длительность timedelta, удаленная из datetime1, двигающаяся вперед во времени, если timedelta.days> 0, или назад, если timedelta.days < 0. Результат имеет тот же атрибут tzinfo, что и входное datetime, и после datetime2 - datetime1 == timedelta. Поднимается OverflowError, если datetime2.year меньше MINYEAR или больше MAXYEAR. Обратите внимание, что настройки часового пояса не выполняются, даже если на входе имеется осведомлённый объект.

  2. Вычисляет datetime2 так, чтобы datetime2 + timedelta == datetime1. Что касается сложения, результат имеет тот же атрибут tzinfo, что и входное datetime, и никакие корректировки часового пояса не выполняются, даже если входные данные осведомлённые.

  3. Вычитание datetime из datetime определяется только в том случае, если оба операнда наивны или если оба осведомлённые. Если один осведомлён, а другой наивен, возникает TypeError.

    Если оба являются наивными или оба осведомлёнными и имеют одинаковый атрибут tzinfo, атрибуты tzinfo игнорируются, и результатом является объект t timedelta, такой как datetime2 + t == datetime1. В этом случае настройка часового пояса не производится.

    Если оба осведомлённые и имеют разные атрибуты tzinfo, a-b действует так, как если бы a и b сначала были преобразованы в наивные даты в формате UTC. Результатом является (a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset()), за исключением того, что реализация никогда не переполняется.

  4. datetime1 считается меньшим, чем datetime2, если datetime1 предшествует datetime2 по времени.

    Если одно сравнение является наивным, а другое осведомлённым, TypeError возникает при попытке сравнения порядка. Для сравнений на равенство наивные экземпляры никогда не равны осведомлённым экземплярам.

    Если оба сравниваемых осведомлены и имеют один и тот же атрибут tzinfo, общий атрибут tzinfo игнорируется и сравниваются базовые даты и время. Если оба компарада осведомлены и имеют разные атрибуты tzinfo, сначала они корректируются путём вычитания их смещений UTC (полученных из self.utcoffset()).

    Изменено в версии 3.3: Сравнение равенства между осведомлёнными и наивными экземплярами datetime не вызывает TypeError.

    Примечание

    Чтобы предотвратить откат сравнения к стандартной схеме сравнения адресов объектов, при сравнении даты и времени обычно возникает TypeError, если другое сравнение также не является объектом datetime. Однако вместо этого возвращается NotImplemented, если другой компарат имеет атрибут timetuple(). Этот хук дает возможность другим типам объектов даты реализовать сравнение смешанного типа. В противном случае, когда объект datetime сравнивается с объектом другого типа, возникает TypeError, если сравнение не является == или !=. В последнем случае возвращается False или True соответственно.

Методы экземпляра:

datetime.date()

Возвращает объект date с тем же годом, месяцем и днём.

datetime.time()

Возврат объекта time с одинаковыми часами, минутами, секундами, микросекундами и кратностью. tzinfo — это None. См. также метод timetz().

Изменено в версии 3.6: Значение кратности копируется в возвращённый объект time.

datetime.timetz()

Возвращает объект time с такими же атрибутами часа, минуты, секунды, микросекунды, кратности и tzinfo. См. также метод time().

Изменено в версии 3.6: Значение кратности копируется в возвращенный объект time.

datetime.replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)

Возвращает дату и время с теми же атрибутами, за исключением тех атрибутов, которым присвоены новые значения в зависимости от того, какие ключевые аргументы указаны. Обратите внимание, что tzinfo=None можно указать для создания наивного datetime из известного datetime без преобразования данных даты и времени.

Добавлено в версии 3.6: Добавлен аргумент fold.

datetime.astimezone(tz=None)

Возвращает объект datetime с новым атрибутом tzinfo tz, настроив данные даты и времени так, чтобы результат был тем же временем UTC, что и self, но по местному времени tz.

Если предоставляется, tz должен быть экземпляром подкласса tzinfo, а его методы utcoffset() и dst() не должны возвращать None. Если self наивен, предполагается, что он представляет время в системном часовом поясе.

При вызове без аргументов (или с tz=None) в качестве целевого часового пояса принимается местный часовой пояс системы. Атрибут .tzinfo преобразованного экземпляра datetime будет установлен на экземпляр timezone с именем зоны и смещением, полученными из ОС.

Если self.tzinfo равно tz, self.astimezone(tz) равно self: настройка даты или времени не выполняется. В противном случае результатом будет местное время в часовом поясе tz, представляющее то же время UTC, что и self: после astz = dt.astimezone(tz) astz - astz.utcoffset() будет иметь те же данные даты и времени, что и dt - dt.utcoffset().

Если вы просто хотите присоединить объект часового пояса tz к datetime dt без корректировки данных даты и времени, используйте dt.replace(tzinfo=tz). Если вы просто хотите удалить объект часового пояса из осведомлённого datetime dt без преобразования данных даты и времени, используйте dt.replace(tzinfo=None).

Обратите внимание, что метод tzinfo.fromutc() по умолчанию можно переопределить в подклассе tzinfo, чтобы повлиять на результат, возвращаемый astimezone(). Игнорируя случаи ошибок, astimezone() действует как:

def astimezone(self, tz):
    if self.tzinfo is tz:
        return self
    # Преобразовать self в UTC и прикрепить новый объект часового пояса.
    utc = (self - self.utcoffset()).replace(tzinfo=tz)
    # Конвертировать из UTC в локальное время tz.
    return tz.fromutc(utc)

Изменено в версии 3.3: tz теперь можно пропустить.

Изменено в версии 3.6: Теперь метод astimezone() можно вызывать в наивных экземплярах, которые, как предполагается, представляют локальное время системы.

datetime.utcoffset()

Если tzinfoNone, возвращает None, иначе возвращает self.tzinfo.utcoffset(self) и вызывает исключение, если последний не возвращает None или объект timedelta с величиной меньше одного дня.

Изменено в версии 3.7: Смещение UTC не ограничивается целым числом минут.

datetime.dst()

Если tzinfo — это None, возвращает None, иначе возвращает self.tzinfo.dst(self) и вызывает исключение, если последний не возвращает None или объект timedelta с величиной менее одного дня.

Изменено в версии 3.7: Смещение летнего времени не ограничивается целым числом минут.

datetime.tzname()

Если tzinfoNone, возвращает None, иначе возвращает self.tzinfo.tzname(self), вызывает исключение, если последний не возвращает None или строковый объект

datetime.timetuple()

Возвращает time.struct_time, например, time.localtime().

d.timetuple() эквивалентен:

time.struct_time((d.year, d.month, d.day,
                  d.hour, d.minute, d.second,
                  d.weekday(), yday, dst))

где yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1 — номер дня в текущем году, начиная с 1 для 1 января. Флаг tm_isdst результата устанавливается в соответствии с методом dst(): tzinfo — это None или dst() возвращает None, tm_isdst — это -1; иначе, если dst() возвращает ненулевое значение, tm_isdst устанавливается в 1; иначе tm_isdst устанавливается 0.

datetime.utctimetuple()

Если datetime экземпляр d является наивным, это то же самое, что и d.timetuple(), за исключением того, что tm_isdst принудительно устанавливается в 0 независимо от того, что возвращает d.dst(). Летнее время никогда не действует для времени UTC.

Если d известно, d нормализуется по времени UTC путём вычитания d.utcoffset(), и возвращается time.struct_time для нормализованного времени. tm_isdst принудительно устанавливается в 0. Обратите внимание, что OverflowError может быть подято, если d.year был MINYEAR или MAXYEAR и корректировка UTC выходит за границу года.

Предупреждение

Поскольку наивные объекты datetime обрабатываются многими методами datetime как локальное время, для представления времени в формате UTC предпочтительно использовать осведомлённое время; в результате использование utcfromtimetuple может привести к ошибочным результатам. Если у вас есть наивный datetime, представляющий UTC, используйте datetime.replace(tzinfo=timezone.utc), чтобы он знал, после чего вы можете использовать datetime.timetuple().

datetime.toordinal()

Возвращает Пролептический григорианский порядковый номер даты. То же, что и self.date().toordinal().

datetime.timestamp()

Возвращает отметку времени POSIX, соответствующую экземпляру datetime. Возвращаемое значение — float, аналогичное возвращаемому time.time().

Предполагается, что простые экземпляры datetime представляют локальное время, и этот метод полагается на функцию платформы C mktime() для выполнения преобразования. Поскольку datetime поддерживает более широкий диапазон значений, чем mktime() на многих платформах, этот метод может поднять OverflowError для времён, далекого прошлого или далекого будущего.

Для известных экземпляров datetime возвращаемое значение вычисляется как:

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

Добавлено в версии 3.3.

Изменено в версии 3.6: Метод timestamp() использует атрибут fold для устранения неоднозначности времени в течение повторяющегося интервала.

Примечание

Не существует способа получить метку времени POSIX непосредственно из наивного экземпляра datetime, представляющего время в формате UTC. Если ваше приложение использует это соглашение и часовой пояс вашей системы не установлен на UTC, вы можете получить метку времени POSIX, указав tzinfo=timezone.utc:

timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

или вычисляя метку времени напрямую:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
datetime.weekday()

Возвращает день недели как целое число, где понедельник равен 0, а воскресенье — 6. То же, что и self.date().weekday(). Также isoweekday().

datetime.isoweekday()

Возвращает день недели как целое число, где понедельник — 1, а воскресенье — 7. То же, что и self.date().isoweekday(). См. также weekday(), isocalendar().

datetime.isocalendar()

Возвращает тройку (год ISO, номер недели ISO, день недели ISO). То же, что и self.date().isocalendar().

datetime.isoformat(sep='T', timespec='auto')

Возвращает строку, представляющую дату и время в формате ISO 8601:

  • YYYY-MM-DDTHH:MM:SS.ffffff, если microsecond не равно 0 YYYY-MM-DDTHH:MM:SS, если microsecond равно 0

Если utcoffset() не возвращает None, добавляется строка с указанием смещения UTC:

  • YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]], если microsecond не 0
  • YYYY-MM-DDTHH:MM:SS+HH:MM[:SS[.ffffff]], если microsecond равно 0

Примеры:

>>> from datetime import datetime, timezone
>>> datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat()
'2019-05-18T15:17:08.132263'
>>> datetime(2019, 5, 18, 15, 17, tzinfo=timezone.utc).isoformat()
'2019-05-18T15:17:00+00:00'

Необязательный аргумент sep (по умолчанию 'T') — это односимвольный разделитель, помещаемый между датой и временем результата. Например:

>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
...     """Часовой пояс с произвольным постоянным смещением -06:39."""
...     def utcoffset(self, dt):
...         return timedelta(hours=-6, minutes=-39)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
>>> datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat()
'2009-11-27T00:00:00.000100-06:39'

Необязательный аргумент timespec указывает количество дополнительных компонентов времени, которые необходимо включить (по умолчанию 'auto'). Может быть одним из следующих:

  • 'auto': то же, что 'seconds', если microsecond равно 0, то же самое, что 'microseconds' в противном случае.
  • 'hours': включив hour в двузначный формат HH.
  • 'minutes': включив hour и minute в формате HH:MM.
  • 'seconds': включив hour, minute и second в формате HH:MM:SS.
  • 'milliseconds': включив полный рабочий день, но сократив дробную вторую часть до миллисекунд. Формат HH:MM:SS.sss.
  • 'microseconds': включить полный рабочий день в формате HH:MM:SS.ffffff.

Примечание

Исключённые компоненты времени усекаются, а не округляются.

ValueError будет вызван из-за недопустимого аргумента timespec:

>>> from datetime import datetime
>>> datetime.now().isoformat(timespec='minutes')   
'2002-12-25T00:00'
>>> dt = datetime(2015, 1, 1, 12, 30, 59, 0)
>>> dt.isoformat(timespec='microseconds')
'2015-01-01T12:30:59.000000'

Добавлено в версии 3.6: Добавлен timespec аргумент.

datetime.__str__()

Для экземпляра d datetime str(d) эквивалентно d.isoformat(' ').

datetime.ctime()

Возвращает строку, представляющую дату и время:

>>> from datetime import datetime
>>> datetime(2002, 12, 4, 20, 30, 40).ctime()
'Wed Dec  4 20:30:40 2002'

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

d.ctime() эквивалентен:

time.ctime(time.mktime(d.timetuple()))

на платформах, где встроенная функция C ctime() (которую вызывает time.ctime(), но не вызывает datetime.ctime()) соответствует стандарту C.

datetime.strftime(format)

Возвращает строку, представляющую дату и время, управляемую явной строкой формата. Полный список директив форматирования см. в Поведение strftime() и strptime().

datetime.__format__(format)

То же, что и datetime.strftime(). Позволяет указать строку формата для объекта datetime в форматированных строковых литералах и при использовании str.format(). Полный список директив форматирования см. в Поведение strftime() и strptime().

Примеры использования: datetime

Примеры работы с объектами datetime:

>>> from datetime import datetime, date, time, timezone

>>> # Использование datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)

>>> # Использование datetime.now()
>>> datetime.now()   
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043)   # GMT +1
>>> datetime.now(timezone.utc)   
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060, tzinfo=datetime.timezone.utc)

>>> # Использование datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)

>>> # Использование datetime.timetuple() получить кортеж всех атрибутов
>>> tt = dt.timetuple()
>>> for it in tt:   
...     print(it)
...
2006    # год
11      # месяц
21      # день
16      # час
30      # минута
0       # секунда
1       # день недели (0 = понедельник)
325     # количество дней с 1 января
-1      # dst - метод tzinfo.dst() возвращает None

>>> # Дата в ISO формате
>>> ic = dt.isocalendar()
>>> for it in ic:   
...     print(it)
...
2006    # ISO год
47      # ISO неделя
2       # ISO день недели

>>> # Форматирование даты и времени
>>> dt.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(dt, "day", "month", "time")
'The day is 21, the month is November, the time is 04:30PM.'

В приведенном ниже примере определяется подкласс tzinfo, захватывающий информацию о часовом поясе для Кабула (Афганистан), который использовал +4 UTC до 1945 года, а затем +4:30 UTC после:

from datetime import timedelta, datetime, tzinfo, timezone

class KabulTz(tzinfo):
    # Кабул используемый +4 до 1945 года, когда они перешли в +4:30
    UTC_MOVE_DATE = datetime(1944, 12, 31, 20, tzinfo=timezone.utc)

    def utcoffset(self, dt):
        if dt.year < 1945:
            return timedelta(hours=4)
        elif (1945, 1, 1, 0, 0) <= dt.timetuple()[:5] < (1945, 1, 1, 0, 30):
            # Неоднозначный ("мнимый") полуторачасовой диапазон, представляющий "кратность" по
            # времени вследствие сдвига от + 4 до + 4:30. Если dt попадает в воображаемый
            # диапазон, используйте fold, чтобы решить, как разрешить. См. PEP495.
            return timedelta(hours=4, minutes=(30 if dt.fold else 0))
        else:
            return timedelta(hours=4, minutes=30)

    def fromutc(self, dt):
        # Выполнить те же проверки, что и в datetime.tzinfo
        if not isinstance(dt, datetime):
            raise TypeError("fromutc() requires a datetime argument")
        if dt.tzinfo is not self:
            raise ValueError("dt.tzinfo is not self")

        # Для fromutc требуется пользовательская реализация, так как входным значением
        # этой функции является datetime с utc значения, но tzinfo со значением self. См.
        # datetime.astimezone или fromtimestamp.
        if dt.replace(tzinfo=timezone.utc) >= self.UTC_MOVE_DATE:
            return dt + timedelta(hours=4, minutes=30)
        else:
            return dt + timedelta(hours=4)

    def dst(self, dt):
        # Кабул не соблюдает летнее время.
        return timedelta(0)

    def tzname(self, dt):
        if dt >= self.UTC_MOVE_DATE:
            return "+04:30"
        return "+04"

Использование KabulTz сверху:

>>> tz1 = KabulTz()

>>> # Дата-время перед изменением
>>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1)
>>> print(dt1.utcoffset())
4:00:00

>>> # Дата-время после изменения
>>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1)
>>> print(dt2.utcoffset())
4:30:00

>>> # Преобразование даты и времени в другой часовой пояс
>>> dt3 = dt2.astimezone(timezone.utc)
>>> dt3
datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc)
>>> dt2
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=KabulTz())
>>> dt2 == dt3
True

Объекты time

Объект time представляет (локальное) время дня, не зависящее от какого- либо конкретного дня и подлежащее настройке с помощью объекта tzinfo.

class datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)

Все аргументы необязательны. tzinfo может быть None или экземпляром подкласса tzinfo. Остальные аргументы должны быть целыми числами в следующих диапазонах:

  • 0 <= hour < 24,
  • 0 <= minute < 60 ,
  • 0 <= second < 60,
  • 0 <= microsecond < 1000000,
  • fold in [0, 1].

Если указан аргумент за пределами этих диапазонов, возникает ValueError. Всё по умолчанию — 0, кроме tzinfo, для которого по умолчанию используется None.

Атрибуты класса:

time.min

Самый ранний из представленных time, time(0, 0, 0, 0).

time.max

Последний представимый time, time(23, 59, 59, 999999).

time.resolution

Наименьшее возможное различие между не равными объектами time, timedelta(microseconds=1), хотя обратите внимание, что арифметика для объектов time не поддерживается.

Атрибуты экземпляра (только для чтения):

time.hour

В range(24).

time.minute

В range(60).

time.second

В range(60).

time.microsecond

В range(1000000).

time.tzinfo

Объект передан в качестве аргумента tzinfo конструктору time или None, если ничего не было передано.

time.fold

В [0, 1]. Используется для устранения неоднозначности настенного времени во время повторяющегося интервала. (Повторяющийся интервал происходит, когда часы откатываются в конце перехода на летнее время или когда смещение UTC для текущей зоны уменьшается по политическим причинам.) Значение 0 (1) представляет собой более ранний (более поздний) из двух моментов с то же настенное изображение времени.

Добавлено в версии 3.6.

Объекты time поддерживают сравнение time с time, где a считается меньше b, когда a предшествует b во времени. Если одно сравнение является наивным, а другое осведомлённым, TypeError возникает при попытке сравнения порядка. Для сравнений на равенство наивные экземпляры никогда не равны осведомлённым экземплярам.

Если оба средства сравнения осведомлены и содержат один и тот же атрибут tzinfo, общий атрибут tzinfo игнорируется и сравниваются базовые времена. Если оба компарада осведомлены и имеют разные атрибуты tzinfo, они сначала корректируются путём вычитания их смещений по Всемирному координированному времени (получено из self.utcoffset()). Чтобы сравнения смешанного типа не возвращались к сравнению по умолчанию по адресу объекта, когда объект time сравнивается с объектом другого типа, возникает TypeError, если сравнение не является == или !=. В последнем случае возвращается False или True соответственно.

Изменено в версии 3.3: Сравнение равенства между осведомлёнными и наивными экземплярами time не вызывает TypeError.

В логических контекстах объект time всегда считается истинным.

Изменено в версии 3.5: До Python 3.5 объект time считался ложным, если он представлял полночь по Всемирному координированному времени. Такое поведение считалось непонятным и подверженным ошибкам и было удалено в Python 3.5. См. bpo-13936 для получения полной информации.

Другой конструктор:

classmethod time.fromisoformat(time_string)

Возвращает time, соответствующий time_string в одном из форматов, выдаваемых time.isoformat(). В частности, эта функция поддерживает строки в формате:

HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]

Осторожно

Не поддерживает синтаксический анализ произвольных строк ISO 8601. Он предназначен только как обратная операция time.isoformat().

Примеры:

>>> from datetime import time
>>> time.fromisoformat('04:23:01')
datetime.time(4, 23, 1)
>>> time.fromisoformat('04:23:01.000384')
datetime.time(4, 23, 1, 384)
>>> time.fromisoformat('04:23:01+04:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))

Добавлено в версии 3.7.

Методы экземпляра:

time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)

Возвращает time с тем же значением, за исключением тех атрибутов, которым присвоены новые значения в зависимости от того, какие ключевые аргументы указаны. Обратите внимание, что tzinfo=None можно указать для создания наивного time из осведомлённого time без преобразования данных времени.

Добавлено в версии 3.6: Добавлен аргумент fold.

time.isoformat(timespec='auto')

Возвращает строку, представляющую время в формате ISO 8601, одно из значений:

  • HH:MM:SS.ffffff, если microsecond не равно 0,
  • HH:MM:SS, если microsecond равно 0,
  • HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]], если utcoffset() не возвращает None,
  • HH:MM:SS+HH:MM[:SS[.ffffff]], если microsecond равно 0, а utcoffset() не возвращает None

Необязательный аргумент timespec указывает количество дополнительных компонентов времени, которые необходимо включить (по умолчанию 'auto'). Может быть одно из следующих:

  • 'auto': то же, что 'seconds', если microsecond равно 0, то же самое, что 'microseconds' в противном случае.
  • 'hours': включите hour в двузначном формате HH.
  • 'minutes': включить hour и minute в формате HH:MM.
  • 'seconds': включить hour, minute и second в формате HH:MM:SS.
  • 'milliseconds': включить полный рабочий день, но сократить дробную вторую часть до миллисекунд. Формат HH:MM:SS.sss.
  • 'microseconds': включить полный рабочий день в формате HH:MM:SS.ffffff.

Примечание

Исключенные компоненты времени усекаются, а не округляются.

ValueError будет вызван из-за недопустимого аргумента timespec.

Пример:

>>> from datetime import time
>>> time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes')
'12:34'
>>> dt = time(hour=12, minute=34, second=56, microsecond=0)
>>> dt.isoformat(timespec='microseconds')
'12:34:56.000000'
>>> dt.isoformat(timespec='auto')
'12:34:56'

Добавлено в версии 3.6: Добавлен аргумент timespec.

time.__str__()

Для времени t str(t) эквивалентен t.isoformat().

time.strftime(format)

Возвращает строку, представляющую время, управляемую явной строкой формата. Полный список директив форматирования см. в Поведение strftime() и strptime().

time.__format__(format)

То же, что и time.strftime(). Позволяет указать строку формата для объекта time в форматированных строковых литералах и при использовании str.format(). Полный список директив форматирования см. в Поведение strftime() и strptime().

time.utcoffset()

Если tzinfoNone, возвращает None, иначе возвращает self.tzinfo.utcoffset(None) и вызывает исключение, если последний не возвращает None или объект timedelta с величиной менее одного дня.

Изменено в версии 3.7: Смещение UTC не ограничивается целым числом минут.

time.dst()

Если tzinfoNone, возвращает None, иначе возвращает self.tzinfo.dst(None) и вызывает исключение, если последний не возвращает None или объект timedelta с величиной меньше одного дня.

Изменено в версии 3.7: Смещение летнего времени не ограничивается целым числом минут.

time.tzname()

Если tzinfoNone, возвращает None, иначе возвращает self.tzinfo.tzname(None) или вызывает исключение, если последний не возвращает None или строковый объект.

Примеры использования: time

Примеры работы с объектом time:

>>> from datetime import time, tzinfo, timedelta
>>> class TZ1(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=1)
...     def dst(self, dt):
...         return timedelta(0)
...     def tzname(self,dt):
...         return "+01:00"
...     def  __repr__(self):
...         return f"{self.__class__.__name__}()"
...
>>> t = time(12, 10, 30, tzinfo=TZ1())
>>> t
datetime.time(12, 10, 30, tzinfo=TZ1())
>>> t.isoformat()
'12:10:30+01:00'
>>> t.dst()
datetime.timedelta(0)
>>> t.tzname()
'+01:00'
>>> t.strftime("%H:%M:%S %Z")
'12:10:30 +01:00'
>>> 'The {} is {:%H:%M}.'.format("time", t)
'The time is 12:10.'

Объекты tzinfo

class datetime.tzinfo

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

Экземпляр (конкретный подкласс) tzinfo может быть передан конструкторам для объектов datetime и time. Последние объекты рассматривают свои атрибуты как находящиеся в локальном времени, а объект tzinfo поддерживает методы, показывающие смещение местного времени от UTC, имя часового пояса и смещение летнего времени, все относительно переданного им объекта даты или времени.

Вам необходимо создать конкретный подкласс и (по крайней мере) предоставить реализации стандартных методов tzinfo, необходимых для используемых вами методов datetime. Модуль datetime предоставляет timezone, простой конкретный подкласс tzinfo, который может представлять часовые пояса с фиксированным смещением от UTC, такие как сам UTC или Североамериканское EST и EDT.

Особое требование для травления: подкласс tzinfo должен содержать метод __init__(), который может вызываться без аргументов, в противном случае он может быть пиклен (pickled), но, возможно, не будет снова распиклен (unpickled). Это техническое требование, которое может быть ослаблено в будущем.

В конкретном подклассе tzinfo может потребоваться реализация следующих методов. Какие именно методы необходимы, зависит от того, как используются известные объекты datetime. Если сомневаетесь, просто реализуйте их все.

tzinfo.utcoffset(dt)

Возвращает смещение местного времени от UTC в виде объекта timedelta, положительного к востоку от UTC. Если местное время находится к западу от UTC, оно должно быть отрицательным.

Представляет собой полное смещение от UTC; например, если объект tzinfo представляет настройки часового пояса и летнего времени, utcoffset() должен вернуть их сумму. Если смещение UTC неизвестно, вернёт None. В противном случае возвращаемое значение должно быть объектом timedelta строго между -timedelta(hours=24) и timedelta(hours=24) (величина смещения должна быть меньше одного дня). Большинство реализаций utcoffset(), вероятно, будут выглядеть как одна из этих двух:

return CONSTANT                 # класс фиксированного смещения
return CONSTANT + self.dst(dt)  # класс с учетом дневного света

Если utcoffset() не возвращает None, dst() также не должен возвращать None.

Реализация по умолчанию utcoffset() вызывает NotImplementedError.

Изменено в версии 3.7: Смещение UTC не ограничивается целым числом минут.

tzinfo.dst(dt)

Возвращает настройку перехода на летнее время (DST) в виде объекта timedelta или None, если информация о летнем времени неизвестна.

Возвращает timedelta(0), если DST не действует. Если действует DST, вернёт смещение как объект timedelta (подробности см. в utcoffset()). Обратите внимание, что смещение DST, если применимо, уже было добавлено к смещению UTC, возвращаемому utcoffset(), поэтому нет необходимости консультироваться с dst(), если вы не заинтересованы в получении информации о DST отдельно. Например, datetime.timetuple() вызывает метод dst() своего атрибута tzinfo, чтобы определить, как должен быть установлен флаг tm_isdst, а tzinfo.fromutc() вызывает dst() для учёта изменений DST при пересечении часовых поясов.

Экземпляр tz подкласса tzinfo, который моделирует как стандартное, так и дневное время, должен быть согласован в этом смысле:

tz.utcoffset(dt) - tz.dst(dt)

должен возвращать тот же результат для каждого datetime dt с dt.tzinfo == tz. Для нормальных подклассов tzinfo это выражение дает «стандартное смещение» часового пояса, которое не должно зависеть от даты или времени, а только от географического положения. Реализация datetime.astimezone() полагается на это, но не может обнаруживать нарушения; ответственность за это несёт программист. Если подкласс tzinfo не может гарантировать этого, он может переопределить реализацию по умолчанию tzinfo.fromutc() в любом случае для правильной работы с astimezone().

Большинство реализаций dst(), вероятно, будут выглядеть как одна из этих двух:

def dst(self, dt):
    # класс с фиксированным смещением: не учитывает DST
    return timedelta(0)

или же:

def dst(self, dt):
   # Код для установки dston и dstoff на время перехода на DST для часового
   # пояса на основе входного dt.year и выраженное в стандартном
   # локальном времени.

    if dston <= dt.replace(tzinfo=None) < dstoff:
        return timedelta(hours=1)
    else:
        return timedelta(0)

Реализация по умолчанию dst() вызывает NotImplementedError.

Изменено в версии 3.7: Смещение DST не ограничивается целым числом минут.

tzinfo.tzname(dt)

Возвращает имя часового пояса, соответствующее объекту dt datetime, в виде строки. Модуль datetime ничего не определяет в именах строк и не требует, чтобы они означали что-либо конкретное. Например, «GMT», «UTC», «-500», «-5: 00», «EDT», «US/Eastern», «America/New York» являются действительными ответами. Возвращает None, если имя строки неизвестно. Обратите внимание, что это метод, а не фиксированная строка, прежде всего потому, что некоторые подклассы tzinfo захотят возвращать разные имена в зависимости от конкретного переданного значения dt, особенно если класс tzinfo учитывает дневное время.

Реализация по умолчанию tzname() поднимает NotImplementedError.

Методы вызываются объектом datetime или time в ответ на их методы с такими же именами. Объект datetime передаёт себя в качестве аргумента, а объект time передаёт None в качестве аргумента. Поэтому методы подкласса tzinfo должны быть готовы принять аргумент dt None или класса datetime.

Когда передан None, разработчик класса должен выбрать лучший ответ. Например, возврат None подходит, если класс хочет сказать, что объекты времени не участвуют в протоколах tzinfo. Для utcoffset(None) может быть более полезно возвращать стандартное смещение UTC, поскольку другого соглашения для определения стандартного смещения нет.

Когда объект datetime передаётся в ответ на метод datetime, dt.tzinfo является тем же объектом, что и self. Методы tzinfo могут полагаться на это, если пользовательский код не вызывает методы tzinfo напрямую. Намерение состоит в том, чтобы методы tzinfo интерпретировали dt как находящееся в местном времени и не беспокоились об объектах в других часовых поясах.

Есть ещё один метод tzinfo, который подкласс может захотеть переопределить:

tzinfo.fromutc(dt)

Вызывается из реализации по умолчанию datetime.astimezone(). При вызове из него dt.tzinfo является self, а данные даты и времени dt следует рассматривать как выражение времени UTC. Цель fromutc() — настроить данные даты и времени, возвращая эквивалентное datetime в self локальном времени.

У большинства подклассов tzinfo должна быть возможность без проблем наследовать реализацию fromutc() по умолчанию. Он достаточно силён для обработки часовых поясов с фиксированным смещением и часовых поясов, учитывающих как стандартное, так и летнее время, и последнее, даже если время перехода на летнее время отличается в разные годы. Примером часового пояса, который реализация fromutc() по умолчанию может не обрабатывать правильно во всех случаях, является тот, где стандартное смещение (от UTC) зависит от конкретной прошедшей даты и времени, что может произойти по политическим причинам. Реализации по умолчанию astimezone() и fromutc() могут не дать желаемого результата, если результатом является один из часов, охватывающих момент изменения стандартного смещения.

Пропуская код для случаев ошибки, реализация fromutc() по умолчанию действует как:

def fromutc(self, dt):
    # поднять ошибку ValueError, если dt.tzinfo не является self
    dtoff = dt.utcoffset()
    dtdst = dt.dst()
    # поднять ValueError, если dtoff равен None или dtdst равен None
    delta = dtoff - dtdst  # это стандартное смещение self
    if delta:
        dt += delta   # преобразование в стандартное локальное время
        dtdst = dt.dst()
        # поднять ValueError, если dtdst None
    if dtdst:
        return dt + dtdst
    else:
        return dt

В следующем файле tzinfo_examples.py есть несколько примеров классов tzinfo:

from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)
HOUR = timedelta(hours=1)
SECOND = timedelta(seconds=1)

# Класс, отражающий представление платформы о местном времени. (Может привести к
# неправильным значениям исторического времени в часовых поясах, где смещение UTC
# и/или правила DST менялись в прошлом.
import time as _time

STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
    DSTOFFSET = timedelta(seconds = -_time.altzone)
else:
    DSTOFFSET = STDOFFSET

DSTDIFF = DSTOFFSET - STDOFFSET

class LocalTimezone(tzinfo):

    def fromutc(self, dt):
        assert dt.tzinfo is self
        stamp = (dt - datetime(1970, 1, 1, tzinfo=self)) // SECOND
        args = _time.localtime(stamp)[:6]
        dst_diff = DSTDIFF // SECOND
        # Обнаружить складку
        fold = (args == _time.localtime(stamp - dst_diff))
        return datetime(*args, microsecond=dt.microsecond,
                        tzinfo=self, fold=fold)

    def utcoffset(self, dt):
        if self._isdst(dt):
            return DSTOFFSET
        else:
            return STDOFFSET

    def dst(self, dt):
        if self._isdst(dt):
            return DSTDIFF
        else:
            return ZERO

    def tzname(self, dt):
        return _time.tzname[self._isdst(dt)]

    def _isdst(self, dt):
        tt = (dt.year, dt.month, dt.day,
              dt.hour, dt.minute, dt.second,
              dt.weekday(), 0, 0)
        stamp = _time.mktime(tt)
        tt = _time.localtime(stamp)
        return tt.tm_isdst > 0

Local = LocalTimezone()


# Полная реализация текущих правил DST времени для основных часовых поясов
# США.

def first_sunday_on_or_after(dt):
    days_to_go = 6 - dt.weekday()
    if days_to_go:
        dt += timedelta(days_to_go)
    return dt


# Правила DST времени США
#
# Это упрощенный (т.е. неверный в некоторых случаях) набор правил для времени
# начала и окончания летнего времени в США. Чтобы получить полный и актуальный
# набор правил DST и определений часовых поясов, посетите базу данных Olson (или
# попробуйте pytz):
# http://www.twinsun.com/tz/tz-link.htm
# http://sourceforge.net/projects/pytz/ (может быть устаревшим)
#
# В США с 2007 года летнее время (DST) начинается в 2 часа ночи (стандартное время) во
# второе воскресенье марта, то есть в первое воскресенье 8 марта или после этой
# даты.
DSTSTART_2007 = datetime(1, 3, 8, 2)
# и заканчивается в 2 часа ночи (по летнему времени) в первое воскресенье ноября.
DSTEND_2007 = datetime(1, 11, 1, 2)
# С 1987 по 2006 год летнее время (DST) начиналось в 2 часа ночи (стандартное время) в
# первое воскресенье апреля и заканчивалось в 2 часа ночи (время летнего времени)
# в последнее воскресенье октября, которое является первым воскресеньем 25
# октября или позже.
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
DSTEND_1987_2006 = datetime(1, 10, 25, 2)
# С 1967 по 1986 летнее время (DST) начиналось в 2 часа ночи (стандартное время) в
# последнее воскресенье апреля (24 апреля или позже) и заканчивалось в 2 часа
# ночи (летнее время) в последнее воскресенье октября, которое является первым
# воскресеньем или позже 25 октября.
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
DSTEND_1967_1986 = DSTEND_1987_2006

def us_dst_range(year):
    # Найти время начала и окончания для летнего времени в США. До 1967 года
    # возвращение start = end без перехода на летнее время.
    if 2006 < year:
        dststart, dstend = DSTSTART_2007, DSTEND_2007
    elif 1986 < year < 2007:
        dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
    elif 1966 < year < 1987:
        dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
    else:
        return (datetime(year, 1, 1), ) * 2

    start = first_sunday_on_or_after(dststart.replace(year=year))
    end = first_sunday_on_or_after(dstend.replace(year=year))
    return start, end


class USTimeZone(tzinfo):

    def __init__(self, hours, reprname, stdname, dstname):
        self.stdoffset = timedelta(hours=hours)
        self.reprname = reprname
        self.stdname = stdname
        self.dstname = dstname

    def __repr__(self):
        return self.reprname

    def tzname(self, dt):
        if self.dst(dt):
            return self.dstname
        else:
            return self.stdname

    def utcoffset(self, dt):
        return self.stdoffset + self.dst(dt)

    def dst(self, dt):
        if dt is None or dt.tzinfo is None:
            # Здесь может быть разумным исключение в одном или обоих случаях. Это зависит от
            # того, как вы хотите к ним относиться. Реализация fromutc() по умолчанию
            # (вызываемая реализацией astimezone() по умолчанию) передает datetime с
            # dt.tzinfo как self.
            return ZERO
        assert dt.tzinfo is self
        start, end = us_dst_range(dt.year)
        # Невозможно сравнить наивные объекты с осведомлёнными, поэтому сначала удалите
        # часовой пояс из dt.
        dt = dt.replace(tzinfo=None)
        if start + HOUR <= dt < end - HOUR:
            # Действует летнее время.
            return HOUR
        if end - HOUR <= dt < end:
            # Fold (неоднозначный час): используйте dt.fold для устранения неоднозначности.
            return ZERO if dt.fold else HOUR
        if start <= dt < start + HOUR:
            # Разрыв (несуществующий час): отменить правило складывания.
            return HOUR if dt.fold else ZERO
        # Летнее время (DST) выключено.
        return ZERO

    def fromutc(self, dt):
        assert dt.tzinfo is self
        start, end = us_dst_range(dt.year)
        start = start.replace(tzinfo=self)
        end = end.replace(tzinfo=self)
        std_time = dt + self.stdoffset
        dst_time = std_time + HOUR
        if end <= dst_time < end + HOUR:
            # Повторный час
            return std_time.replace(fold=1)
        if std_time < start or dst_time >= end:
            # Стандартное время
            return std_time
        if start <= std_time < end - HOUR:
            # Переход на летнее время
            return dst_time


Eastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
Central  = USTimeZone(-6, "Central",  "CST", "CDT")
Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
Pacific  = USTimeZone(-8, "Pacific",  "PST", "PDT")

Обратите внимание, что два раза в год в подклассе tzinfo есть неизбежные тонкости, учитывающие как стандартное, так и летнее время в точках перехода на DST. Для конкретности рассмотрим восточное время США (UTC -0500), где EDT начинается через минуту после 1:59 (EST) во второе воскресенье марта и заканчивается через минуту после 1:59 (EDT) в первое воскресенье ноября:

  UTC   3:MM  4:MM  5:MM  6:MM  7:MM  8:MM
  EST  22:MM 23:MM  0:MM  1:MM  2:MM  3:MM
  EDT  23:MM  0:MM  1:MM  2:MM  3:MM  4:MM

start  22:MM 23:MM  0:MM  1:MM  3:MM  4:MM

  end  23:MM  0:MM  1:MM  1:MM  2:MM  3:MM

Когда начинается DST («стартовая» линия), местные настенные часы перескакивают с 1:59 на 3:00. Настенное время в форме 2:MM не имеет смысла в этот день, поэтому astimezone(Eastern) не даст результата с hour == 2 в день перехода на DST (летнее время). Например, при весеннем форвардном переходе 2016 года мы получаем:

>>> from datetime import datetime, timezone
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = datetime(2016, 3, 13, 5, tzinfo=timezone.utc)
>>> for i in range(4):
...     u = u0 + i*HOUR
...     t = u.astimezone(Eastern)
...     print(u.time(), 'UTC =', t.time(), t.tzname())
...
05:00:00 UTC = 00:00:00 EST
06:00:00 UTC = 01:00:00 EST
07:00:00 UTC = 03:00:00 EDT
08:00:00 UTC = 04:00:00 EDT

Когда заканчивается DST («конечная» линия), возникает потенциально более серьезная проблема: есть час, который нельзя однозначно описать в локальном настенном времени: последний час дневного времени. На востоке это время в форме 5:MM UTC в конце светового дня. Локальные настенные часы снова перескакивают с 1:59 (дневное время) на 1:00 (стандартное время). Местное время формы 1:MM неоднозначно. astimezone() имитирует поведение местных часов, отображая два соседних часа UTC в один и тот же местный час. В восточном примере время UTC в форме 5:MM и 6:MM сопоставляется с 1:MM при преобразовании в восточное время, но более раннее время содержит атрибут fold, установленный на 0, а более поздние времена — на 1. Например, при переходе на осень 2016 года мы получаем:

>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
>>> for i in range(4):
...     u = u0 + i*HOUR
...     t = u.astimezone(Eastern)
...     print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
...
04:00:00 UTC = 00:00:00 EDT 0
05:00:00 UTC = 01:00:00 EDT 0
06:00:00 UTC = 01:00:00 EST 1
07:00:00 UTC = 02:00:00 EST 0

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

Приложения, которые не могут переносить неоднозначности настенного времени, должны явно проверять значение атрибута fold или избегать использования гибридных подклассов tzinfo; нет двусмысленностей при использовании timezone или любого другого подкласса tzinfo с фиксированным смещением (например, класса, представляющего только EST (фиксированное смещение -5 часов) или только EDT (фиксированное смещение -4 часа)).

См.также

dateutil.tz

У модуля datetime есть базовый класс timezone (для обработки произвольных фиксированных смещений от UTC) и его timezone.utc атрибут (экземпляр часового пояса UTC).

Библиотека dateutil.tz выводит IANA базу данных часовых поясов (также известную как база данных Olson) в Python, и рекомендуется его использование.

IANA база данных часовых поясов
База данных часовых поясов (часто называемая tz, tzdata или zoneinfo) содержит код и данные, представляющие историю локальная времени для многих репрезентативных местоположений по всему миру. Он периодически обновляется для отражения изменений, внесенных политическими органами в границы часового пояса, смещения UTC и правила перехода на летнее время.

Объекты timezone

Класс timezone является подклассом tzinfo, каждый экземпляр которого представляет часовой пояс, определенный фиксированным смещением от UTC.

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

class datetime.timezone(offset, name=None)

Аргумент offset должен быть указан как объект timedelta, представляющий разницу между местным временем и временем в формате UTC. Он должен находиться строго между -timedelta(hours=24) и timedelta(hours=24), в противном случае будет поднято ValueError.

Аргумент name не является обязательным. Если указано, это должна быть строка, которая будет использоваться в качестве значения, возвращаемого методом datetime.tzname().

Добавлено в версии 3.2.

Изменено в версии 3.7: Смещение UTC не ограничивается целым числом минут.

timezone.utcoffset(dt)

Возвращает фиксированное значение, указанное при создании экземпляра timezone.

Аргумент dt игнорируется. Возвращаемое значение — экземпляр timedelta, равный разнице между местным временем и временем в формате UTC.

Изменено в версии 3.7: Смещение UTC не ограничивается целым числом минут.

timezone.tzname(dt)

Возвращает фиксированное значение, указанное при создании экземпляра timezone.

Если name не указано в конструкторе, имя, возвращаемое tzname(dt), создается из значения offset следующим образом. Если offsettimedelta(0), имя — «UTC», в противном случае это строка в формате UTC±HH:MM, где ± — знак offset, HH и MM — две цифры offset.hours и offset.minutes соответственно.

Изменено в версии 3.6: Имя, созданное из offset=timedelta(0), теперь представляет собой обычное «UTC», а не 'UTC+00:00'.

timezone.dst(dt)

Всегда возвращает None.

timezone.fromutc(dt)

Возврат dt + offset. Аргумент dt должен быть осведомлённым экземпляром datetime с tzinfo, установленным на self.

Атрибуты класса:

timezone.utc

Часовой пояс UTC: timezone(timedelta(0)).

Поведение strftime() и strptime()

Все объекты date, datetime и time поддерживают метод strftime(format) для создания строки, представляющей время, под контролем явной строки формата.

И наоборот, метод класса datetime.strptime() создаёт объект datetime из строки, представляющей дату и время, и соответствующей строки формата.

В таблице ниже представлено общее сравнение strftime() и strptime():

  strftime strptime
Использование Преобразовать объект в строку в соответствии с заданным форматом Парсинг строки в объект datetime, учитывая соответствующий формат
Тип метода Метод экземпляра Метод класса
Метод из date; datetime; time datetime
Сигнатура strftime(format) strptime(date_string, format)

Коды форматов strftime() и strptime()

Ниже приведен список всех кодов формата, которые требуются стандарту C 1989 года, и они работают на всех платформах со стандартной реализацией C.

Директива Значение Пример Прим.
%a Будний день как сокращенное название в локали.
Sun, Mon, …, Sat (en_US);
So, Mo, …, Sa (de_DE)
(1)
%A День недели как полное название в локали.
Sunday, Monday, …, Saturday (en_US);
Sonntag, Montag, …, Samstag (de_DE)
(1)
%w День недели в виде десятичного числа, где 0 - воскресенье, а 6 - суббота. 0, 1, …, 6  
%d День месяца в виде десятичного числа с лидирующими нулями. 01, 02, …, 31 (9)
%b Месяц как сокращенное название локали.
Jan, Feb, …, Dec (en_US);
Jan, Feb, …, Dez (de_DE)
(1)
%B Месяц как полное имя в локали.
January, February, …, December (en_US);
Januar, Februar, …, Dezember (de_DE)
(1)
%m Месяц в виде десятичного числа с лидирующими нулями. 01, 02, …, 12 (9)
%y Год без века в виде десятичного числа с лидирующими нулями. 00, 01, …, 99 (9)
%Y Год с веком как десятичное число. 0001, 0002, …, 2013, 2014, …, 9998, 9999 (2)
%H Час (24-часовые часы) в виде десятичного числа с нулевым числом. 00, 01, …, 23 (9)
%I Час (12-часовые часы) в виде десятичного числа с нулевым числом. 01, 02, …, 12 (9)
%p Языковой стандарт эквивалентен AM или PM.
AM, PM (en_US);
am, pm (de_DE)
(1), (3)
%M Минута в виде десятичного числа с нулевым числом. 00, 01, …, 59 (9)
%S Секунда в виде десятичного числа с нулевым заполнением. 00, 01, …, 59 (4), (9)
%f Микросекунда - десятичное число, заполненное нулем слева. 000000, 000001, …, 999999 (5)
%z Смещение UTC в формате ±HHMM[SS[.ffffff]] (пустая строка, если объект наивен). (empty), +0000, -0400, +1030, +063415, -030712.345216 (6)
%Z Имя часового пояса (пустая строка, если объект является наивным). (empty), UTC, EST, CST  
%j День года в виде десятичного числа с нулевым числом. 001, 002, …, 366 (9)
%U Номер недели года (воскресенье как первый день недели) в виде нулевого десятичного числа. Все дни в новом году, предшествующие первому воскресенью, считаются 0 в неделе. 00, 01, …, 53 (7), (9)
%W Номер недели года (понедельник как первый день недели) в виде десятичного числа. Все дни в новом году, предшествующие первому понедельнику, считаются неделями 0. 00, 01, …, 53 (7), (9)
%c Соответствующее представление даты и времени языкового стандарта.
Tue Aug 16 21:30:00 1988 (en_US);
Di 16 Aug 21:30:00 1988 (de_DE)
(1)
%x Соответствующее представление даты языкового стандарта.
08/16/88 (None);
08/16/1988 (en_US);
16.08.1988 (de_DE)
(1)
%X Соответствующее представление времени языкового стандарта.
21:30:00 (en_US);
21:30:00 (de_DE)
(1)
%% А литерал '%' символ. %  

Для удобства включены несколько дополнительных директив, не требуемых стандартом C89. Все параметры соответствуют значениям даты ISO 8601.

Директива Значение Пример Прим.
%G ISO 8601 год с веком, представляющим год, который содержит большую часть ISO недели (%V). 0001, 0002, …, 2013, 2014, …, 9998, 9999 (8)
%u День недели ISO 8601 в виде десятичного числа, где 1 - понедельник. 1, 2, …, 7  
%V Неделя ISO 8601 в виде десятичного числа с понедельником в качестве первого дня недели. Неделя 01 - это неделя, содержащая 4 января. 01, 02, …, 53 (8), (9)

Они могут быть доступны не на всех платформах при использовании с методом strftime(). Директивы ISO 8601 год и ISO 8601 неделя не взаимозаменяемы с указанными выше директивами года и недели. Вызов strptime() с неполными или неоднозначными директивами ISO 8601 вызовет ValueError.

Полный набор поддерживаемых кодов форматов различается в зависимости от платформы, поскольку Python вызывает функцию strftime() библиотеки C платформы, и варианты платформы являются обычными. Чтобы увидеть полный набор кодов формата, поддерживаемых вашей платформой, обратитесь к документации strftime(3).

Добавлено в версии 3.6: Добавлены %G, %u и %V.

Техническая деталь

Вообще говоря, d.strftime(fmt) действует как time.strftime(fmt, d.timetuple()) модуля time, хотя не все объекты поддерживают метод timetuple().

Для метода класса datetime.strptime() значение по умолчанию — 1900-01-01T00:00:00.000: любые компоненты, не указанные в строке формата, будут извлечены из значения по умолчанию. [4]

Использование datetime.strptime(date_string, format) эквивалентно:

datetime(*(time.strptime(date_string, format)[0:6]))

кроме случаев, когда формат включает в себя субсекундные компоненты или информацию о смещении часового пояса, которые поддерживаются в datetime.strptime, но отбрасываются time.strptime.

Для объектов time не следует использовать коды формата для года, месяца и дня, поскольку объекты time не имеют таких значений. Если они все равно используются, год заменяется 1900, а месяц и день — 1.

Для объектов date не следует использовать коды формата для часов, минут, секунд и микросекунд, поскольку объекты date не имеют таких значений. Если они все равно используются, их заменяет 0.

По той же причине обработка строк формата, содержащих Юникод кодовые точки, которые не могут быть представлены в кодировке текущего языкового стандарта, также зависит от платформы. На некоторых платформах такие кодовые точки сохраняются в выводе без изменений, в то время как на других strftime может вызывать UnicodeError или вместо этого возвращать пустую строку.

Примечания:

  1. Поскольку формат зависит от текущего языкового стандарта, следует проявлять осторожность, делая предположения о выходном значении. Порядок полей будет различаться (например, «месяц/день/год» по сравнению с «день/месяц/ год»), а выходные данные могут содержать символы Юникода, закодированные с использованием кодировки по умолчанию для языкового стандарта (например, если текущий языковой стандарт — ja_JP, кодировка по умолчанию может быть любой из eucJP, SJIS или utf-8; используйте locale.getlocale() для определения кодировки текущей локали).

  2. Метод strptime() может анализировать годы в полном диапазоне [1, 9999], но годы < 1000 должны быть заполнены нулями до 4-значной ширины.

    Изменено в версии 3.2: В предыдущих версиях метод strftime() был ограничен годами >= 1900.

    Изменено в версии 3.3: В версии 3.2 метод strftime() был ограничен годами >= 1000.

  3. При использовании с методом strptime() директива %p влияет только на поле выходного часа, если для синтаксического анализа часа используется директива %I.

  4. В отличие от модуля time, модуль datetime не поддерживает дополнительные секунды.

  5. При использовании с методом strptime() директива %f принимает от одной до шести цифр и нулевые поля справа. %f — это расширение набора символов формата в стандарте C (но реализовано отдельно в объектах datetime и поэтому всегда доступно).

  6. Для наивного объекта коды формата %z и %Z заменяются пустыми строками.

    Для знающего объекта:

    %z utcoffset() преобразуется в строку формы ±HHMM[SS[.ffffff]], где HH — это двухзначная строка, дающая номер часов смещения UTC, MM — это двухзначная строка, дающая номер UTC смещение минут, SS — это двухзначная строка, дающая номер смещения UTC секунд, а ffffff — это строка из 6 цифр, дающая номер UTC смещение микросекунд. Часть ffffff пропускается, если смещение равно a целое количество секунд и ffffff и SS часть опускается, если смещение составляет целое количество минут. Например, если utcoffset() возвращает timedelta(hours=-3, minutes=-30), %z - заменяется строкой '-0330'.

    Изменено в версии 3.7: Смещение UTC не ограничивается целым числом минут.

    Изменено в версии 3.7: Когда директива %z предоставляется методу strptime(), смещения UTC могут иметь двоеточие в качестве разделителя между часами, минутами и секундами. Например, '+01:00:00' будет проанализирован как смещение в один час. Кроме того, предоставление 'Z' идентично '+00:00'.

    %Z Если tzname() возвращает None, %Z заменяется пустой строкой. В противном случае %Z заменяется возвращаемым значением, которое должно быть быть строкой.

    Изменено в версии 3.2: Когда директива %z предоставлена методу strptime(), будет создан известный объект datetime. tzinfo результата будет установлен на экземпляр timezone.

  7. При использовании с методом strptime(), %U и %W используются в расчётах только тогда, когда указаны день недели и календарный год (%Y).

  8. Подобно %U и %W, %V используется в вычислениях только тогда, когда день недели и год ISO (%G) указаны в строке формата strptime(). Также обратите внимание, что %G и %Y не взаимозаменяемы.

  9. При использовании метода strptime() ведущий ноль является необязательным для форматов %d, %m, %H, %I, %M, %S, %J, %U, %W и %V. Формат %y требует ведущего нуля.

Сноски

[1]Если есть, мы игнорируем эффекты Относительности
[2]Это соответствует определению «Пролептического Григорианского» календаря в Дершовица и книге Рейнгольда Календарные расчёты, где это базовый календарь для всех вычислений. Смотрите в книге алгоритмы преобразования между Пролептическими Григорианскими ординалами и многими другими календарными системами.
[3]См. Р. Х. ван Гента Руководство по математике календаря ISO 8601 для подробного объяснения.
[4]Предача datetime.strptime('Feb 29', '%b %d') провалится, т. к. 1900 не високосный год.