Содержание страницы
8.1. datetime – Основные типы даты и времени¶datetime – Basic date and time types
Модуль datetime предоставляет классы для работы с датами и временем как в простых, так и в сложных сценариях. Поддерживается арифметика дат и времени, но основное внимание в реализации уделяется эффективному извлечению отдельных компонентов для форматирования вывода и преобразований. Дополнительные возможности см. также в модулях time и calendar.
Существует два типа объектов даты и времени: «наивные» и «осведомлённые». Это различие указывает на то, учитывает ли объект часовой пояс, переход на летнее время или другие алгоритмические или политические корректировки времени. Представляет ли наивный объект datetime всемирное координированное время (UTC), местное время или время в каком-либо другом часовом поясе, зависит исключительно от программы – точно так же, как от программы зависит, обозначает ли конкретное число метры, мили или массу. Наивные объекты datetime просты для понимания и работы, но ценой игнорирования некоторых аспектов реальности.
Для приложений, которым требуется больше возможностей, объекты datetime и time содержат необязательный атрибут информации о часовом поясе tzinfo, который может содержать экземпляр подкласса абстрактного класса tzinfo. Эти объекты tzinfo содержат информацию о смещении от UTC, названии часового пояса и о том, действует ли переход на летнее время. Обратите внимание, что модуль datetime не предоставляет конкретных реализаций класса tzinfo. Поддержка часовых поясов с требуемым уровнем детализации возлагается на приложение. Правила корректировки времени по всему миру скорее политические, чем рациональные, и не существует стандарта, подходящего для всех приложений.
Модуль datetime предоставляет следующие константы:
- datetime.MAXYEAR¶
- Наибольший номер года, допустимый в объекте date или datetime. MAXYEAR равен 9999.
См. также
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 для обеспечения настраиваемой концепции корректировки времени (например, для учёта часового пояса и/или летнего времени).
Объекты этих типов неизменяемы.
Объекты типа date всегда наивны.
Объект d типа time или datetime может быть наивным или осведомлённым. d является осведомлённым, если d.tzinfo не равно None и d.tzinfo.utcoffset(d) не возвращает None. Если d.tzinfo равно None, или если d.tzinfo не равно None, но d.tzinfo.utcoffset(d) возвращает None, то d является наивным.
Различие между наивными и осведомлёнными объектами не применимо к объектам timedelta.
Отношения подклассов:
object
timedelta
tzinfo
time
date
datetime
8.1.2. Объекты timedelta¶timedelta Objects
Объект timedelta представляет продолжительность, разницу между двумя датами или моментами времени.
- class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)¶
Все аргументы необязательны и по умолчанию равны 0. Аргументы могут быть целыми числами или числами с плавающей запятой, положительными или отрицательными.
Внутри хранятся только days, seconds и microseconds. Аргументы преобразуются в эти единицы:
- Миллисекунда преобразуется в 1000 микросекунд.
- Минута преобразуется в 60 секунд.
- Час преобразуется в 3600 секунд.
- Неделя преобразуется в 7 дней.
а затем дни, секунды и микросекунды нормализуются так, что представление уникально, с
- 0 <= микросекунды < 1000000
- 0 <= секунды < 3600*24 (количество секунд в одном дне)
- -999999999 <= дни <= 999999999
Если какой-либо аргумент является числом с плавающей запятой и есть дробные микросекунды, дробные микросекунды, оставшиеся от всех аргументов, объединяются и их сумма округляется до ближайшей микросекунды. Если ни один аргумент не является числом с плавающей запятой, процессы преобразования и нормализации являются точными (информация не теряется).
Если нормализованное значение дней выходит за указанный диапазон, возбуждается исключение OverflowError.
Обратите внимание, что нормализация отрицательных значений может сначала показаться неожиданной. Например,
>>> from datetime import timedelta >>> d = timedelta(microseconds=-1) >>> (d.days, d.seconds, d.microseconds) (-1, 86399, 999999)
Атрибуты класса:
- 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 // 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) |
Примечания:
Это точное вычисление, но может произойти переполнение.
Это точное вычисление и не может вызвать переполнение.
Деление на 0 вызывает ZeroDivisionError.
timedelta.max не представим как объект timedelta.
Строковые представления объектов timedelta нормализуются аналогично их внутреннему представлению. Это приводит к несколько необычным результатам для отрицательных timedelta. Например:
>>> timedelta(hours=-5) datetime.timedelta(-1, 68400) >>> print(_) -1 day, 19:00:00
Помимо перечисленных выше операций, объекты timedelta поддерживают определённые сложения и вычитания с объектами date и datetime (см. ниже).
Сравнения объектов timedelta поддерживаются: объект timedelta с меньшей продолжительностью считается меньшим timedelta. Чтобы сравнения смешанных типов не использовали сравнение по умолчанию по адресу объекта, при сравнении объекта timedelta с объектом другого типа возбуждается TypeError, если только сравнение не является == или !=. Последние случаи возвращают соответственно False или True.
Объекты timedelta являются хэшируемыми (могут использоваться в качестве ключей словаря), поддерживают эффективную сериализацию и в логическом контексте объект timedelta считается истинным тогда и только тогда, когда он не равен timedelta(0).
Пример использования:
>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
... minutes=50, seconds=600) # составляет 365 дней
>>> 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. Объекты date¶date Objects
Объект date представляет дату (год, месяц и день) в идеализированном календаре – текущем григорианском календаре, бесконечно продолженном в обоих направлениях. 1 января 1 года называется днём номер 1, 2 января 1 года называется днём номер 2 и так далее. Это соответствует определению «пролептического григорианского» календаря в книге Дершовица и Рейнгольда «Calendrical Calculations», где он является базовым календарём для всех вычислений. За алгоритмами преобразования между пролептическими григорианскими порядковыми номерами и многими другими календарными системами обращайтесь к этой книге.
- class datetime.date(year, month, day)¶
Все аргументы обязательны. Аргументы могут быть целыми числами в следующих диапазонах:
- MINYEAR <= year <= MAXYEAR
- 1 <= month <= 12
- 1 <= day <= количество дней в указанном month и 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¶
- Наименьшая возможная разница между неравными объектами даты, timedelta(days=1).
Атрибуты экземпляра (только для чтения):
- 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) |
Примечания:
- date2 смещается вперёд во времени, если timedelta.days > 0, или назад, если timedelta.days < 0. После этого date2 - date1 == timedelta.days. timedelta.seconds и timedelta.microseconds игнорируются. OverflowError возбуждается, если date2.year окажется меньше MINYEAR или больше MAXYEAR.
- Это не совсем эквивалентно date1 + (-timedelta), поскольку -timedelta сам по себе может вызвать переполнение в случаях, когда date1 - timedelta не вызывает. timedelta.seconds и timedelta.microseconds игнорируются.
- Это точная операция и не может вызвать переполнение. timedelta.seconds и timedelta.microseconds равны 0, и после этого date2 + timedelta == date1.
- Другими словами, 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.phys.uu.nl/~vgent/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().
Пример подсчёта дней до события:
>>> 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'
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 <= секунда < 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 объекта. См. также 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() может возбуждать ValueError, если метка времени выходит за пределы диапазона значений, поддерживаемого 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 возбуждается, если date_string и format не могут быть разобраны time.strptime() или если функция возвращает значение, не являющееся временным кортежем. Смотрите раздел Поведение strftime() и strptime().
Атрибуты класса:
- datetime.max¶
- Самый поздний представимый объект datetime: datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None).
- datetime.resolution¶
- Наименьшая возможная разница между неравными объектами datetime: timedelta(microseconds=1).
Атрибуты экземпляра (только для чтения):
- 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) |
datetime2 – это datetime1, из которого вычтен timedelta. Если timedelta.days > 0, результат сдвигается вперёд во времени, а если timedelta.days < 0 – назад. Результирующий объект содержит тот же атрибут tzinfo, что и исходный datetime, при этом выполняется равенство datetime2 - datetime1 == timedelta. Если год datetime2 окажется меньше MINYEAR или больше MAXYEAR, будет возбуждено исключение OverflowError. Обратите внимание: корректировка часовых поясов не выполняется, даже если исходный объект осведомлён.
Вычисляет datetime2 таким образом, что datetime2 + timedelta == datetime1. Как и при сложении, результат содержит тот же атрибут tzinfo, что и исходный datetime; корректировка часовых поясов не выполняется, даже если исходный объект осведомлён. Данная операция не полностью эквивалентна datetime1 + (-timedelta), поскольку отдельно взятое -timedelta может вызвать переполнение в тех случаях, когда datetime1 - timedelta его не вызывает.
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.
Если оба объекта наивны (naive), либо оба осведомлены и имеют один и тот же атрибут 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()), за исключением того, что реализация никогда не вызывает переполнения.
datetime1 считается меньше datetime2, когда datetime1 предшествует datetime2 по времени.
Если один из сравниваемых объектов наивный, а другой осведомлённый, возбуждается исключение TypeError. Если оба осведомлены и имеют один и тот же атрибут tzinfo, общий атрибут tzinfo игнорируется, и сравниваются базовые даты. Если оба осведомлены и имеют разные атрибуты tzinfo, то сравниваемые объекты сначала корректируются вычитанием их UTC-смещений (полученных из self.utcoffset()).
Примечание
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.time()¶
- Return time object with same hour, minute, second and microsecond. tzinfo is None. See also method timetz().
- datetime.timetz()¶
- Возвращает объект time с теми же значениями hour, minute, second, microsecond и tzinfo. См. также метод time().
- datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])¶
- Возвращает datetime с теми же атрибутами, за исключением тех, для которых указаны новые значения в виде именованных аргументов. Обратите внимание, что можно указать tzinfo=None, чтобы создать наивный 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).
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)
- 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. Обратите внимание, что атрибут tm_year результата может быть равен MINYEAR-1 или MAXYEAR+1, если год d был 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()¶
- Возвращает кортеж из трёх элементов: (год по 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.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:
>>> 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'
Использование datetime с tzinfo:
>>> from datetime import timedelta, datetime, tzinfo
>>> class GMT1(tzinfo):
... def __init__(self): # Летнее время начинается в последнее воскресенье марта
... 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)
... def utcoffset(self, dt):
... return timedelta(hours=1) + self.dst(dt)
... def dst(self, dt):
... 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 __init__(self):
... 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)
... def utcoffset(self, dt):
... return timedelta(hours=1) + self.dst(dt)
... def dst(self, dt):
... if self.dston <= dt.replace(tzinfo=None) < self.dstoff:
... return timedelta(hours=2)
... 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 # 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
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.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 соответственно.
- хэш, использование в качестве ключа словаря
- эффективная сериализация (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() и 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
>>> 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'
8.1.6. tzinfo Объекты¶tzinfo Objects
tzinfo – это абстрактный базовый класс, то есть этот класс не следует инстанциировать напрямую. Требуется создать конкретный подкласс и (как минимум) реализовать стандартные методы tzinfo, необходимые для используемых методов datetime. Модуль datetime не содержит конкретных подклассов tzinfo.
Экземпляр (конкретного подкласса) tzinfo может передаваться конструкторам объектов datetime и time. Последние объекты рассматривают свои атрибуты как местное время, а объект tzinfo предоставляет методы, раскрывающие смещение местного времени от UTC, название часового пояса и смещение на летнее время – всё относительно переданного им объекта даты или времени.
Особое требование для сериализации (pickling): подкласс tzinfo должен иметь метод __init__(), который можно вызвать без аргументов, иначе его можно сериализовать, но, возможно, нельзя будет десериализовать. Это техническое требование, которое может быть смягчено в будущем.
Конкретному подклассу tzinfo может потребоваться реализовать следующие методы. Какие именно методы необходимы, зависит от того, как используются осведомлённые объекты datetime. В случае сомнений достаточно реализовать все.
- tzinfo.utcoffset(self, 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(self, dt)¶
Возвращает поправку на летнее время (DST) в минутах к востоку от UTC или None, если информация о DST неизвестна. Возвращает timedelta(0), если DST не действует. Если DST действует, возвращает смещение в виде объекта timedelta (подробнее см. utcoffset()). Обратите внимание, что смещение DST, если применимо, уже добавлено к смещению UTC, возвращаемому utcoffset(), поэтому нет необходимости обращаться к dst(), если только не требуется получить информацию о DST отдельно. Например, datetime.timetuple() вызывает метод dst() своего атрибута tzinfo, чтобы определить, как должен быть установлен флаг tm_isdst, а tzinfo.fromutc() вызывает dst() для учёта изменений DST при пересечении часовых поясов.
Экземпляр tz подкласса tzinfo, который моделирует как стандартное, так и летнее время, должен быть согласован в следующем смысле:
tz.utcoffset(dt) - tz.dst(dt)
должно возвращать один и тот же результат для каждого datetime dt с dt.tzinfo == tz. Для разумных подклассов tzinfo это выражение даёт «стандартное смещение» часового пояса, которое не должно зависеть от даты или времени, а только от географического положения. Реализация datetime.astimezone() полагается на это, но не может обнаружить нарушения; это обязанность программиста обеспечить это. Если подкласс tzinfo не может гарантировать это, он может переопределить реализацию по умолчанию tzinfo.fromutc(), чтобы он корректно работал с astimezone() в любом случае.
Большинство реализаций dst(), вероятно, будут выглядеть как один из этих двух вариантов:
def dst(self): # класс с фиксированным смещением: не учитывает летнее время return timedelta(0)
или
def dst(self): # Код для установки dston и dstoff в значения летнего времени часового пояса # переходные моменты времени на основе входного dt.year и выраженные # в стандартном местном времени. Затем 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): # вызывает ошибку 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() могла дать такую гарантию, метод rzinfo.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; неоднозначностей нет при использовании UTC или любого другого подкласса tzinfo с фиксированным смещением (например, класс, представляющий только EST (фиксированное смещение -5 часов) или только EDT (фиксированное смещение -4 часа)).
8.1.7. Поведение 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 подставляется вместо них.
Для наивного объекта коды форматирования %z и %Z заменяются пустыми строками.
Для осведомлённого объекта:
- %z
- utcoffset() преобразуется в строку из 5 символов вида +HHMM или -HHMM, где HH – двузначная строка, указывающая количество часов смещения UTC, а MM – двузначная строка, указывающая количество минут смещения UTC. Например, если utcoffset() возвращает timedelta(hours=-3, minutes=-30), то %z заменяется строкой '-0330'.
- %Z
- Если tzname() возвращает None, то %Z заменяется пустой строкой. В противном случае %Z заменяется возвращённым значением, которое должно быть строкой.
Полный набор поддерживаемых кодов формата зависит от платформы, поскольку Python вызывает функцию strftime() из библиотеки C данной платформы, а различия между платформами – обычное дело.
Ниже приведён список всех кодов формата, которые требуются стандартом C (версии 1989 года), и они работают на всех платформах со стандартной реализацией C. Обратите внимание, что версия 1999 года стандарта C добавила дополнительные коды формата.
Точный диапазон лет, для которых работает strftime(), также различается на разных платформах. Независимо от платформы, годы до 1900 использовать нельзя.
| Директива | Значение | Примечания |
|---|---|---|
| %a | Сокращённое название дня недели в соответствии с локалью. | |
| %A | Полное название дня недели в соответствии с локалью. | |
| %b | Сокращённое название месяца в соответствии с локалью. | |
| %B | Полное название месяца в соответствии с локалью. | |
| %c | Представление даты и времени, подходящее для локали. | |
| %d | День месяца в виде десятичного числа [01,31]. | |
| %f | Микросекунды в виде десятичного числа [0,999999], с дополнением нулями слева. | (1) |
| %H | Часы (24-часовой формат) в виде десятичного числа [00,23]. | |
| %I | Часы (12-часовой формат) в виде десятичного числа [01,12]. | |
| %j | День года в виде десятичного числа [001,366]. | |
| %m | Месяц в виде десятичного числа [01,12]. | |
| %M | Минуты в виде десятичного числа [00,59]. | |
| %p | Эквивалент AM или PM, зависящий от локали. | (2) |
| %S | Секунды в виде десятичного числа [00,61]. | (3) |
| %U | Номер недели в году (воскресенье – первый день недели) в виде десятичного числа [00,53]. Все дни нового года до первого воскресенья считаются частью недели 0. | (4) |
| %w | День недели в виде десятичного числа [0 (воскресенье), 6]. | |
| %W | Номер недели в году (понедельник – первый день недели) в виде десятичного числа [00,53]. Все дни нового года до первого понедельника считаются частью недели 0. | (4) |
| %x | Представление даты, соответствующее локали. | |
| %X | Представление времени, соответствующее локали. | |
| %y | Год без века в виде десятичного числа [00,99]. | |
| %Y | Год со столетием в виде десятичного числа. | |
| %z | Смещение UTC в формате +HHMM или -HHMM (пустая строка, если объект наивный). | (5) |
| %Z | Название часового пояса (пустая строка, если объект наивный). | |
| %% | Литеральный символ '%'. |
Примечания:
- При использовании с методом strptime() директива %f принимает от одной до шести цифр и дополняет нулями справа. %f является расширением набора символов форматирования в стандарте C (но реализовано отдельно в объектах datetime, и поэтому всегда доступно).
- При использовании с методом strptime() директива %p влияет на поле часа на выходе только если директива %I используется для разбора часа.
- Диапазон действительно равен от 0 до 61; согласно стандарту Posix, это учитывает високосные секунды и (очень редкие) двойные високосные секунды. Модуль time может генерировать и принимает високосные секунды, поскольку он основан на стандарте Posix, но модуль datetime не принимает високосные секунды во входных данных strptime() и не будет генерировать их в выводе strftime().
- При использовании с методом strptime() директивы %U и %W используются только в вычислениях, когда указаны день недели и год.
- Например, если utcoffset() возвращает timedelta(hours=-3, minutes=-30), то %z заменяется строкой '-0330'.