Spec-Zone.ru › Python 3.14

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

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

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

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

Совет

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

См. также

Module calendar

Общие функции для работы с календарями.

Module time

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

Module zoneinfo

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

Пакет dateutil

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

Пакет DateType

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

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

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

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

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

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

timedelta, tzinfo, time, and date inherit from object; timezone inherits from tzinfo; and datetime inherits from date.

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

Типы 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, объединяются и нормализуются в эти три итоговых атрибута:

>>> import datetime as dt
>>> delta = dt.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)

Совет

Используйте import datetime as dt вместо import datetime или from datetime import datetime, чтобы не путать модуль и класс. См. Как я импортирую модуль datetime в Python.

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

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

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

>>> import datetime as dt
>>> d = dt.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():

>>> import datetime as dt
>>> duration = dt.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(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
>>> import datetime as dt
>>> year = dt.timedelta(days=365)
>>> another_year = dt.timedelta(weeks=40, days=84, hours=23,
...                             minutes=50, seconds=600)
>>> year == another_year
True
>>> year.total_seconds()
31536000.0

Примеры арифметических операций с timedelta:

>>> import datetime as dt
>>> year = dt.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, если метка времени выходит за диапазон значений, поддерживаемых функцией C-платформы localtime(), и OSError в случае сбоя localtime(). Обычно поддерживаются только годы с 1970 по 2038. Обратите внимание, что в системах, не совместимых с POSIX, в которых метка времени учитывает високосные секунды, високосные секунды игнорируются функцией fromtimestamp().

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

classmethod date.fromordinal(ordinal)

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

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

classmethod date.fromisoformat(date_string)

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

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

Примеры:

>>> import datetime as dt
>>> dt.date.fromisoformat('2019-12-04')
datetime.date(2019, 12, 4)
>>> dt.date.fromisoformat('20191204')
datetime.date(2019, 12, 4)
>>> dt.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-календаря, заданной параметрами year, week и day. Это обратная функция к date.isocalendar().

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

classmethod date.strptime(date_string, format)

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

date(*(time.strptime(date_string, format)[0:3]))

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

Примечание

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

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

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

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

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

timedelta.days дней после date1 будет date2. (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 с теми же значениями, но с обновлёнными указанными параметрами.

Пример:

>>> import datetime as dt
>>> d = dt.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 года:

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

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

date.isoformat()

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

>>> import datetime as dt
>>> dt.date(2002, 12, 4).isoformat()
'2002-12-04'
date.__str__()

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

date.ctime()

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

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

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

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

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

date.strftime(format)

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

date.__format__(format)

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

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

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

>>> import time
>>> import datetime as dt
>>> today = dt.date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == dt.date.fromtimestamp(time.time())
True
>>> my_birthday = dt.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:

>>> import datetime as dt
>>> d = dt.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 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.15: Принимает любое действительное число в качестве timestamp, а не только целое число или число с плавающей точкой.

Устарел начиная с версии 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).

Примеры:

>>> import datetime as dt
>>> dt.datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)
>>> dt.datetime.fromisoformat('20111104')
datetime.datetime(2011, 11, 4, 0, 0)
>>> dt.datetime.fromisoformat('2011-11-04T00:05:23')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> dt.datetime.fromisoformat('2011-11-04T00:05:23Z')
datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc)
>>> dt.datetime.fromisoformat('20111104T000523')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> dt.datetime.fromisoformat('2011-W01-2T00:05:23.283')
datetime.datetime(2011, 1, 4, 0, 5, 23, 283000)
>>> dt.datetime.fromisoformat('2011-11-04 00:05:23.283')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
>>> dt.datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
>>> dt.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-календаря, заданной аргументами year, week и day. Компоненты 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() согласно format или если функция возвращает значение, не являющееся кортежем времени. См. также поведение strftime() и strptime() и datetime.fromisoformat().

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

>>> import datetime as dt
>>> date_string = "02/29"
>>> when = dt.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: Смещение перехода на летнее время больше не ограничено целым числом минут.

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 платформы для преобразования. Поскольку datetime поддерживает более широкий диапазон значений, чем функции C платформы на многих платформах, этот метод может вызвать исключение OverflowError или OSError для времени, значительно удалённого в прошлое или будущее.

Для экземпляров datetime с информацией о часовом поясе возвращаемое значение вычисляется следующим образом:

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

Примечание

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

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

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

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

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

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

Изменено в версии 3.6: Этот метод больше не использует функцию C платформы mktime() для выполнения преобразований.

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

Примеры:

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

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

>>> import datetime as dt
>>> class TZ(dt.tzinfo):
...     """A time zone with an arbitrary, constant -06:39 offset."""
...     def utcoffset(self, when):
...         return dt.timedelta(hours=-6, minutes=-39)
...
>>> dt.datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
>>> dt.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:

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

Изменено в версии 3.6: Добавлен параметр timespec.

datetime.__str__()

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

datetime.ctime()

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

>>> import datetime as dt
>>> dt.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:

>>> import datetime as dt

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

>>> # Using datetime.now()
>>> dt.datetime.now()
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043)   # GMT +1
>>> dt.datetime.now(dt.timezone.utc)
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060, tzinfo=datetime.timezone.utc)

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

>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = my_datetime.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 = my_datetime.isocalendar()
>>> for it in ic:
...     print(it)
...
2006    # ISO year
47      # ISO week
2       # ISO weekday

>>> # Formatting a datetime
>>> my_datetime.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(my_datetime, "day", "month", "time")
'The day is 21, the month is November, the time is 04:30PM.'

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

import datetime as dt

class KabulTz(dt.tzinfo):
    # Kabul used +4 until 1945, when they moved to +4:30
    UTC_MOVE_DATE = dt.datetime(1944, 12, 31, 20, tzinfo=dt.timezone.utc)

    def utcoffset(self, when):
        if when.year < 1945:
            return dt.timedelta(hours=4)
        elif (1945, 1, 1, 0, 0) <= when.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 when falls in the imaginary range, use fold to decide how
            # to resolve. See PEP 495.
            return dt.timedelta(hours=4, minutes=(30 if when.fold else 0))
        else:
            return dt.timedelta(hours=4, minutes=30)

    def fromutc(self, when):
        # Follow same validations as in datetime.tzinfo
        if not isinstance(when, dt.datetime):
            raise TypeError("fromutc() requires a datetime argument")
        if when.tzinfo is not self:
            raise ValueError("when.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 when.replace(tzinfo=dt.timezone.utc) >= self.UTC_MOVE_DATE:
            return when + dt.timedelta(hours=4, minutes=30)
        else:
            return when + dt.timedelta(hours=4)

    def dst(self, when):
        # Kabul does not observe daylight saving time.
        return dt.timedelta(0)

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

Пример использования KabulTz из предыдущего фрагмента:

>>> tz1 = KabulTz()

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

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

>>> # Convert datetime to another time zone
>>> dt3 = dt2.astimezone(dt.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. Дробные секунды могут содержать любое количество цифр (всё, что превышает 6 цифр, будет усечено).
  4. Дробные часы и минуты не поддерживаются.

Примеры:

>>> import datetime as dt
>>> dt.time.fromisoformat('04:23:01')
datetime.time(4, 23, 1)
>>> dt.time.fromisoformat('T04:23:01')
datetime.time(4, 23, 1)
>>> dt.time.fromisoformat('T042301')
datetime.time(4, 23, 1)
>>> dt.time.fromisoformat('04:23:01.000384')
datetime.time(4, 23, 1, 384)
>>> dt.time.fromisoformat('04:23:01,000384')
datetime.time(4, 23, 1, 384)
>>> dt.time.fromisoformat('04:23:01+04:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
>>> dt.time.fromisoformat('04:23:01Z')
datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)
>>> dt.time.fromisoformat('04:23:01+00:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)

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

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

classmethod time.strptime(date_string, format)

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

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

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

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

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

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

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.

Пример:

>>> import datetime as dt
>>> dt.time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes')
'12:34'
>>> my_time = dt.time(hour=12, minute=34, second=56, microsecond=0)
>>> my_time.isoformat(timespec='microseconds')
'12:34:56.000000'
>>> my_time.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:

>>> import datetime as dt
>>> class TZ1(dt.tzinfo):
...     def utcoffset(self, when):
...         return dt.timedelta(hours=1)
...     def dst(self, when):
...         return dt.timedelta(0)
...     def tzname(self, when):
...         return "+01:00"
...     def  __repr__(self):
...         return f"{self.__class__.__name__}()"
...
>>> t = dt.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__(), который можно вызвать без аргументов; в противном случае объект можно сериализовать, но, возможно, нельзя будет десериализовать. Это техническое требование, которое в будущем может быть смягчено.

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

import datetime as dt

def dst(self, when):
    # a fixed-offset class:  doesn't account for DST
    return dt.timedelta(0)

или:

import datetime as dt

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

    if dston <= when.replace(tzinfo=None) < dstoff:
        return dt.timedelta(hours=1)
    else:
        return dt.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() по умолчанию работает примерно так:

import datetime as dt

def fromutc(self, when):
    # raise ValueError error if when.tzinfo is not self
    dtoff = when.utcoffset()
    dtdst = when.dst()
    # raise ValueError if dtoff is None or dtdst is None
    delta = dtoff - dtdst  # this is self's standard offset
    if delta:
        when += delta   # convert to standard local time
        dtdst = when.dst()
        # raise ValueError if dtdst is None
    if dtdst:
        return when + dtdst
    else:
        return when

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

import datetime as dt

# 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

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

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

DSTDIFF = DSTOFFSET - STDOFFSET


class LocalTimezone(dt.tzinfo):

    def fromutc(self, when):
        assert when.tzinfo is self
        stamp = (when - 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 dt.datetime(*args, microsecond=when.microsecond,
                           tzinfo=self, fold=fold)

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

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

    def tzname(self, when):
        return time.tzname[self._isdst(when)]

    def _isdst(self, when):
        tt = (when.year, when.month, when.day,
              when.hour, when.minute, when.second,
              when.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(when):
    days_to_go = 6 - when.weekday()
    if days_to_go:
        when += dt.timedelta(days_to_go)
    return when


# 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 = dt.datetime(1, 3, 8, 2)
# and ends at 2am (DST time) on the first Sunday of Nov.
DSTEND_2007 = dt.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 = dt.datetime(1, 4, 1, 2)
DSTEND_1987_2006 = dt.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 = dt.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 (dt.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(dt.tzinfo):

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

    def __repr__(self):
        return self.reprname

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

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

    def dst(self, when):
        if when is None or when.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 when.tzinfo is self.
            return ZERO
        assert when.tzinfo is self
        start, end = us_dst_range(when.year)
        # Can't compare naive to aware objects, so strip the timezone from
        # when first.
        when = when.replace(tzinfo=None)
        if start + HOUR <= when < end - HOUR:
            # DST is in effect.
            return HOUR
        if end - HOUR <= when < end:
            # Fold (an ambiguous hour): use when.fold to disambiguate.
            return ZERO if when.fold else HOUR
        if start <= when < start + HOUR:
            # Gap (a non-existent hour): reverse the fold rule.
            return HOUR if when.fold else ZERO
        # DST is off.
        return ZERO

    def fromutc(self, when):
        assert when.tzinfo is self
        start, end = us_dst_range(when.year)
        start = start.replace(tzinfo=self)
        end = end.replace(tzinfo=self)
        std_time = when + 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 года получаем:

>>> import datetime as dt
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = dt.datetime(2016, 3, 13, 5, tzinfo=dt.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 года получаем:

>>> import datetime as dt
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = dt.datetime(2016, 11, 6, 4, tzinfo=dt.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), позволяющий создать строку, представляющую время, в соответствии с явно заданной строкой формата.

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

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

strftime

strptime

Назначение

Преобразовать объект в строку в соответствии с заданным форматом

Разобрать строку и создать объект, используя соответствующий формат

Тип метода

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

Метод класса

Сигнатура

strftime(format)

strptime(date_string, format)

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

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

>>> import datetime as dt
>>> dt.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() и date.strptime() значением по умолчанию является 1900-01-01T00:00:00.000: все компоненты, не указанные в строке формата, берутся из значения по умолчанию.

Примечание

Строки формата без разделителей могут быть неоднозначными при разборе. Например, при использовании %Y%m%d строка 2026111 может быть разобрана как 2026-11-01 или как 2026-01-11. Используйте разделители, чтобы входные данные разбирались ожидаемым образом.

Примечание

При разборе частичных дат без года методы datetime.strptime() и date.strptime() вызовут исключение при обработке 29 февраля, поскольку 1900 год по умолчанию не является високосным. Перед разбором всегда добавляйте к строкам с частичной датой високосный год по умолчанию.

>>> import datetime as dt
>>> value = "2/29"
>>> dt.datetime.strptime(value, "%m/%d")
Traceback (most recent call last):
...
ValueError: day 29 must be in range 1..28 for month 2 in year 1900
>>> dt.datetime.strptime(f"1904 {value}", "%Y %m/%d")
datetime.datetime(1904, 2, 29, 0, 0)

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

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

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

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

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

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

Примечания:

  1. Поскольку формат зависит от текущей локали, следует осторожно делать предположения о выходном значении. Порядок полей может различаться (например, «месяц/день/год» и «день/месяц/год»), а выходные данные могут содержать символы, не относящиеся к 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: Если методу strptime() передана директива %z, в смещениях относительно 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: Если методу strptime() передана директива %z, будет создан осведомлённый объект 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() всегда включайте год в формат. Если в разбираемом значении нет года, добавьте явный фиктивный високосный год. В противном случае при встрече с 29 февраля ваш код вызовет исключение, поскольку год по умолчанию, используемый анализатором (1900), не является високосным. Пользователи сталкиваются с этой ошибкой каждый високосный год.

    >>> month_day = "02/29"
    >>> dt.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]

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

[3]

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

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

Spec-Zone.ru

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