Spec-Zone.ru › Python 3.13

datetime — базовые типы даты и времени

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

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

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

Совет

Перейти к кодам формата.

См. также

Module calendar

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

Module time

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

Module zoneinfo

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

Пакет dateutil

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

Пакет DateType

Сторонняя библиотека, вводящая отдельные статические типы, чтобы, например, средства статической проверки типов могли различать даты и время без сведений о часовом поясе и с такими сведениями.

Объекты с часовым поясом и без него

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

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

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

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

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

Константы

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

datetime.MINYEAR

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

datetime.MAXYEAR

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

datetime.UTC

Псевдоним для единственного экземпляра часового пояса UTC datetime.timezone.utc.

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

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

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

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

class datetime.tzinfo

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

class datetime.timezone

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

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

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

Иерархия подклассов:

object
    timedelta
    tzinfo
        timezone
    time
    date
        datetime

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

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

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

Определение наличия сведений о часовом поясе

Объекты типа date всегда не содержат сведений о часовом поясе.

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

Объект 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 не содержит сведений о часовом поясе.

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

Объекты timedelta

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

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

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

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

  • Миллисекунды преобразуются в микросекунды (умножаются на 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
... )
>>> # Only days, seconds, and microseconds remain
>>> 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 может быть неочевидным, используйте следующий рецепт, чтобы получить более удобный для чтения формат:

>>> def pretty_timedelta(td):
...     if td.days >= 0:
...         return str(td)
...     return f'-({-td!s})'
...
>>> d = timedelta(hours=-1)
>>> str(d)  # not human-friendly
'-1 day, 23:00:00'
>>> pretty_timedelta(d)
'-(1:00:00)'

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

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.

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

timedelta.days

От -999 999 999 до 999 999 999 включительно.

timedelta.seconds

От 0 до 86 399 включительно.

Внимание

Довольно распространённая ошибка — непреднамеренно использовать этот атрибут, хотя на самом деле требуется получить значение total_seconds():

>>> from datetime import timedelta
>>> duration = timedelta(seconds=11235813)
>>> duration.days, duration.seconds
(130, 3813)
>>> duration.total_seconds()
11235813.0
timedelta.microseconds

От 0 до 999 999 включительно.

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

Операция

Результат

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 с разрешением равенства в пользу чётного числа.

f = t2 / t3

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

t1 = t2 / f or t1 = t2 / i

Деление дельты на число с плавающей запятой или целое число. Результат округляется до ближайшего кратного 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. Деление на ноль вызывает исключение 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 поддерживают сравнение на равенство и упорядочение.

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

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

timedelta.total_seconds()

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

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

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

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

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

>>> # Components of another_year add up to exactly 365 days
>>> 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 <= 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, если метка времени выходит за пределы диапазона значений, поддерживаемого функцией localtime() платформы C, и исключение OSError при сбое localtime(). Обычно диапазон ограничен годами с 1970 по 2038. Обратите внимание, что в системах, отличных от POSIX, которые включают високосные секунды в своё представление метки времени, високосные секунды игнорируются методом fromtimestamp().

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

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, заданной в любом допустимом формате ISO 8601, за следующими исключениями:

  1. Даты с сокращённой точностью пока не поддерживаются (YYYY-MM, YYYY).
  2. Расширенные представления дат пока не поддерживаются (±YYYYYY-MM-DD).
  3. Порядковые даты пока не поддерживаются (YYYY-OOO).

Примеры:

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

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

Изменено в версии 3.11: Ранее этот метод поддерживал только формат YYYY-MM-DD.

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)

Сравнение на равенство. (4)

Сравнение на упорядочение. (5)

Примечания:

  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. Объекты date равны, если они представляют одну и ту же дату.

    Объекты date, которые не являются экземплярами datetime, никогда не равны объектам datetime, даже если они представляют одну и ту же дату.

  5. date1 считается меньшей, чем date2, если date1 предшествует date2 во времени. Иными словами, date1 < date2 тогда и только тогда, когда date1.toordinal() < date2.toordinal().

    Сравнение на упорядочение объекта date, который не является экземпляром datetime, и объекта datetime вызывает исключение TypeError.

Изменено в версии 3.13: Сравнение объекта datetime и экземпляра подкласса date, который не является подклассом datetime, больше не преобразует последний в date, игнорируя часть, относящуюся ко времени, и часовой пояс. Поведение по умолчанию можно изменить, переопределив специальные методы сравнения в подклассах.

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

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

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

Возвращает новый объект date с теми же значениями, но с обновлёнными указанными параметрами.

Пример:

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

Универсальная функция copy.replace() также поддерживает объекты date.

date.timetuple()

Возвращает time.struct_time, аналогичный возвращаемому функцией time.localtime().

Часы, минуты и секунды равны 0, а флаг летнего времени равен -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.__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()))

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

date.strftime(format)

Возвращает строку, представляющую дату; формат задаётся явной строкой формата. Для кодов формата, обозначающих часы, минуты или секунды, будут использоваться нулевые значения. См. также разделы Поведение strftime() и strptime() и date.isoformat().

date.__format__(format)

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

Примеры использования: 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) # 730920th day after 1. 1. 0001
>>> d
datetime.date(2002, 3, 11)

>>> # Methods related to formatting string output
>>> 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.'

>>> # Methods for to extracting 'components' under different calendars
>>> 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 )

>>> # A date object is immutable; all operations produce a new object
>>> 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().

Примечание

Последовательные вызовы datetime.now() могут возвращать один и тот же момент времени в зависимости от точности используемых часов.

classmethod datetime.utcnow()

Возвращает текущие дату и время UTC; значение tzinfo равно None.

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

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

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

Устарело начиная с версии 3.12: Вместо этого используйте datetime.now() с 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: Если временная метка выходит за диапазон значений, поддерживаемых функциями C платформы localtime() или gmtime(), возбуждается исключение OverflowError вместо ValueError. При сбое localtime() или gmtime() возбуждается исключение OSError вместо ValueError.

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

classmethod datetime.utcfromtimestamp(timestamp)

Возвращает объект UTC datetime, соответствующий временной метке 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 рекомендуется использовать объекты datetime с часовым поясом. Поэтому рекомендуемый способ создать объект, представляющий определённую временную метку UTC, — вызвать datetime.fromtimestamp(timestamp, tz=timezone.utc).

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

Устарело начиная с версии 3.12: Вместо этого используйте datetime.fromtimestamp() с UTC.

classmethod datetime.fromordinal(ordinal)

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

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

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

Для любого объекта datetime d, d == datetime.combine(d.date(), d.time(), d.tzinfo).

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

classmethod datetime.fromisoformat(date_string)

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

  1. Смещения часовых поясов могут включать дробные секунды.
  2. Разделитель T может быть заменён любым одиночным символом Unicode.
  3. Дробные часы и минуты не поддерживаются.
  4. Даты с пониженной точностью пока не поддерживаются (YYYY-MM, YYYY).
  5. Расширенные представления даты пока не поддерживаются (±YYYYYY-MM-DD).
  6. Порядковые даты пока не поддерживаются (YYYY-OOO).

Примеры:

>>> from datetime import datetime
>>> datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)
>>> datetime.fromisoformat('20111104')
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-04T00:05:23Z')
datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('20111104T000523')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> datetime.fromisoformat('2011-W01-2T00:05:23.283')
datetime.datetime(2011, 1, 4, 0, 5, 23, 283000)
>>> 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.

Изменено в версии 3.11: Ранее этот метод поддерживал только форматы, которые могли быть созданы с помощью date.isoformat() или datetime.isoformat().

classmethod datetime.fromisocalendar(year, week, day)

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

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

classmethod datetime.strptime(date_string, format)

Возвращает объект datetime, соответствующий строке date_string, разобранной согласно формату format.

Если format не содержит микросекунд или сведений о часовом поясе, это эквивалентно:

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

Исключение ValueError возбуждается, если строку date_string и формат не удаётся разобрать с помощью time.strptime() или если функция возвращает значение, не являющееся кортежем времени. См. также разделы Поведение strftime() и strptime() и datetime.fromisoformat().

Изменено в версии 3.13: Если в format указан день месяца без года, теперь выдаётся предупреждение DeprecationWarning. Это позволяет избежать повторяющейся раз в четыре года ошибки високосного года в коде, предназначенном для разбора только месяца и дня: год по умолчанию, используемый при отсутствии года в формате, не является високосным. Начиная с Python 3.15 такие значения format могут приводить к ошибке. В качестве обходного решения всегда указывайте год в format. Если разбираются значения date_string без года, явно добавьте перед разбором високосный год:

>>> from datetime import datetime
>>> date_string = "02/29"
>>> when = datetime.strptime(f"{date_string};1984", "%m/%d;%Y")  # Avoids leap year bug.
>>> when.strftime("%B %d")
'February 29'

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

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)

Сравнение на равенство. (4)

Сравнение порядка. (5)

  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 игнорируются, а результатом является объект timedelta t такой, что datetime2 + t == datetime1. В этом случае коррекция часового пояса не выполняется.

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

  4. Объекты datetime равны, если представляют одинаковые дату и время с учётом часового пояса.

    Наивные объекты datetime и объекты с часовым поясом никогда не равны.

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

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

    Сравнение порядка между наивными объектами datetime и объектами с часовым поясом возбуждает исключение TypeError.

    Если оба сравниваемых объекта имеют часовой пояс и одинаковый атрибут tzinfo, атрибуты tzinfo и fold игнорируются, а базовые объекты datetime сравниваются. Если оба сравниваемых объекта имеют часовой пояс и разные атрибуты tzinfo, сравнение выполняется так, как если бы объекты сначала были преобразованы в даты и время UTC, за исключением того, что реализация никогда не допускает переполнения.

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

Изменено в версии 3.13: При сравнении объекта datetime с экземпляром подкласса date, который не является подклассом datetime, последний больше не преобразуется в date с игнорированием части, относящейся ко времени, и часового пояса. Поведение по умолчанию можно изменить, переопределив специальные методы сравнения в подклассах.

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

datetime.date()

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

datetime.time()

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

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

datetime.timetz()

Возвращает объект time с теми же атрибутами часа, минуты, секунды, микросекунды, 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 с часовым поясом, не преобразуя данные даты и времени.

Объекты datetime также поддерживаются универсальной функцией copy.replace().

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

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

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

def astimezone(self, tz):
    if self.tzinfo is tz:
        return self
    # Convert self to UTC, and attach the new timezone object.
    utc = (self - self.utcoffset()).replace(tzinfo=tz)
    # Convert from UTC to tz's local time.
    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 как местное время, для представления времени UTC рекомендуется использовать datetime с часовым поясом; поэтому применение datetime.utctimetuple() может привести к вводящим в заблуждение результатам. Если у вас есть наивный 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 или OSError.

Для экземпляров 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):
...     """A time zone with an arbitrary, constant -06:39 offset."""
...     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.

Примечание

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

Если аргумент timespec недопустим, будет вызвано исключение ValueError:

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

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

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

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

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

datetime.strftime(format)

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

datetime.__format__(format)

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

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

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

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

>>> # Using datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)

>>> # Using 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)

>>> # Using datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)

>>> # Using datetime.timetuple() to get tuple of all attributes
>>> 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

>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> for it in ic:
...     print(it)
...
2006    # ISO year
47      # ISO week
2       # ISO weekday

>>> # Formatting a 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):
    # Kabul used +4 until 1945, when they moved to +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):
            # An ambiguous ("imaginary") half-hour range representing
            # a 'fold' in time due to the shift from +4 to +4:30.
            # If dt falls in the imaginary range, use fold to decide how
            # to resolve. See PEP495.
            return timedelta(hours=4, minutes=(30 if dt.fold else 0))
        else:
            return timedelta(hours=4, minutes=30)

    def fromutc(self, dt):
        # Follow same validations as in 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")

        # A custom implementation is required for fromutc as
        # the input to this function is a datetime with utc values
        # but with a tzinfo set to self.
        # See datetime.astimezone or 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):
        # Kabul does not observe daylight saving time.
        return timedelta(0)

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

Пример использования KabulTz, приведённого выше:

>>> tz1 = KabulTz()

>>> # Datetime before the change
>>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1)
>>> print(dt1.utcoffset())
4:00:00

>>> # Datetime after the change
>>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1)
>>> print(dt2.utcoffset())
4:30:00

>>> # Convert datetime to another time zone
>>> 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 поддерживают сравнение на равенство и сравнение порядка: a считается меньше b, если a предшествует b по времени.

Наивные и осведомлённые объекты time никогда не равны. Сравнение порядка между наивными и осведомлёнными объектами time вызывает исключение TypeError.

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

Изменено в версии 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 в любом допустимом формате ISO 8601, со следующими исключениями:

  1. Смещения часовых поясов могут содержать дробные секунды.
  2. Начальный символ T, обычно обязательный в случаях возможной неоднозначности между датой и временем, не требуется.
  3. Дробные секунды могут содержать любое число цифр (все символы после шестого будут усечены).
  4. Дробные часы и минуты не поддерживаются.

Примеры:

>>> from datetime import time
>>> time.fromisoformat('04:23:01')
datetime.time(4, 23, 1)
>>> time.fromisoformat('T04:23:01')
datetime.time(4, 23, 1)
>>> time.fromisoformat('T042301')
datetime.time(4, 23, 1)
>>> time.fromisoformat('04:23:01.000384')
datetime.time(4, 23, 1, 384)
>>> 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)))
>>> time.fromisoformat('04:23:01Z')
datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)
>>> time.fromisoformat('04:23:01+00:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)

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

Изменено в версии 3.11: Ранее этот метод поддерживал только форматы, которые можно было получить с помощью time.isoformat().

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

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

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

Объекты time также поддерживаются универсальной функцией copy.replace().

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

Примечание

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

При недопустимом аргументе timespec будет вызвано исключение ValueError.

Пример:

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

time.__format__(format)

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

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: Смещение летнего времени не ограничивается целым числом минут.

time.tzname()

Если tzinfo равен None, возвращает 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.

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

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

tzinfo.utcoffset(dt)

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

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

return CONSTANT                 # fixed-offset class
return CONSTANT + self.dst(dt)  # daylight-aware class

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

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

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

tzinfo.dst(dt)

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

Если летнее время не действует, верните timedelta(0). Если оно действует, верните смещение в виде объекта timedelta (подробности см. в описании utcoffset()). Обратите внимание: если применимо, поправка на летнее время уже добавлена к смещению относительно UTC, возвращаемому utcoffset(), поэтому вызывать dst() нужно только в том случае, если вас интересуют отдельные сведения о переходе на летнее время. Например, datetime.timetuple() вызывает метод dst() атрибута tzinfo, чтобы определить, какое значение установить флагу tm_isdst, а tzinfo.fromutc() вызывает 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):
    # a fixed-offset class:  doesn't account for DST
    return timedelta(0)

или:

def dst(self, dt):
    # Code to set dston and dstoff to the time zone's DST
    # transition times based on the input dt.year, and expressed
    # in standard local time.

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

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

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

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):
    # raise ValueError error if dt.tzinfo is not self
    dtoff = dt.utcoffset()
    dtdst = dt.dst()
    # raise ValueError if dtoff is None or dtdst is None
    delta = dtoff - dtdst  # this is self's standard offset
    if delta:
        dt += delta   # convert to standard local time
        dtdst = dt.dst()
        # raise ValueError if dtdst is 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)

# A class capturing the platform's idea of local time.
# (May result in wrong values on historical times in
#  timezones where UTC offset and/or the DST rules had
#  changed in the past.)
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
        # Detect 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()


# A complete implementation of current DST rules for major US time zones.

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


# US DST Rules
#
# This is a simplified (i.e., wrong for a few cases) set of rules for US
# DST start and end times. For a complete and up-to-date set of DST rules
# and timezone definitions, visit the Olson Database (or try pytz):
# http://www.twinsun.com/tz/tz-link.htm
# https://sourceforge.net/projects/pytz/ (might not be up-to-date)
#
# In the US, since 2007, DST starts at 2am (standard time) on the second
# Sunday in March, which is the first Sunday on or after Mar 8.
DSTSTART_2007 = datetime(1, 3, 8, 2)
# and ends at 2am (DST time) on the first Sunday of Nov.
DSTEND_2007 = datetime(1, 11, 1, 2)
# From 1987 to 2006, DST used to start at 2am (standard time) on the first
# Sunday in April and to end at 2am (DST time) on the last
# Sunday of October, which is the first Sunday on or after Oct 25.
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
DSTEND_1987_2006 = datetime(1, 10, 25, 2)
# From 1967 to 1986, DST used to start at 2am (standard time) on the last
# Sunday in April (the one on or after April 24) and to end at 2am (DST time)
# on the last Sunday of October, which is the first Sunday
# on or after Oct 25.
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
DSTEND_1967_1986 = DSTEND_1987_2006

def us_dst_range(year):
    # Find start and end times for US DST. For years before 1967, return
    # start = end for no DST.
    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:
            # An exception may be sensible here, in one or both cases.
            # It depends on how you want to treat them.  The default
            # fromutc() implementation (called by the default astimezone()
            # implementation) passes a datetime with dt.tzinfo is self.
            return ZERO
        assert dt.tzinfo is self
        start, end = us_dst_range(dt.year)
        # Can't compare naive to aware objects, so strip the timezone from
        # dt first.
        dt = dt.replace(tzinfo=None)
        if start + HOUR <= dt < end - HOUR:
            # DST is in effect.
            return HOUR
        if end - HOUR <= dt < end:
            # Fold (an ambiguous hour): use dt.fold to disambiguate.
            return ZERO if dt.fold else HOUR
        if start <= dt < start + HOUR:
            # Gap (a non-existent hour): reverse the fold rule.
            return HOUR if dt.fold else ZERO
        # DST is off.
        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:
            # Repeated hour
            return std_time.replace(fold=1)
        if std_time < start or dst_time >= end:
            # Standard time
            return std_time
        if start <= std_time < end - HOUR:
            # Daylight saving time
            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 в день начала летнего времени. Например, при переходе на летнее время весной 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 (экземпляр timezone для часового пояса UTC).

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

База данных часовых поясов 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 следующим образом. Если 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()

Объекты 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()

Эти методы принимают коды формата, которые можно использовать для разбора и форматирования дат:

>>> datetime.strptime('31/01/22 23:59:59.999999',
...                   '%d/%m/%y %H:%M:%S.%f')
datetime.datetime(2022, 1, 31, 23, 59, 59, 999999)
>>> _.strftime('%a %d %b %Y, %I:%M%p')
'Mon 31 Jan 2022, 11:59PM'

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

Директива

Значение

Пример

Примечания

%a

День недели в виде сокращённого названия в соответствии с текущей локалью.

(1)

%A

День недели в виде полного названия в соответствии с текущей локалью.

(1)

%w

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

0, 1, …, 6

%d

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

01, 02, …, 31

(9)

%b

Месяц в виде сокращённого названия в соответствии с текущей локалью.

(1)

%B

Месяц в виде полного названия в соответствии с текущей локалью.

(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 в соответствии с текущей локалью.

(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

Представление даты и времени, соответствующее текущей локали.

(1)

%x

Представление даты, соответствующее текущей локали.

(1)

%X

Представление времени, соответствующее текущей локали.

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

%:z

Смещение относительно UTC в формате ±HH:MM[:SS[.ffffff]] (пустая строка, если объект не содержит сведений о часовом поясе).

(пусто), +00:00, -04:00, +10:30, +06:34:15, -03:07:12.345216

(6)

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

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

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

Добавлено в версии 3.12: Добавлена %:z.

Технические подробности

В целом 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. Поскольку формат зависит от текущей локали, следует с осторожностью делать предположения о результирующем значении. Порядок полей может различаться (например, «месяц/день/год» или «день/месяц/год»), а вывод может содержать символы, не входящие в ASCII.
  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 заменяются пустыми строками.

    Для объекта с часовым поясом:

    %z

    utcoffset() преобразуется в строку вида ±HHMM[SS[.ffffff]], где HH — это строка из 2 цифр, указывающая количество часов смещения относительно UTC, MM — строка из 2 цифр, указывающая количество минут смещения относительно UTC, SS — строка из 2 цифр, указывающая количество секунд смещения относительно UTC, а ffffff — строка из 6 цифр, указывающая количество микросекунд смещения относительно 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

    Работает точно так же, как %z, но между часами, минутами и секундами добавляется разделитель в виде двоеточия.

    %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 используется в вычислениях только тогда, когда в строке формата strptime() указаны день недели и год ISO (%G). Обратите также внимание, что %G и %Y не взаимозаменяемы.
  9. При использовании с методом strptime() начальный ноль необязателен для форматов %d, %m, %H, %I, %M, %S, %j, %U, %W и %V. Для формата %y начальный ноль обязателен.
  10. При разборе месяца и дня с помощью strptime() всегда указывайте год в формате. Если в разбираемом значении год отсутствует, добавьте явный фиктивный високосный год. В противном случае при обработке високосного дня код вызовет исключение, поскольку год, используемый анализатором по умолчанию, не является високосным. Пользователи сталкиваются с этой ошибкой каждые четыре года…

    >>> month_day = "02/29"
    >>> datetime.strptime(f"{month_day};1984", "%m/%d;%Y")  # No leap year bug.
    datetime.datetime(1984, 2, 29, 0, 0)
    

    Устарело с версии 3.13, будет удалено в версии 3.15: Вызовы strptime() со строкой формата, содержащей день месяца без года, теперь выдают предупреждение DeprecationWarning. В версии 3.15 или более поздней это поведение может быть изменено так, чтобы вызывалась ошибка или вместо этого использовался високосный год по умолчанию. См. gh-70647.

Сноски

[1]

То есть если не учитывать эффекты теории относительности

[2]

Это соответствует определению «пролептического григорианского» календаря в книге Dershowitz и Reingold Calendrical Calculations, где он служит базовым календарём для всех вычислений. Алгоритмы преобразования порядковых номеров пролептического григорианского календаря в другие календарные системы и обратно см. в книге.

[3]

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

[4]

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

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/datetime.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API