Документация Python неофициальный перевод
Содержание страницы

datetime – Основные типы даты и времениdatetime – Basic date and time types

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


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

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

См. также

Модуль calendar

Общие функции, связанные с календарём.

Модуль time

Доступ к времени и преобразования.

Модуль zoneinfo

Конкретные часовые пояса, представляющие базу данных часовых поясов IANA.

Пакет dateutil

Сторонняя библиотека с расширенной поддержкой часовых поясов и разбора.

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

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

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

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

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

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

КонстантыConstants

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

datetime.MINYEAR

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

datetime.MAXYEAR

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

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

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

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

Типы date, datetime, time и timezone имеют следующие общие особенности:

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

  • Объекты этих типов являются хешируемыми, то есть могут использоваться в качестве ключей словаря.

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

Определение, является ли объект осведомлённым или наивнымDetermining if an Object is Aware or Naive

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

Объект типа time или datetime может быть aware или naive.

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

  1. d.tzinfo не является None

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

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

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

  1. t.tzinfo не является None

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

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

Различие между aware и naive не применимо к объектам timedelta .

timedelta Объектыtimedelta Objects

Объект 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 истинны. (1)

t1 = t2 - t3

Разность t2 и t3. После этого t1 == t2 - t3 и t2 == t1 + t3 истинны. (1)(6)

t1 = t2 * i or t1 = i * t2

Дельта, умноженная на целое число. После этого t1 // i == t2 истинно при условии i != 0.

В общем случае, t1 * i == t1 * (i-1) + t1 является истинным. (1)

t1 = t2 * f or t1 = f * t2

Дельта, умноженная на число с плавающей запятой. Результат округляется до ближайшего кратного timedelta.resolution по правилу round-half-to-even.

f = t2 / t3

Деление (3) общей длительности t2 на единицу интервала t3. Возвращает объект float.

t1 = t2 / f or t1 = t2 / i

Дельта, делённая на число с плавающей запятой или целое число. Результат округляется до ближайшего кратного timedelta.resolution по правилу round-half-to-even.

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. Например:

    >>> 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.

Примеры использования: timedeltaExamples of usage: 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 Objects

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

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

class datetime.date(year, month, day)

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

  • MINYEAR <= year <= MAXYEAR

  • 1 <= month <= 12

  • 1 <= day <= number of days in the given month and year

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

Другие конструкторы – все методы класса:

classmethod date.today()

Возвращает текущую локальную дату.

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

classmethod date.fromtimestamp(timestamp)

Возвращает локальную дату, соответствующую метке времени POSIX, такую, как возвращает функция time.time().

Это может вызвать OverflowError, если метка времени находится за пределами диапазона значений, поддерживаемого функцией C localtime() платформы, и 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, соответствующий строке с датой, заданной в формате 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()

Возвращает объект именованный кортеж с тремя компонентами: year, week и weekday.

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

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

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

>>> from datetime import date
>>> date(2003, 12, 29).isocalendar()
datetime.IsoCalendarDate(year=2004, week=1, weekday=1)
>>> date(2004, 1, 4).isocalendar()
datetime.IsoCalendarDate(year=2004, week=1, weekday=7)

Изменено в версии 3.9: Результат изменён с кортежа на именованный кортеж.

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)

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

date.__format__(format)

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

Примеры использования: dateExamples of Usage: 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                # year
3                   # month
11                  # day
0
0
0
0                   # weekday (0 = Monday)
70                  # 70th day in the year
-1
>>> ic = d.isocalendar()
>>> for i in ic:    
...     print(i)
2002                # ISO year
11                  # ISO week number
1                   # ISO day number ( 1 = Monday )

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

datetime Объектыdatetime Objects

Объект 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 предпочтительнее использовать осведомлённые объекты datetime. Поэтому рекомендуемый способ создания объекта, представляющего текущее время в 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)

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

Это может возбуждать OverflowError, если метка времени выходит за диапазон значений, поддерживаемых платформенной функцией C gmtime(), и 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 предпочтительнее использовать aware-даты. Поэтому рекомендуемый способ создания объекта для конкретной метки времени в 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.

Для любого объекта datetime d d == datetime.combine(d.date(), d.time(), d.tzinfo). Если date является объектом 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. Обратите внимание, что корректировка часового пояса не производится, даже если входной объект является осведомленным (aware).

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

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

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

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

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

    Если один операнд сравнения является наивным (naive), а другой – aware, то TypeError возбуждается при попытке упорядочивающего сравнения. Для сравнений на равенство наивные экземпляры никогда не равны aware-экземплярам.

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

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

    Примечание

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

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

datetime.date()

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

datetime.time()

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

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

datetime.timetz()

Возвращает объект time с теми же атрибутами hour, minute, second, microsecond, fold и tzinfo. См. также метод time().

Изменено в версии 3.6: Значение fold копируется в возвращаемый объект 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)

Возвращает datetime с теми же атрибутами, за исключением тех, для которых заданы новые значения с помощью переданных именованных аргументов. Обратите внимание: 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()

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

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

datetime.dst()

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

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

datetime.tzname()

Если tzinfo равно None, возвращается 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 как местное время, предпочтительнее использовать осознанные объекты datetime для представления времени в UTC; как результат, использование datetime.utctimetuple() может давать вводящие в заблуждение результаты. Если у вас есть наивный datetime, представляющий UTC, используйте datetime.replace(tzinfo=timezone.utc), чтобы сделать его осознанным, после чего можно использовать datetime.timetuple().

datetime.toordinal()

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

datetime.timestamp()

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

Считается, что наивные экземпляры datetime представляют местное время, и этот метод полагается на функцию mktime() платформы C для выполнения преобразования. Поскольку 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()

Возвращает именованный кортеж с тремя компонентами: year, week и weekday. То же, что 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__()

Для экземпляра datetime d, 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'

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

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().

Примеры использования: datetimeExamples of Usage: 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    # year
11      # month
21      # day
16      # hour
30      # minute
0       # second
1       # weekday (0 = Monday)
325     # number of days since 1st January
-1      # dst - method tzinfo.dst() returned None

>>> # Дата в формате ISO
>>> ic = dt.isocalendar()
>>> for it in ic:   
...     print(it)
...
2006    # ISO year
47      # ISO week
2       # ISO weekday

>>> # Форматирование datetime
>>> 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, который фиксирует информацию о часовом поясе для Кабула (Афганистан). До 1945 года там использовалось смещение +4 UTC, а затем +4:30 UTC:

from datetime import timedelta, datetime, tzinfo, timezone

class KabulTz(tzinfo):
    # В Кабуле до 1945 года использовали +4, затем перешли на +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()

>>> # Datetime до изменения
>>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1)
>>> print(dt1.utcoffset())
4:00:00

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

>>> # Преобразовать datetime в другой часовой пояс
>>> 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 Objects

Объект 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 по времени. Если один операнд сравнения является наивным (naive), а другой – aware, то TypeError возбуждается при попытке упорядочивающего сравнения. Для сравнений на равенство наивные экземпляры никогда не равны aware-экземплярам.

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

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

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

Изменено в версии 3.5: До Python 3.5 объект time считался ложным, если он представлял полночь в UTC. Это поведение считалось неочевидным и чреватым ошибками и было удалено в 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 в f-строках и при использовании str.format(). Полный список директив форматирования см. Поведение strftime() и strptime().

time.utcoffset()

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

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

time.dst()

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

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

time.tzname()

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

Примеры использования: timeExamples of Usage: 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 Объектыtzinfo Objects

class datetime.tzinfo

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

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

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

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

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

tzinfo.utcoffset(dt)

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

Это представляет общее смещение от UTC; например, если объект tzinfo представляет как часовой пояс, так и корректировки DST, 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, если информация о DST неизвестна.

Возвращает 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):
    # класс с фиксированным смещением: не учитывает летнее время
    return timedelta(0)

или:

def dst(self, dt):
    # Код для установки dston и dstoff в значения летнего времени часового пояса
    # переходные моменты времени на основе входного 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)

Возвращает название часового пояса, соответствующее объекту datetime dt, в виде строки. Модуль 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 или 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-смещение и/или правила летнего времени
#  менялись в прошлом.)
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
        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()


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

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


# Правила летнего времени в США
#
# Это упрощённый набор правил для США (т.е. неверный для некоторых случаев)
# времени начала и окончания летнего времени. Полный и актуальный набор правил летнего времени
# и определений часовых поясов смотрите в базе данных Olson (или попробуйте pytz):
# http://www.twinsun.com/tz/tz-link.htm
# https://sourceforge.net/projects/pytz/ (возможно, не актуально)
#
# В США с 2007 года летнее время начинается в 2 часа ночи (стандартное время) во второе
# воскресенье марта, то есть первое воскресенье 8 марта или после него.
DSTSTART_2007 = datetime(1, 3, 8, 2)
# и заканчивается в 2 часа ночи (летнее время) в первое воскресенье ноября.
DSTEND_2007 = datetime(1, 11, 1, 2)
# С 1987 по 2006 год летнее время начиналось в 2 часа ночи (стандартное время) в первое
# воскресенье апреля и заканчивалось в 2 часа ночи (летнее время) в последнее
# воскресенье октября, то есть первое воскресенье 25 октября или после него.
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
DSTEND_1987_2006 = datetime(1, 10, 25, 2)
# С 1967 по 1986 год летнее время начиналось в 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:
            # Сложить (неоднозначный час): используйте dt.fold для разрешения неоднозначности.
            return ZERO if dt.fold else HOUR
        if start <= dt < start + HOUR:
            # Gap (несуществующий час): примените обратное правило fold.
            return HOUR if dt.fold else ZERO
        # Летнее время не действует.
        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, учитывающем как стандартное, так и летнее время, дважды в год в точках перехода на летнее время возникают неизбежные тонкости. Для конкретики рассмотрим восточное время США (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

Когда начинается летнее время (строка «start»), местные настенные часы перескакивают с 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

Когда заканчивается летнее время (строка «end»), возникает потенциально более серьёзная проблема: есть час, который невозможно однозначно выразить в местном настенном времени – последний час летнего времени. В восточном поясе это время вида 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 часа)).

См. также

zoneinfo

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

zoneinfo предоставляет базу данных часовых поясов IANA (также известную как база данных Олсона) в Python, и её использование рекомендуется.

база данных часовых поясов IANA

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

timezone Объектыtimezone Objects

Класс 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 следующим образом. Если offset равно timedelta(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() Поведениеstrftime() and strptime() Behavior

Объекты 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() Коды форматовstrftime() and strptime() Format Codes

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

Директива

Значение

Пример

Примечания

%a

День недели как сокращённое название в локали.

Вс, Пн, …, Сб (en_US);
So, Mo, …, Sa (de_DE)

(1)

%A

Название дня недели в полной форме, зависящее от локали.

Воскресенье, Понедельник, …, Суббота (en_US);
Sonntag, Montag, …, Samstag (de_DE)

(1)

%w

День недели в виде десятичного числа, где 0 – воскресенье, а 6 – суббота.

0, 1, …, 6

%d

День месяца в виде десятичного числа, дополненного слева нулями.

01, 02, …, 31

(9)

%b

Название месяца в сокращённой форме, зависящей от локали.

Янв, Фев, …, Дек (en_US);
Jan, Feb, …, Dez (de_DE)

(1)

%B

Название месяца в полной форме, зависящей от локали.

Январь, Февраль, …, Декабрь (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

Микросекунды в виде десятичного числа, дополненного слева нулями до 6 цифр.

000000, 000001, …, 999999

(5)

%z

Смещение UTC в формате ±HHMM[SS[.ffffff]] (пустая строка, если объект наивный).

(пусто), +0000, -0400, +1030, +063415, -030712.345216

(6)

%Z

Название часового пояса (пустая строка, если объект наивный).

(пусто), UTC, GMT

(6)

%j

День года в виде десятичного числа, дополненного слева нулями.

001, 002, …, 366

(9)

%U

Номер недели в году (воскресенье – первый день недели) в виде десятичного числа, дополненного слева нулями. Все дни в новом году до первого воскресенья считаются неделей 0.

00, 01, …, 53

(7), (9)

%W

Номер недели в году (понедельник – первый день недели) в виде десятичного числа, дополненного слева нулями. Все дни в новом году до первого понедельника считаются неделей 0.

00, 01, …, 53

(7), (9)

%c

Представление даты и времени, подходящее для локали.

Вт Авг 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 8601 (%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 были добавлены.

Технические деталиTechnical Detail

В целом, d.strftime(fmt) действует как time из модуля time.strftime(fmt, d.timetuple()), хотя не все объекты поддерживают метод 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.

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

Примечания:

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

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

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

    Изменено в версии 3.3: В версии 3.2 метод strftime() был ограничен gодами >= 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 – шестисимвольная строка, задающая количество микросекунд смещения UTC. Часть ffffff опускается, если смещение составляет целое число секунд, а части 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

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

    strptime() принимает только определённые значения для %Z:

    1. любое значение из time.tzname для локали вашей системы

    2. жёстко заданные значения UTC и GMT

    Так, человек, живущий в Японии, может иметь JST, UTC и GMT в качестве допустимых значений, но, вероятно, не EST. Для недопустимых значений будет возбуждено ValueError.

    Изменено в версии 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

Это соответствует определению пролептического григорианского календаря в книге Дершовица и Рейнгольда Calendrical Calculations, где он является базовым календарём для всех вычислений. Смотрите книгу для алгоритмов преобразования между пролептическими григорианскими порядковыми номерами и многими другими календарными системами.

3

Смотрите руководство по математике календаря ISO 8601 Р. Х. ван Гента для хорошего объяснения.

4

Передача datetime.strptime('Feb 29', '%b %d') завершится ошибкой, поскольку 1900 не является високосным годом.