Spec-Zone.ru › Python 2.7

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

Новая версия 2.3.

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

Существует два вида объектов дат и времени: «наивные» и «осознанные».

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

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

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

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

datetime.MINYEAR

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

datetime.MAXYEAR

Наибольшее значение года, разрешенное для объекта date или datetime. MAXYEAR равно 9999.

См. также

Module calendar

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

Module time

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

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

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 для предоставления настраиваемого понятия корректировки времени (например, для учёта часового пояса и/или летнего времени).

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

Объекты типа 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
    time
    date
        datetime

2. Объекты timedelta

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

class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])

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

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

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

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

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

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

Если нормализованное значение дней лежит вне указанного диапазона, генерируется исключение 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 or t1 = i * t2

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

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

t1 = t2 // i

Вычисляется целая часть, а остаток (если есть) отбрасывается. (3)

+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(hours=-5)
    datetime.timedelta(-1, 68400)
    >>> print(_)
    -1 day, 19:00:00
    

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

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

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

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

timedelta.total_seconds()

Возвращает общее количество секунд, содержащихся в интервале времени. Эквивалентно (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 с включенным делением с плавающей точкой.

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

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

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

>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
...                          minutes=50, seconds=600)  # adds up to 365 days
>>> 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

3. Объекты date

Объект date представляет дату (год, месяц и день) в идеализированном календаре, текущем григорианском календаре, неограниченно продолженном в обоих направлениях. 1 января года 1 называется днем 1, 2 января года 1 называется днем 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(). Это может вызвать ValueError, если метка времени выходит за пределы диапазона значений, поддерживаемых платформенной функцией C localtime(). Обычно это ограничивается годами от 1970 до 2038. Обратите внимание, что на не-POSIX системах, которые включают високосные секунды в свое понятие метки времени, високосные секунды игнорируются функцией fromtimestamp().

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

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

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

date.year

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

date.month

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

date.day

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

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

Операция

Результат

date2 = date1 + timedelta

date2 смещен на timedelta.days дней относительно date1. (1)

date2 = date1 - timedelta

Вычисляет date2 так, что date2 + timedelta == date1. (2)

timedelta = date1 - date2

(3)

date1 < date2

date1 считается меньше date2, когда date1 предшествует date2 во времени. (4)

Примечания:

  1. date2 смещается вперёд во времени, если timedelta.days > 0, или назад, если timedelta.days < 0. После этого date2 - date1 == timedelta.days. timedelta.seconds и timedelta.microseconds игнорируются. OverflowError генерируется, если date2.year будет меньше MINYEAR или больше MAXYEAR.
  2. Это не совсем эквивалентно 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()

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

Календарь ISO — широко используемый вариант григорианского календаря. См. https://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, ‘ГГГГ-ММ-ДД’. Например, 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)

Возвращает строку, представляющую дату, управляемую явным строковым форматом. Коды формата, относящиеся к часам, минутам или секундам, будут видеть значения 0. Полный список директив форматирования см. в разделе 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) # 730920th day after 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.'

4. Объекты datetime

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

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

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

Аргументы 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

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

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

classmethod datetime.today()

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

END_OF_DOCUMENT_MARKER
classmethod datetime.now([tz])

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

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

classmethod datetime.utcnow()

Возвращает текущую дату и время UTC, с tzinfo None. Это аналогично now(), но возвращает текущую дату и время UTC в виде простого объекта datetime. См. также now().

classmethod datetime.fromtimestamp(timestamp[, tz])

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

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

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

classmethod datetime.utcfromtimestamp(timestamp)

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

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() или если она возвращает значение, которое не является кортежем времени. Полный список управляющих символов форматирования см. в разделе strftime() и strptime() поведение.

Введено в версии 2.5.

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

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 если он не был передан.

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

Операция

Результат

datetime2 = datetime1 + timedelta

(1)

datetime2 = datetime1 - timedelta

(2)

timedelta = datetime1 - datetime2

(3)

datetime1 < datetime2

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

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

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

    Примечание

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

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

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

datetime.date()

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

datetime.time()

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

datetime.timetz()

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

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

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

datetime.astimezone(tz)

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

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

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

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

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

def astimezone(self, tz):
    if self.tzinfo is tz:
        return self
    # Convert self to UTC, and attach the new time zone object.
    utc = (self - self.utcoffset()).replace(tzinfo=tz)
    # Convert from UTC to tz's local time.
    return tz.fromutc(utc)
datetime.utcoffset()

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

datetime.dst()

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

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(). DST никогда не применяется к времени UTC.

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

datetime.toordinal()

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

datetime.weekday()

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

datetime.isoweekday()

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

datetime.isocalendar()

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

datetime.isoformat([sep])

Возвращает строку, представляющую дату и время в формате 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
>>> # Using datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)
>>> # Using datetime.now() or 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)
>>> # Using datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)
>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = dt.timetuple()
>>> for it in tt:   
...     print it
...
2006    # year
11      # month
21      # day
16      # hour
30      # minute
0       # second
1       # weekday (0 = Monday)
325     # number of days since 1st January
-1      # dst - method tzinfo.dst() returned None
>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> for it in ic:   
...     print it
...
2006    # ISO year
47      # ISO week
2       # ISO weekday
>>> # Formatting 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):
...         # DST starts last Sunday in March
...         d = datetime(dt.year, 4, 1)   # ends last Sunday in October
...         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()
>>> # Daylight Saving Time
>>> 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)
>>> # Convert datetime to another time zone
>>> dt3 = dt2.astimezone(GMT2())
>>> dt3     # doctest: +ELLIPSIS
datetime.datetime(2006, 6, 14, 14, 0, tzinfo=<GMT2 object at 0x...>)
>>> dt2     # doctest: +ELLIPSIS
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=<GMT1 object at 0x...>)
>>> dt2.utctimetuple() == dt3.utctimetuple()
True

5. Объекты time

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

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

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

  • 0 <= hour < 24
  • 0 <= minute < 60
  • 0 <= second < 60
  • 0 <= microsecond < 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 соответственно.
  • хеширование, использование в качестве ключей словарей
  • эффективная сериализация
  • в контексте булевых значений объект 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() и strptime() Поведение.

time.__format__(format)

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

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, timedelta
>>> 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                               # doctest: +ELLIPSIS
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.'

6. Объекты tzinfo

class datetime.tzinfo

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

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

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

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

tzinfo.utcoffset(self, dt)

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

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

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

По умолчанию utcoffset() вызывает NotImplementedError.

tzinfo.dst(self, dt)

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

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

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

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

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

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

или

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

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

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

tzinfo.tzname(self, 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(self, dt)

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

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

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

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

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

from datetime import tzinfo, timedelta, datetime

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

# A UTC class.

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

    def utcoffset(self, dt):
        return ZERO

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

    def dst(self, dt):
        return ZERO

utc = UTC()

# A class building tzinfo objects for fixed-offset time zones.
# Note that FixedOffset(0, "UTC") is a different way to build a
# UTC tzinfo object.

class FixedOffset(tzinfo):
    """Fixed offset in minutes east from 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

# A class capturing the platform's idea of local time.

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


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

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


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

class USTimeZone(tzinfo):

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

    def __repr__(self):
        return self.reprname

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

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

    def dst(self, dt):
        if dt is None or dt.tzinfo is None:
            # An exception may be sensible here, in one or both cases.
            # It depends on how you want to treat them.  The default
            # fromutc() implementation (called by the default astimezone()
            # implementation) passes a datetime with dt.tzinfo is self.
            return ZERO
        assert dt.tzinfo is self

        # Find start and end times for US DST. For years before 1967, return
        # ZERO for no DST.
        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))

        # Can't compare naive to aware objects, so strip the timezone from
        # dt first.
        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

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

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

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

См. также

pytz

В стандартной библиотеке нет экземпляров tzinfo, но существует сторонняя библиотека, которая предоставляет базу данных часовых поясов IANA (также известную как базу данных Olson) в Python: pytz.

pytz содержит актуальную информацию, и ее использование рекомендуется.

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

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

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

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])), за исключением случаев, когда формат включает компоненты до секунд или информацию о смещении часового пояса, которые поддерживаются в datetime.strptime, но игнорируются в time.strptime.

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

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

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

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

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

Точный диапазон лет, для которых strftime() работает, также варьируется в зависимости от платформы. Независимо от платформы, годы до 1900 года использовать нельзя.

Директива

Значение

Пример

Примечания

%a

День недели в сокращенном названии, согласно текущему языку.

(1)

%A

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

(1)

%w

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

0, 1, …, 6

%d

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

01, 02, …, 31

%b

Месяц в сокращенном названии, согласно текущему языку.

(1)

%B

Месяц в полном названии, согласно текущему языку.

(1)

%m

Месяц как десятичное число с ведущими нулями.

01, 02, …, 12

%y

Год без столетия как десятичное число с ведущими нулями.

00, 01, …, 99

%Y

Год со столетием как десятичное число.

1970, 1988, 2001, 2013

%H

Час (24-часовой формат) как десятичное число с ведущими нулями.

00, 01, …, 23

%I

Час (12-часовой формат) как десятичное число с ведущими нулями.

01, 02, …, 12

%p

Локализованное обозначение AM или PM.

(1), (2)

%M

Минута как десятичное число с ведущими нулями.

00, 01, …, 59

%S

Секунда как десятичное число с ведущими нулями.

00, 01, …, 59

(3)

%f

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

000000, 000001, …, 999999

(4)

%z

Смещение от UTC в формате +HHMM или -HHMM (пустая строка, если объект «наивный»).

(пустая), +0000, -0400, +1030

(5)

%Z

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

(пустая), UTC, EST, CST

%j

Номер дня в году как десятичное число с ведущими нулями.

001, 002, …, 366

%U

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

00, 01, …, 53

(6)

%W

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

00, 01, …, 53

(6)

%c

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

(1)

%x

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

(1)

%X

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

(1)

%%

Буквальный символ '%'.

%

Примечания:

  1. Поскольку формат зависит от текущего языка, следует проявлять осторожность при предположениях о значении вывода. Порядок полей будет различаться (например, «месяц/день/год» против «день/месяц/год»), а вывод может содержать символы Юникода, закодированные с использованием кодировки по умолчанию языка (например, если текущий язык ja_JP, кодировка по умолчанию может быть любой из eucJP, SJIS, или utf-8; используйте locale.getlocale() для определения кодировки текущего языка).
  2. При использовании метода strptime(), директива %p влияет только на поле часа вывода, если для разбора часа используется директива %I.
  3. В отличие от модуля time, модуль datetime не поддерживает високосные секунды.
  4. %f — это расширение набора символов форматирования в стандарте C (но реализованное отдельно в объектах datetime и, следовательно, всегда доступное). При использовании метода strptime(), директива %f принимает от одного до шести цифр и добавляет нули справа.

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

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

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

    %z

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

    %Z

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

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

Примечания

1

Если, то есть, мы игнорируем эффекты относительности

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

Spec-Zone.ru

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