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

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

Модуль datetime предоставляет классы для работы с датами и временем как в простых, так и в сложных сценариях. Поддерживается арифметика дат и времени, но основное внимание в реализации уделяется эффективному извлечению атрибутов для форматирования вывода и манипуляции. За дополнительными возможностями обращайтесь к модулям time и calendar.

Существует два вида объектов даты и времени: «наивные» (naive) и «осведомлённые» (aware).

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

См. также

Модуль calendar
Общие функции, связанные с календарём.
Модуль time
Доступ к времени и преобразования.

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

class datetime.date

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

class datetime.time

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

class datetime.datetime

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

class datetime.timedelta

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

class datetime.tzinfo

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

class datetime.timezone

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

Новое в версии 3.2.

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

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

Объект типа time или datetime может быть наивным или осведомлённым. Объект datetime d является осведомлённым, если d.tzinfo не равно None и d.tzinfo.utcoffset(d) не возвращает None. Если d.tzinfo равно None, или если d.tzinfo не равно None, но d.tzinfo.utcoffset(d) возвращает None, то d является наивным. Объект time t является осведомлённым, если t.tzinfo не равно None и t.tzinfo.utcoffset(None) не возвращает None. В противном случае t является наивным.

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

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

object
    timedelta
    tzinfo
        timezone
    time
    date
        datetime

8.1.2. Объекты timedeltatimedelta Objects

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

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

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

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

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

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

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

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

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

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

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

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

timedelta.min

Наиболее отрицательный объект timedelta, timedelta(-999999999).

timedelta.max

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

timedelta.resolution

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

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

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

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

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

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

Примечания:

  1. Это точное вычисление, но может произойти переполнение.

  2. Это точное вычисление и не может вызвать переполнение.

  3. Деление на 0 вызывает ZeroDivisionError.

  4. timedelta.max не представим как объект timedelta.

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

    >>> timedelta(hours=-5)
    datetime.timedelta(-1, 68400)
    >>> print(_)
    -1 day, 19:00:00
    

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

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

Сравнения объектов timedelta поддерживаются: объект timedelta с меньшей продолжительностью считается меньшим timedelta. Чтобы сравнения смешанных типов не использовали сравнение по умолчанию по адресу объекта, при сравнении объекта timedelta с объектом другого типа возбуждается TypeError, если только сравнение не является == или !=. Последние случаи возвращают соответственно False или True.

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

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

timedelta.total_seconds()

Возвращает общее количество секунд, содержащихся в интервале. Эквивалентно td / timedelta(seconds=1).

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

Новое в версии 3.2.

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

>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
...                          minutes=50, seconds=600)  # составляет 365 дней
>>> year.total_seconds()
31536000.0
>>> year == another_year
True
>>> ten_years = 10 * year
>>> ten_years, ten_years.days // 365
(datetime.timedelta(3650), 10)
>>> nine_years = ten_years - year
>>> nine_years, nine_years.days // 365
(datetime.timedelta(3285), 9)
>>> three_years = nine_years // 3;
>>> three_years, three_years.days // 365
(datetime.timedelta(1095), 3)
>>> abs(three_years - ten_years) == 2 * three_years + year
True

8.1.3. Объекты datedate Objects

Объект date представляет дату (год, месяц и день) в идеализированном календаре – текущем григорианском календаре, бесконечно продолженном в обоих направлениях. 1 января 1 года называется днём номер 1, 2 января 1 года называется днём номер 2 и так далее. Это соответствует определению «пролептического григорианского» календаря в книге Дершовица и Рейнгольда «Calendrical Calculations», где он является базовым календарём для всех вычислений. За алгоритмами преобразования между пролептическими григорианскими порядковыми номерами и многими другими календарными системами обращайтесь к этой книге.

class datetime.date(year, month, day)

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

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

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

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

classmethod date.today()

Возвращает текущую локальную дату. Это эквивалентно date.fromtimestamp(time.time()).

classmethod date.fromtimestamp(timestamp)

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

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

classmethod date.fromordinal(ordinal)

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

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

date.min

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

date.max

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

date.resolution

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

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

date.year

От MINYEAR до MAXYEAR включительно.

date.month

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

date.day

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

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

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

Примечания:

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

Даты могут использоваться в качестве ключей словаря. В логическом контексте все объекты date считаются истинными.

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

date.replace(year, month, day)

Возвращает дату с тем же значением, за исключением параметров, которым заданы новые значения с помощью указанных именованных аргументов. Например, если d == date(2002, 12, 31), то d.replace(day=26) == date(2002, 12, 26).

date.timetuple()

Возвращает time.struct_time, такой как возвращается time.localtime(). Часы, минуты и секунды равны 0, а флаг DST равен -1. d.timetuple() эквивалентно time.struct_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1)), где yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1 – номер дня в текущем году, начиная с 1 для 1 января.

date.toordinal()

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

date.weekday()

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

date.isoweekday()

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

date.isocalendar()

Возвращает кортеж из трёх элементов: (год по ISO, номер недели по ISO, день недели по ISO).

ISO-календарь – это широко используемый вариант григорианского календаря. См. http://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm для подробного объяснения.

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

Например, 2004 год начинается в четверг, поэтому первая неделя ISO-года 2004 начинается в понедельник, 29 декабря 2003 г., и заканчивается в воскресенье, 4 января 2004 г., так что date(2003, 12, 29).isocalendar() == (2004, 1, 1) и date(2004, 1, 4).isocalendar() == (2004, 1, 7).

date.isoformat()

Возвращает строку, представляющую дату в формате ISO 8601, ‘YYYY-MM-DD’. Например, date(2002, 12, 4).isoformat() == '2002-12-04'.

date.__str__()

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

date.ctime()

Возвращает строку, представляющую дату, например date(2002, 12, 4).ctime() == 'Wed Dec 4 00:00:00 2002'. d.ctime() эквивалентно time.ctime(time.mktime(d.timetuple())) на платформах, где встроенная функция C ctime() (которую вызывает time.ctime(), но которую date.ctime() не вызывает) соответствует стандарту C.

date.strftime(format)

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

date.__format__(format)

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

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

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

Пример работы с date:

>>> from datetime import date
>>> d = date.fromordinal(730920) # 730920-й день после 1.1.0001
>>> d
datetime.date(2002, 3, 11)
>>> 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 )
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
'The day is 11, the month is March.'

8.1.4. datetime Объектыdatetime Objects

Объект datetime – это единый объект, содержащий всю информацию из объекта date и объекта time. Как и объект date, datetime предполагает использование текущего григорианского календаря, расширенного в обоих направлениях; как и объект time, datetime предполагает, что в каждом дне ровно 3600*24 секунд.

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

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

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

  • MINYEAR <= year <= MAXYEAR
  • 1 <= month <= 12
  • 1 <= day <= количество дней в указанном month и year
  • 0 <= hour < 24
  • 0 <= minute < 60
  • 0 <= second < 60
  • 0 <= microsecond < 1000000

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

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

classmethod datetime.today()

Возвращает текущее локальное datetime с tzinfo, равным None. Это эквивалентно datetime.fromtimestamp(time.time()). См. также now(), fromtimestamp().

classmethod datetime.now(tz=None)

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

В противном случае tz должен быть экземпляром подкласса класса tzinfo, и текущие дата и время преобразуются в часовой пояс tz. В этом случае результат эквивалентен tz.fromutc(datetime.utcnow().replace(tzinfo=tz)). См. также today(), utcnow().

classmethod datetime.utcnow()

Возвращает текущие UTC дату и время с tzinfo, равным None. Это похоже на now(), но возвращает текущие UTC дату и время в виде наивного объекта datetime. Осведомленный (aware) текущий UTC datetime можно получить, вызвав datetime.now(timezone.utc). См. также now().

classmethod datetime.fromtimestamp(timestamp, tz=None)

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

В противном случае tz должен быть экземпляром подкласса класса tzinfo, и временная метка преобразуется в часовой пояс tz. В этом случае результат эквивалентен tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz)).

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

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

classmethod datetime.utcfromtimestamp(timestamp)

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

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

datetime(1970, 1, 1) + timedelta(seconds=timestamp)

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

classmethod datetime.fromordinal(ordinal)

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

classmethod datetime.combine(date, time)

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

classmethod datetime.strptime(date_string, format)

Возвращает объект datetime, соответствующий строке date_string, разобранной в соответствии с форматом format. Эквивалентно datetime(*(time.strptime(date_string, format)[0:6])). ValueError возбуждается, если time.strptime() не может разобрать date_string и format или возвращает значение, не являющееся временным кортежем. Полный список директив форматирования см. в strftime() и strptime() – поведение.

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

datetime.min

Самый ранний представимый объект datetime: datetime(MINYEAR, 1, 1, tzinfo=None).

datetime.max

Самый поздний представимый объект datetime: datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None).

datetime.resolution

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

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

datetime.year

Between MINYEAR and MAXYEAR inclusive.

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, если ничего не передано.

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

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

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

  3. Subtraction of a datetime from a datetime is defined only if both operands are naive, or if both are aware. If one is aware and the other is naive, TypeError is raised.

    If both are naive, or both are aware and have the same tzinfo attribute, the tzinfo attributes are ignored, and the result is a timedelta object t such that datetime2 + t == datetime1. No time zone adjustments are done in this case.

    If both are aware and have different tzinfo attributes, a-b acts as if a and b were first converted to naive UTC datetimes first. The result is (a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset()) except that the implementation never overflows.

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

    If one comparand is naive and the other is aware, TypeError is raised if an order comparison is attempted. For equality comparisons, naive instances are never equal to aware instances.

    If both comparands are aware, and have the same tzinfo attribute, the common tzinfo attribute is ignored and the base datetimes are compared. If both comparands are aware and have different tzinfo attributes, the comparands are first adjusted by subtracting their UTC offsets (obtained from self.utcoffset()).

    Changed in version 3.3: Equality comparisons between naive and aware datetime instances don’t raise TypeError.

    Примечание

    In order to stop comparison from falling back to the default scheme of comparing object addresses, datetime comparison normally raises TypeError if the other comparand isn’t also a datetime object. However, NotImplemented is returned instead if the other comparand has a timetuple() attribute. This hook gives other kinds of date objects a chance at implementing mixed-type comparison. If not, when a datetime object is compared to an object of a different type, TypeError is raised unless the comparison is == or !=. The latter cases return False or True, respectively.

datetime objects can be used as dictionary keys. In Boolean contexts, all datetime objects are considered to be true.

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

datetime.date()

Return date object with same year, month and day.

datetime.time()

Return time object with same hour, minute, second and microsecond. tzinfo is None. See also method timetz().

datetime.timetz()

Return time object with same hour, minute, second, microsecond, and tzinfo attributes. See also method time().

datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])

Return a datetime with the same attributes, except for those attributes given new values by whichever keyword arguments are specified. Note that tzinfo=None can be specified to create a naive datetime from an aware datetime with no conversion of date and time data.

datetime.astimezone(tz=None)

Return a datetime object with new tzinfo attribute tz, adjusting the date and time data so the result is the same UTC time as self, but in tz‘s local time.

If provided, tz must be an instance of a tzinfo subclass, and its utcoffset() and dst() methods must not return None. self must be aware (self.tzinfo must not be None, and self.utcoffset() must not return None).

If called without arguments (or with tz=None) the system local timezone is assumed. The tzinfo attribute of the converted datetime instance will be set to an instance of timezone with the zone name and offset obtained from the OS.

If self.tzinfo is tz, self.astimezone(tz) is equal to self: no adjustment of date or time data is performed. Else the result is local time in time zone tz, representing the same UTC time as self: after astz = dt.astimezone(tz), astz - astz.utcoffset() will usually have the same date and time data as dt - dt.utcoffset(). The discussion of class tzinfo explains the cases at Daylight Saving Time transition boundaries where this cannot be achieved (an issue only if tz models both standard and daylight time).

If you merely want to attach a time zone object tz to a datetime dt without adjustment of date and time data, use dt.replace(tzinfo=tz). If you merely want to remove the time zone object from an aware datetime dt without conversion of date and time data, use dt.replace(tzinfo=None).

Note that the default tzinfo.fromutc() method can be overridden in a tzinfo subclass to affect the result returned by astimezone(). Ignoring error cases, astimezone() acts like:

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

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

datetime.utcoffset()

If tzinfo is None, returns None, else returns self.tzinfo.utcoffset(self), and raises an exception if the latter doesn’t return None, or a timedelta object representing a whole number of minutes with magnitude less than one day.

datetime.dst()

If tzinfo is None, returns None, else returns self.tzinfo.dst(self), and raises an exception if the latter doesn’t return None, or a timedelta object representing a whole number of minutes with magnitude less than one day.

datetime.tzname()

If tzinfo is None, returns None, else returns self.tzinfo.tzname(self), raises an exception if the latter doesn’t return None or a string object,

datetime.timetuple()

Return a time.struct_time such as returned by time.localtime(). d.timetuple() is equivalent to time.struct_time((d.year, d.month, d.day, d.hour, d.minute, d.second, d.weekday(), yday, dst)), where yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1 is the day number within the current year starting with 1 for January 1st. The tm_isdst flag of the result is set according to the dst() method: tzinfo is None or dst() returns None, tm_isdst is set to -1; else if dst() returns a non-zero value, tm_isdst is set to 1; else tm_isdst is set to 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.toordinal()

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

datetime.timestamp()

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

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

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

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

Новое в версии 3.3.

Примечание

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

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

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

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

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

datetime.isoweekday()

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

datetime.isocalendar()

Возвращает кортеж из трёх элементов: (год по ISO, номер недели по ISO, день недели по ISO). Эквивалентно self.date().isocalendar().

datetime.isoformat(sep='T')

Возвращает строку, представляющую дату и время в формате ISO 8601, YYYY-MM-DDTHH:MM:SS.mmmmmm или, если microsecond равен 0, YYYY-MM-DDTHH:MM:SS

Если utcoffset() возвращает не None, добавляется строка из 6 символов, указывающая смещение UTC в часах и минутах со знаком: YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM или, если microsecond равен 0 YYYY-MM-DDTHH:MM:SS+HH:MM

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

>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
...     def utcoffset(self, dt): return timedelta(minutes=-399)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
datetime.__str__()

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

datetime.ctime()

Возвращает строку, представляющую дату и время, например datetime(2002, 12, 4, 20, 30, 40).ctime() == 'Wed Dec  4 20:30:40 2002'. d.ctime() эквивалентно time.ctime(time.mktime(d.timetuple())) на платформах, где родная C-функция ctime() (которую вызывает time.ctime(), но которую datetime.ctime() не вызывает) соответствует стандарту C.

datetime.strftime(format)

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

datetime.__format__(format)

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

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

>>> from datetime import datetime, date, time
>>> # Использование datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)
>>> # Использование datetime.now() или datetime.utcnow()
>>> datetime.now()   
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043)   # GMT +1
>>> datetime.utcnow()   
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060)
>>> # Использование datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)
>>> # Использование datetime.timetuple() для получения кортежа всех атрибутов
>>> tt = dt.timetuple()
>>> for it in tt:   
...     print(it)
...
2006    # year
11      # month
21      # day
16      # hour
30      # minute
0       # second
1       # weekday (0 = Monday)
325     # number of days since 1st January
-1      # dst - method tzinfo.dst() returned None
>>> # Дата в формате ISO
>>> ic = dt.isocalendar()
>>> for it in ic:   
...     print(it)
...
2006    # ISO year
47      # ISO week
2       # ISO weekday
>>> # Форматирование datetime
>>> dt.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(dt, "day", "month", "time")
'The day is 21, the month is November, the time is 04:30PM.'

Использование datetime с tzinfo:

>>> from datetime import timedelta, datetime, tzinfo
>>> class GMT1(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=1) + self.dst(dt)
...     def dst(self, dt):
...         # Летнее время начинается в последнее воскресенье марта
...         d = datetime(dt.year, 4, 1)   # Заканчивается в последнее воскресенье октября
...         self.dston = d - timedelta(days=d.weekday() + 1)
...         d = datetime(dt.year, 11, 1)
...         self.dstoff = d - timedelta(days=d.weekday() + 1)
...         if self.dston <=  dt.replace(tzinfo=None) < self.dstoff:
...             return timedelta(hours=1)
...         else:
...             return timedelta(0)
...     def tzname(self,dt):
...          return "GMT +1"
...
>>> class GMT2(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=2) + self.dst(dt)
...     def dst(self, dt):
...         d = datetime(dt.year, 4, 1)
...         self.dston = d - timedelta(days=d.weekday() + 1)
...         d = datetime(dt.year, 11, 1)
...         self.dstoff = d - timedelta(days=d.weekday() + 1)
...         if self.dston <=  dt.replace(tzinfo=None) < self.dstoff:
...             return timedelta(hours=1)
...         else:
...             return timedelta(0)
...     def tzname(self,dt):
...         return "GMT +2"
...
>>> gmt1 = GMT1()
>>> # Летнее время
>>> dt1 = datetime(2006, 11, 21, 16, 30, tzinfo=gmt1)
>>> dt1.dst()
datetime.timedelta(0)
>>> dt1.utcoffset()
datetime.timedelta(0, 3600)
>>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=gmt1)
>>> dt2.dst()
datetime.timedelta(0, 3600)
>>> dt2.utcoffset()
datetime.timedelta(0, 7200)
>>> # Преобразовать datetime в другой часовой пояс
>>> dt3 = dt2.astimezone(GMT2())
>>> dt3     
datetime.datetime(2006, 6, 14, 14, 0, tzinfo=<GMT2 object at 0x...>)
>>> dt2     
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=<GMT1 object at 0x...>)
>>> dt2.utctimetuple() == dt3.utctimetuple()
True

8.1.5. time Объектыtime Objects

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

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

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

  • 0 <= hour < 24
  • 0 <= minute < 60
  • 0 <= секунда < 60
  • 0 <= микросекунда < 1000000.

Если указан аргумент вне этих диапазонов, возбуждается 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 с time, где a считается меньшим, чем b, если a предшествует b во времени. Если один операнд является наивным, а другой – осведомлённым, при попытке упорядочивающего сравнения возбуждается TypeError. При сравнении на равенство наивные экземпляры никогда не равны осведомлённым.

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

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

  • хэш, использование в качестве ключа словаря

  • эффективная сериализация (pickling)

  • в логических контекстах объект time считается истинным тогда и только тогда, когда после преобразования в минуты и вычитания utcoffset() (или 0, если он равен None) результат не равен нулю.

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

time.replace([hour[, minute[, second[, microsecond[, tzinfo]]]]])

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

time.isoformat()

Возвращает строку, представляющую время в формате ISO 8601: HH:MM:SS.mmmmmm или, если self.microsecond равно 0, HH:MM:SS. Если utcoffset() не возвращает None, добавляется 6-символьная строка, указывающая смещение UTC в (знаковых) часах и минутах: HH:MM:SS.mmmmmm+HH:MM или, если self.microsecond равно 0, HH:MM:SS+HH:MM.

time.__str__()

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

time.strftime(format)

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

time.__format__(format)

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

time.utcoffset()

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

time.dst()

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

time.tzname()

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

Пример:

>>> from datetime import time, tzinfo
>>> class GMT1(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=1)
...     def dst(self, dt):
...         return timedelta(0)
...     def tzname(self,dt):
...         return "Europe/Prague"
...
>>> t = time(12, 10, 30, tzinfo=GMT1())
>>> t                               
datetime.time(12, 10, 30, tzinfo=<GMT1 object at 0x...>)
>>> gmt = GMT1()
>>> t.isoformat()
'12:10:30+01:00'
>>> t.dst()
datetime.timedelta(0)
>>> t.tzname()
'Europe/Prague'
>>> t.strftime("%H:%M:%S %Z")
'12:10:30 Europe/Prague'
>>> 'The {} is {:%H:%M}.'.format("time", t)
'The time is 12:10.'

8.1.6. tzinfo Объектыtzinfo Objects

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

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

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

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

tzinfo.utcoffset(dt)

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

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

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

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

tzinfo.dst(dt)

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

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

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

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

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

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

или

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

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

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

tzinfo.tzname(dt)

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

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

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

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

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

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

tzinfo.fromutc(dt)

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

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

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

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

Примеры классов tzinfo:

from datetime import tzinfo, timedelta, datetime

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

# Класс UTC.

class UTC(tzinfo):
    """UTC"""

    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

# Класс, создающий объекты tzinfo для часовых поясов с фиксированным смещением.
# Обратите внимание, что FixedOffset(0, "UTC") – это другой способ построения
# Объект tzinfo UTC.

class FixedOffset(tzinfo):
    """Фиксированное смещение в минутах к востоку от UTC."""

    def __init__(self, offset, name):
        self.__offset = timedelta(minutes=offset)
        self.__name = name

    def utcoffset(self, dt):
        return self.__offset

    def tzname(self, dt):
        return self.__name

    def dst(self, dt):
        return ZERO

# Класс, отражающий представление платформы о местном времени.

import time as _time

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

DSTDIFF = DSTOFFSET - STDOFFSET

class LocalTimezone(tzinfo):

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

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

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

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

Local = LocalTimezone()


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

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


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

class USTimeZone(tzinfo):

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

    def __repr__(self):
        return self.reprname

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

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

    def dst(self, dt):
        if dt is None or dt.tzinfo is None:
            # В одном или обоих случаях здесь может быть уместно исключение.
            # Это зависит от того, как вы хотите их обрабатывать. Реализация по умолчанию
            # fromutc() (вызываемая реализацией astimezone() по умолчанию)
            # реализация) передаёт datetime с dt.tzinfo равным self.
            return ZERO
        assert dt.tzinfo is self

        # Найти время начала и окончания перехода на летнее время в США. Для лет до 1967 года вернуть
        # ZERO – если переход на летнее время не применяется.
        if 2006 < dt.year:
            dststart, dstend = DSTSTART_2007, DSTEND_2007
        elif 1986 < dt.year < 2007:
            dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
        elif 1966 < dt.year < 1987:
            dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
        else:
            return ZERO

        start = first_sunday_on_or_after(dststart.replace(year=dt.year))
        end = first_sunday_on_or_after(dstend.replace(year=dt.year))

        # Нельзя сравнивать наивные и осведомлённые объекты, поэтому сначала удалите часовой пояс из
        # сначала dt.
        if start <= dt.replace(tzinfo=None) < end:
            return HOUR
        else:
            return ZERO

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

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

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

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

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

Когда начинается летнее время (строка «start»), местные настенные часы перескакивают с 1:59 на 3:00. Местное время вида 2:MM в этот день не имеет смысла, поэтому astimezone(Eastern) не вернёт результат с hour == 2 в день начала DST. Чтобы astimezone() могла дать такую гарантию, метод tzinfo.dst() должен считать время в «потерянном часе» (2:MM для Eastern) летним.

Когда летнее время заканчивается (строка «end»), возникает потенциально более серьёзная проблема: есть час, который невозможно однозначно записать в местном настенном времени – последний час летнего времени. Для Eastern это моменты вида 5:MM UTC в день окончания летнего времени. Местные настенные часы перескакивают с 1:59 (летнее время) обратно на 1:00 (стандартное). Местное время вида 1:MM становится неоднозначным. astimezone() имитирует поведение местных часов, сопоставляя два соседних часа UTC одному и тому же местному часу. В примере с Eastern моменты UTC вида 5:MM и 6:MM при преобразовании в Eastern оба дают 1:MM. Чтобы astimezone() могла дать такую гарантию, метод tzinfo.dst() должен считать время в «повторяющемся часе» стандартным. Этого легко добиться, как в примере, выражая моменты перехода DST в стандартном местном времени часового пояса.

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

См. также

pytz

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

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

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

8.1.7. Объекты timezonetimezone Objects

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

class datetime.timezone(offset[, name])

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

Аргумент name необязателен. Если он указан, то должен быть строкой, которая используется как значение, возвращаемое методом tzname(dt). В противном случае tzname(dt) возвращает строку 'UTC±HH:MM', где s – знак offset, HH и MM – две цифры offset.hours и offset.minutes соответственно.

Новое в версии 3.2.

timezone.utcoffset(dt)

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

timezone.tzname(dt)

Возвращает фиксированное значение, указанное при создании экземпляра timezone, или строку 'UTC±HH:MM', где s – знак offset, HH и MM – две цифры offset.hours и offset.minutes соответственно.

timezone.dst(dt)

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

timezone.fromutc(dt)

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

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

timezone.utc

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

8.1.8. Поведение strftime() и strptime()strftime() and strptime() Behavior

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

И наоборот, метод класса datetime.strptime() создаёт объект datetime из строки, представляющей дату и время, и соответствующей строки формата. datetime.strptime(date_string, format) эквивалентно datetime(*(time.strptime(date_string, format)[0:6])).

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

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

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

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

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

Примечания:

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

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

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

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

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

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

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

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

    Для осведомлённого объекта:

    %z

    utcoffset() преобразуется в строку из 5 символов вида +HHMM или -HHMM, где HH – двухсимвольная строка, представляющая количество часов смещения UTC, а MM – двухсимвольная строка, представляющая количество минут смещения UTC. Например, если utcoffset() возвращает timedelta(hours=-3, minutes=-30), то %z заменяется строкой '-0330'.

    %Z

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

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

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

Сноски

[1]Если, конечно, не учитывать эффекты теории относительности