Руководство для начинающих по модулю времени time Python
Оглавление
- Работа со временем в Python с помощью секунд
- Понимание часовых поясов
- Работа со временем в Python с помощью структур данных
- Преобразование времени Python в секундах в объект
- Преобразование объекта локального времени в секунды
- Преобразование объекта времени Python в строку
- Преобразование строки времени в Python в объект
- Приостановка выполнения
- Измерение производительности
- Заключение
- Дальнейшее чтение
Модуль Python time
предоставляет множество способов представления времени в коде, таких как объекты, числа и строки. Он также обеспечивает функциональность, отличную от представления времени, например, ожидание во время выполнения кода и измерение эффективности вашего кода.
В этой статье мы рассмотрим наиболее часто используемые функции и объекты в time
.
К концу этой статьи вы сможете:
- Понимайте основные понятия, лежащие в основе работы с датами и временем, такие как эпохи, часовые пояса и летнее время
- Представлять время в коде с помощью плавающих элементов, кортежей и
struct_time
- Преобразование между различными представлениями времени
- Приостановить выполнение потока
- Измерьте производительность кода с помощью
perf_counter()
Вы начнете с изучения того, как можно использовать число с плавающей точкой для представления времени.
Работа со временем в Python с помощью секунд
Одним из способов управления концепцией времени Python в вашем приложении является использование числа с плавающей точкой, которое представляет собой количество секунд, прошедших с начала эпохи - то есть с определенной начальной точки.
Давайте подробнее разберемся, что это значит, почему это полезно и как вы можете использовать это для реализации логики, основанной на времени Python, в вашем приложении.
Эпоха
В предыдущем разделе вы узнали, что в Python можно управлять временем с помощью числа с плавающей точкой, представляющего прошедшее время с начала эры.
Мерриам-Вебстер определяет эпоху как:
- Фиксированная точка времени, от которой отсчитывается ряд лет
- Система хронологических обозначений, рассчитываемая на основе данной даты
Важная концепция, которую необходимо усвоить, заключается в том, что, имея дело со временем Python, вы рассматриваете период времени, определяемый начальной точкой. В вычислительной технике эту начальную точку называют эпохой.
Эпоха, таким образом, является отправной точкой, по которой можно измерять ход времени.
Например, если вы определите эпоху как полночь 1 января 1970 года UTC - эпоху, определенную в Windows и большинстве UNIX-систем, - то вы можете представить полночь 2 января 1970 года UTC как 86400
секунд с момента эпохи.
Это связано с тем, что в минуте 60 секунд, в часе 60 минут, а в сутках 24 часа. 2 января 1970 года по Гринвичу - это всего лишь один день после эпохи, поэтому вы можете применить элементарную математику, чтобы получить такой результат:
>>> 60 * 60 * 24
86400
Также важно отметить, что вы все еще можете представлять время до эпохи. Просто количество секунд будет отрицательным.
Например, вы представите полночь 31 декабря 1969 года по UTC (используя эпоху 1 января 1970 года) как -86400
секунд.
Хотя 1 января 1970 года по Гринвичу является общепринятой эпохой, это не единственная эпоха, используемая в вычислениях. На самом деле, различные операционные системы, файловые системы и API иногда используют разные эпохи.
Как вы уже видели, системы UNIX определяют эпоху как 1 января 1970 года. Win32 API, с другой стороны, определяет эпоху как 1 января 1601 года.
Вы можете использовать time.gmtime()
для определения эпохи вашей системы:
>>> import time
>>> time.gmtime(0)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
Вы узнаете о gmtime()
и struct_time
в ходе этой статьи. Пока же просто знайте, что вы можете использовать time
для определения эпохи с помощью этой функции.
Теперь, когда вы поняли, как измерять время в секундах с помощью эпохи, давайте посмотрим на модуль Python time
, чтобы увидеть, какие функции он предлагает, чтобы помочь вам сделать это.
Python Время в секундах как число с плавающей точкой
First, time.time()
возвращает количество секунд, прошедших с момента эпохи. Возвращаемое значение представляет собой число с плавающей точкой для учета дробных секунд:
>>> from time import time
>>> time()
1551143536.9323719
Число, которое вы получите на своей машине, может быть совсем другим, потому что точка отсчета, считающаяся эпохой, может быть совсем другой.
Далее: В Python 3.7 появилась функция time_ns()
, которая возвращает целочисленное значение, представляющее то же прошедшее время с эпохи, но в наносекундах, а не в секундах.
Измерение времени в секундах полезно по нескольким причинам:
- Вы можете использовать float для вычисления разницы между двумя точками во времени.
- float легко сериализуется, что означает, что его можно хранить для передачи данных и выходить целым и невредимым с другой стороны.
Иногда, однако, вы можете захотеть увидеть текущее время, представленное в виде строки. Для этого вы можете передать в time.ctime()
число секунд, полученное из time()
.
Python Время в секундах как строка, представляющая местное время
Как вы уже видели, вы можете захотеть преобразовать время Python, представленное как количество прошедших секунд с момента эпохи, в строку. Вы можете сделать это, используя ctime()
:
>>> from time import time, ctime
>>> t = time()
>>> ctime(t)
'Mon Feb 25 19:11:59 2019'
Здесь вы записали текущее время в секундах в переменную t
, затем передали t
в качестве аргумента в ctime()
, которая возвращает строковое представление этого же времени.
Технические подробности: Аргумент, представляющий секунды с момента эпохи, является необязательным в соответствии с определением ctime()
. Если вы не передаете аргумент, то ctime()
по умолчанию использует возвращаемое значение time()
. Таким образом, вы можете упростить приведенный выше пример:
>>> from time import ctime
>>> ctime()
'Mon Feb 25 19:11:59 2019'
Строковое представление времени, также известное как timestamp, возвращаемое ctime()
, имеет следующую структуру:
- День недели:
Mon
(Monday
) - Месяц года:
Feb
(February
) - День месяца:
25
- Часы, минуты и секунды с использованием 24-часовой нотации:
19:11:59
- Год:
2019
В предыдущем примере показана временная метка конкретного момента, снятая с компьютера, расположенного в Южно-Центральном регионе США. Но, допустим, вы живете в Сиднее, Австралия, и выполнили ту же команду в тот же момент.
Вместо приведенного выше вывода вы увидите следующее:
>>> from time import time, ctime
>>> t = time()
>>> ctime(t)
'Tue Feb 26 12:11:59 2019'
Обратите внимание, что части временной метки day of week
, day of month
и hour
отличаются от первого примера.
Эти результаты отличаются, потому что временная метка, возвращаемая ctime()
, зависит от вашего географического положения.
Примечание: Хотя понятие часовых поясов относится к вашему физическому местоположению, вы можете изменить его в настройках компьютера, не переезжая в другое место.
Представление времени, зависящее от вашего физического местоположения, называется местным временем и использует понятие временных зон.
Примечание: Поскольку местное время зависит от вашей локали, временные метки часто учитывают специфические для локали детали, такие как порядок элементов в строке и перевод сокращений дня и месяца. ctime()
игнорирует эти детали.
Давайте немного углубимся в понятие часовых поясов, чтобы вы могли лучше понять представления времени в Python.
Понимание часовых поясов
Часовой пояс - это регион мира, который подчиняется стандартному времени. Часовые пояса определяются их смещением от координированного универсального времени (UTC) и, возможно, включением летнего времени (о чем мы расскажем подробнее далее в этой статье).
Забавный факт: Если вы носитель английского языка, вам, возможно, интересно, почему сокращение "Всемирное координированное время" - UTC, а не более очевидное CUT. Однако если вы носитель французского языка, вы бы назвали его "Temps Universel Coordonné", что предполагает другую аббревиатуру: TUC.
В конце концов, Международный союз электросвязи и Международный астрономический союз пришли к компромиссу и выбрали UTC в качестве официальной аббревиатуры, чтобы, независимо от языка, аббревиатура была одинаковой.
UTC и часовые пояса
UTC - это стандарт времени, по которому синхронизируется (или координируется) все мировое времяисчисление. Сам по себе он не является часовым поясом, а скорее трансцендентным стандартом, определяющим, что такое часовые пояса.
Всемирное время точно измеряется с помощью астрономического времени, относящегося к вращению Земли, и атомных часов.
Временные зоны определяются по их смещению относительно UTC. Например, в Северной и Южной Америке центральный часовой пояс (CT) отстает от UTC на пять или шесть часов и поэтому использует обозначения UTC-5:00 или UTC-6:00.
Сидней, Австралия, напротив, относится к австралийскому восточному часовому поясу (AET), который опережает UTC на десять или одиннадцать часов (UTC+10:00 или UTC+11:00).
Эта разница (UTC-6:00 - UTC+10:00) является причиной разницы, которую вы наблюдали в двух выводах ctime()
в предыдущих примерах:
- Центральное время (CT):
'Mon Feb 25 19:11:59 2019'
- Австралийское восточное время (AET):
'Tue Feb 26 12:11:59 2019'
Между этими временами разница составляет ровно шестнадцать часов, что согласуется со смещением часовых поясов, о котором говорилось выше.
Возможно, вам интересно, почему CT может отставать от UTC на пять или шесть часов, а AET - на десять или одиннадцать часов. Причина в том, что в некоторых регионах мира, включая части этих часовых поясов, наблюдается переход на летнее время.
Летнее время
В летние месяцы обычно бывает больше дневных световых часов, чем в зимние. В связи с этим в некоторых регионах весной и летом вводится летнее время, чтобы лучше использовать эти часы дневного света.
В местах, где соблюдается DST, в начале весны часы переходят на один час вперед (фактически теряя один час). Затем, осенью, часы будут переведены на стандартное время.
Буквы S и D обозначают стандартное время и летнее время в обозначениях часовых поясов:
- Центральное стандартное время (CST)
- Австралийское восточное летнее время (AEDT)
Когда вы представляете время в виде временных меток в местном времени, всегда важно учитывать, применяется ли DST или нет.
ctime()
учитывает летнее время. Таким образом, указанная ранее разница в выходных данных будет точнее выглядеть следующим образом:
- Центральное стандартное время (CST):
'Mon Feb 25 19:11:59 2019'
- Австралийское восточное летнее время (AEDT):
'Tue Feb 26 12:11:59 2019'
Работа со временем в Python с помощью структур данных
Теперь, когда вы хорошо знаете многие фундаментальные понятия о времени, включая эпохи, часовые пояса и UTC, давайте рассмотрим другие способы представления времени с помощью модуля Python time
.
Python Время как кортеж
Вместо числа для представления времени в Python можно использовать другую примитивную структуру данных: кортеж.
Кортеж позволяет вам управлять временем немного проще, абстрагируя некоторые данные и делая их более читаемыми.
Когда вы представляете время в виде кортежа, каждый элемент в вашем кортеже соответствует определенному элементу времени:
- Год
- Месяц как целое число, в диапазоне от 1 (январь) до 12 (декабрь)
- День месяца
- Час как целое число, в диапазоне от 0 (12 часов ночи) до 23 (11 часов вечера)
- Минута
- Секунда
- День недели в виде целого числа, в диапазоне от 0 (понедельник) до 6 (воскресенье)
- День года
- Летнее время как целое число со следующими значениями:
1
- летнее время.0
- стандартное время.-1
- неизвестно.
Используя уже изученные методы, вы можете представить одно и то же время в Python двумя разными способами:
>>> from time import time, ctime
>>> t = time()
>>> t
1551186415.360564
>>> ctime(t)
'Tue Feb 26 07:06:55 2019'
>>> time_tuple = (2019, 2, 26, 7, 6, 55, 1, 57, 0)
В данном случае и t
, и time_tuple
представляют одно и то же время, но кортеж обеспечивает более удобный интерфейс для работы с компонентами времени.
Технические подробности: На самом деле, если вы посмотрите на время Python, представленное time_tuple
в секундах (что вы увидите позже в этой статье), вы увидите, что оно разрешается 1551186415.0
, а не 1551186415.360564
.
Это происходит потому, что кортеж не имеет способа представления дробных секунд.
Хотя кортеж обеспечивает более удобный интерфейс для работы со временем в Python, существует еще более совершенный объект: struct_time
.
Python Время как объект
Проблема с конструкцией кортежа в том, что он все равно выглядит как куча чисел, хотя он лучше организован, чем одно число, основанное на секундах.
struct_time
обеспечивает решение этой проблемы, используя NamedTuple
из модуля collections
Python, чтобы связать последовательность чисел кортежа с полезными идентификаторами:
>>> from time import struct_time
>>> time_tuple = (2019, 2, 26, 7, 6, 55, 1, 57, 0)
>>> time_obj = struct_time(time_tuple)
>>> time_obj
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=26, tm_hour=7, tm_min=6, tm_sec=55, tm_wday=1, tm_yday=57, tm_isdst=0)
Технические подробности: Если вы изучаете другой язык, то термины struct
и object
могут быть противоположны друг другу.
В Python не существует типа данных, называемого struct
. Вместо этого все является объектом.
Однако название struct_time
заимствовано из библиотеки времени на языке Си, где типом данных на самом деле является struct
.
Фактически, модуль time
Python, который реализован на C, использует этот struct
напрямую, включая заголовочный файл times.h
.
Теперь вы можете обращаться к определенным элементам time_obj
, используя имя атрибута, а не индекс:
>>> day_of_year = time_obj.tm_yday
>>> day_of_year
57
>>> day_of_month = time_obj.tm_mday
>>> day_of_month
26
Помимо удобства чтения и использования struct_time
, его важно знать еще и потому, что он является возвращаемым типом многих функций в модуле Python time
.
Преобразование времени Python в секундах в объект
Теперь, когда вы познакомились с тремя основными способами работы со временем в Python, вы узнаете, как преобразовывать данные между различными типами времени.
Преобразование между типами временных данных зависит от того, указано ли время в UTC или местное время.
Всемирное координированное время (UTC)
Эпоха использует для своего определения UTC, а не часовой пояс. Поэтому количество секунд, прошедших с момента наступления эпохи, не зависит от вашего географического положения.
Однако то же самое нельзя сказать о struct_time
. Объектное представление времени Python может учитывать или не учитывать ваш часовой пояс.
Существует два способа преобразовать float, представляющий секунды, в struct_time
:
- UTC
- Местное время
Для преобразования плавающего времени в Python в время по UTC struct_time
в модуле Python time
предусмотрена функция gmtime()
.
Вы уже видели gmtime()
, использованный один раз в этой статье:
>>> import time
>>> time.gmtime(0)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
Вы использовали этот вызов, чтобы узнать эпоху вашей системы. Теперь у вас есть лучшая основа для понимания того, что здесь происходит.
gmtime()
преобразует количество прошедших секунд с момента эпохи в struct_time
в UTC. В данном случае вы передали 0
в качестве количества секунд, то есть вы пытаетесь найти саму эпоху в UTC.
Примечание: Обратите внимание, что атрибут tm_isdst
установлен в значение 0
. Этот атрибут показывает, использует ли часовой пояс летнее время. UTC никогда не подписывается на DST, поэтому этот флаг всегда будет 0
при использовании gmtime()
.
Как вы уже видели, struct_time
не может представлять дробные секунды, поэтому gmtime()
игнорирует дробные секунды в аргументе:
>>> import time
>>> time.gmtime(1.99)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=1, tm_wday=3, tm_yday=1, tm_isdst=0)
Обратите внимание, что хотя количество прошедших секунд было очень близко к 2
, .99
дробные секунды были просто проигнорированы, как показано на tm_sec=1
.
Параметр secs
для gmtime()
является необязательным, то есть вы можете вызвать gmtime()
без аргументов. В этом случае вы получите текущее время в UTC:
>>> import time
>>> time.gmtime()
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=28, tm_hour=12, tm_min=57, tm_sec=24, tm_wday=3, tm_yday=59, tm_isdst=0)
Интересно, что в модуле time
не существует обратной функции для этой функции. Вместо этого вам придется искать в модуле Python calendar
функцию с именем timegm()
:
>>> import calendar
>>> import time
>>> time.gmtime()
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=28, tm_hour=13, tm_min=23, tm_sec=12, tm_wday=3, tm_yday=59, tm_isdst=0)
>>> calendar.timegm(time.gmtime())
1551360204
timegm()
принимает кортеж (или struct_time
, поскольку является подклассом кортежа) и возвращает соответствующее количество секунд, прошедших с эпохи.
Исторический контекст: Если вам интересно, почему timegm()
нет в time
, вы можете посмотреть обсуждение в Python Issue 6280.
Короче говоря, первоначально она была добавлена в calendar
, потому что time
близко следует библиотеке времени языка C (определенной в time.h
), которая не содержит соответствующей функции. В вышеупомянутом выпуске была предложена идея перемещения или копирования timegm()
в time
.
Однако, учитывая развитие библиотеки datetime
, несоответствия в исправленной реализации time.timegm()
и вопрос о том, как затем работать с calendar.timegm()
, сопровождающие отказались от патча, предложив использовать вместо него datetime
.
Работа с UTC важна для программирования, поскольку это стандарт. Вам не нужно беспокоиться о DST, часовом поясе или информации о локали.
Однако существует множество случаев, когда вы захотите использовать местное время. Далее вы увидите, как преобразовать секунды в местное время, чтобы вы могли сделать именно это.
Локальное время
В вашем приложении вам может понадобиться работать с местным временем, а не с UTC. Модуль Python time
предоставляет функцию для получения местного времени из количества секунд, прошедших с момента наступления эпохи, которая называется localtime()
.
Сигнатура localtime()
похожа на gmtime()
тем, что принимает необязательный аргумент secs
, который используется для построения struct_time
с учетом вашего местного часового пояса:
>>> import time
>>> time.time()
1551448206.86196
>>> time.localtime(1551448206.86196)
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=7, tm_min=50, tm_sec=6, tm_wday=4, tm_yday=60, tm_isdst=0)
Обратите внимание, что tm_isdst=0
. Поскольку DST зависит от местного времени, tm_isdst
будет меняться между 0
и 1
в зависимости от того, применима ли DST для данного времени. Так как tm_isdst=0
, DST не применяется для 1 марта 2019 года.
В США в 2019 году переход на летнее время начинается 10 марта. Поэтому, чтобы проверить, правильно ли изменится флаг DST, нужно добавить к аргументу secs
секунд за 9 дней.
Чтобы вычислить это, возьмите количество секунд в сутках (86 400) и умножьте его на 9 дней:
>>> new_secs = 1551448206.86196 + (86400 * 9)
>>> time.localtime(new_secs)
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=10, tm_hour=8, tm_min=50, tm_sec=6, tm_wday=6, tm_yday=69, tm_isdst=1)
Теперь вы увидите, что struct_time
показывает дату 10 марта 2019 года с помощью tm_isdst=1
. Также обратите внимание, что tm_hour
также перескочил вперед, на 8
вместо 7
в предыдущем примере, из-за перехода на летнее время.
Начиная с Python 3.3, struct_time
также включает два атрибута, которые полезны для определения часового пояса struct_time
:
tm_zone
tm_gmtoff
Сначала эти атрибуты зависели от платформы, но начиная с Python 3.6 они доступны на всех платформах.
Во-первых, tm_zone
сохраняет местный часовой пояс:
>>> import time
>>> current_local = time.localtime()
>>> current_local.tm_zone
'CST'
Здесь видно, что localtime()
возвращает struct_time
с часовым поясом, установленным на CST
(центральное стандартное время).
Как вы уже видели, вы также можете определить часовой пояс на основе двух частей информации, смещения UTC и DST (если применимо):
>>> import time
>>> current_local = time.localtime()
>>> current_local.tm_gmtoff
-21600
>>> current_local.tm_isdst
0
В данном случае вы видите, что current_local
отстает от GMT на 21600
секунды, что означает среднее время по Гринвичу. GMT - это часовой пояс без смещения UTC: UTC±00:00.
21600
секунд, деленное на количество секунд в час (3 600), означает, что current_local
время равно GMT-06:00
(или UTC-06:00
).
Вы можете использовать смещение GMT плюс статус DST, чтобы сделать вывод, что current_local
находится UTC-06:00
в стандартном времени, что соответствует Центральному стандартному часовому поясу.
Как и gmtime()
, при вызове localtime()
можно игнорировать аргумент secs
, и он вернет текущее местное время в формате struct_time
:
>>> import time
>>> time.localtime()
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=8, tm_min=34, tm_sec=28, tm_wday=4, tm_yday=60, tm_isdst=0)
В отличие от gmtime()
, обратная функция localtime()
действительно существует в модуле Python time
. Давайте посмотрим, как это работает.
Преобразование объекта локального времени в секунды
Вы уже видели, как преобразовать объект времени UTC в секунды с помощью calendar.timegm()
. Чтобы преобразовать местное время в секунды, вы будете использовать mktime()
.
mktime()
требует передачи параметра t
, который принимает форму либо обычного 9-кортежа, либо struct_time
объекта, представляющего местное время:
>>> import time
>>> time_tuple = (2019, 3, 10, 8, 50, 6, 6, 69, 1)
>>> time.mktime(time_tuple)
1552225806.0
>>> time_struct = time.struct_time(time_tuple)
>>> time.mktime(time_struct)
1552225806.0
Важно помнить, что t
должен быть кортежем, представляющим местное время, а не UTC:
>>> from time import gmtime, mktime
>>> # 1
>>> current_utc = time.gmtime()
>>> current_utc
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=14, tm_min=51, tm_sec=19, tm_wday=4, tm_yday=60, tm_isdst=0)
>>> # 2
>>> current_utc_secs = mktime(current_utc)
>>> current_utc_secs
1551473479.0
>>> # 3
>>> time.gmtime(current_utc_secs)
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=20, tm_min=51, tm_sec=19, tm_wday=4, tm_yday=60, tm_isdst=0)
Примечание: Для этого примера предположим, что местное время равно March 1, 2019 08:51:19 CST
.
Этот пример показывает, почему важно использовать mktime()
для местного времени, а не UTC:
-
gmtime()
без аргумента возвращаетstruct_time
, используя UTC.current_utc
показываетMarch 1, 2019 14:51:19 UTC
. Это точно, потому чтоCST is UTC-06:00
, поэтому UTC должно опережать местное время на 6 часов. -
mktime()
пытается вернуть количество секунд, ожидая местное время, но вместо этого вы передалиcurrent_utc
. Таким образом, вместо того чтобы понять, чтоcurrent_utc
- это время UTC, он предполагает, что вы имели в видуMarch 1, 2019 14:51:19 CST
. -
gmtime()
затем используется для преобразования этих секунд обратно в UTC, что приводит к несоответствию. Теперь время составляетMarch 1, 2019 20:51:19 UTC
. Причиной этого несоответствия является тот факт, чтоmktime()
ожидается местное время. Таким образом, преобразование обратно в UTC добавляет еще 6 часов к местному времени.
Работа с часовыми поясами, как известно, очень сложна, поэтому важно настроить себя на успех, поняв разницу между UTC и местным временем, а также функции времени Python, которые работают с каждым из них.
Преобразование объекта времени Python в строку
Хотя работа с кортежами - это весело и все такое, иногда лучше работать со строками.
Строковые представления времени, также известные как временные метки, помогают сделать время более читаемым и могут быть особенно полезны для создания интуитивно понятных пользовательских интерфейсов.
Для преобразования объекта time.struct_time
в строку используются две функции Python time
:
asctime()
strftime()
Вначале вы узнаете о asctime()
.
asctime()
Вы используете asctime()
для преобразования кортежа времени или struct_time
в временную метку:
>>> import time
>>> time.asctime(time.gmtime())
'Fri Mar 1 18:42:08 2019'
>>> time.asctime(time.localtime())
'Fri Mar 1 12:42:15 2019'
Оба gmtime()
и localtime()
возвращают struct_time
экземпляры, для UTC и местного времени соответственно.
Вы можете использовать asctime()
для преобразования любого struct_time
в метку времени. asctime()
работает аналогично ctime()
, о которой вы узнали ранее в этой статье, за исключением того, что вместо числа с плавающей точкой вы передаете кортеж. Даже формат временной метки у этих двух функций одинаков.
Как и в случае с ctime()
, параметр для asctime()
является необязательным. Если вы не передадите объект времени в asctime()
, то он будет использовать текущее локальное время:
>>> import time
>>> time.asctime()
'Fri Mar 1 12:56:07 2019'
Как и в случае с ctime()
, он также игнорирует информацию о локали.
Одним из самых больших недостатков asctime()
является негибкость формата. strftime()
решает эту проблему, позволяя форматировать временные метки.
strftime()
Вы можете оказаться в ситуации, когда формат строк из ctime()
и asctime()
не устраивает ваше приложение. Вместо этого вы можете захотеть отформатировать строки так, чтобы они были более понятны вашим пользователям.
Например, если вы хотите отобразить время в строке, учитывающей информацию о локали.
Для форматирования строк, заданных кортежем времени struct_time
или Python, вы используете strftime()
, что означает "string format time."
strftime()
принимает два аргумента:
format
задает порядок и форму элементов времени в вашей строке.t
- необязательный кортеж времени.
Для форматирования строки используются директивы. Директивы - это последовательности символов, начинающиеся с %
, которые задают определенный элемент времени, например:
%d
: День месяца%m
: Месяц года%Y
: Год
Например, вы можете вывести дату в местном времени, используя стандарт ISO 8601 следующим образом:
>>> import time
>>> time.strftime('%Y-%m-%d', time.localtime())
'2019-03-01'
Дальнейшее чтение: Хотя представление дат с помощью времени в Python вполне допустимо и приемлемо, вам также следует рассмотреть возможность использования модуля Python datetime
, который предоставляет сокращения и более надежную основу для совместной работы с датами и временем.
Например, вы можете упростить вывод даты в формате ISO 8601, используя datetime
:
>>> from datetime import date
>>> date(year=2019, month=3, day=1).isoformat()
'2019-03-01'
Чтобы узнать больше об использовании модуля Python datetime
, посмотрите статью Using Python datetime to Work With Dates and Times
Как вы уже видели, большим преимуществом использования strftime()
перед asctime()
является его способность отображать временные метки, использующие информацию, специфичную для конкретной местности.
Например, если вы хотите представить дату и время с учетом местной специфики, вы не можете использовать asctime()
:
>>> from time import asctime
>>> asctime()
'Sat Mar 2 15:21:14 2019'
>>> import locale
>>> locale.setlocale(locale.LC_TIME, 'zh_HK') # Chinese - Hong Kong
'zh_HK'
>>> asctime()
'Sat Mar 2 15:58:49 2019'
Обратите внимание, что даже после программной смены локали asctime()
по-прежнему возвращает дату и время в том же формате, что и раньше.
Технические подробности: LC_TIME
- это категория локали для форматирования даты и времени. Аргумент locale
'zh_HK'
может быть другим, в зависимости от вашей системы.
При использовании strftime()
, однако, вы увидите, что он учитывает локаль:
>>> from time import strftime, localtime
>>> strftime('%c', localtime())
'Sat Mar 2 15:23:20 2019'
>>> import locale
>>> locale.setlocale(locale.LC_TIME, 'zh_HK') # Chinese - Hong Kong
'zh_HK'
>>> strftime('%c', localtime())
'六 3/ 2 15:58:12 2019' 2019'
Здесь вы успешно использовали информацию о локали, потому что использовали strftime()
.
Примечание: %c
- это директива для даты и времени, соответствующих местным условиям.
Если временной кортеж не передан в параметре t
, то strftime()
по умолчанию будет использовать результат localtime()
. Таким образом, вы можете упростить приведенные выше примеры, удалив необязательный второй аргумент:
>>> from time import strftime
>>> strftime('The current local datetime is: %c')
'The current local datetime is: Fri Mar 1 23:18:32 2019'
Здесь вы использовали время по умолчанию вместо того, чтобы передать в качестве аргумента свое собственное. Также обратите внимание, что аргумент format
может состоять из текста, отличного от директив форматирования.
Дальнейшее чтение: Ознакомьтесь с этим подробным списком директив, доступных для strftime()
.
Модуль Python time
также включает обратную операцию преобразования временной метки обратно в объект struct_time
.
Преобразование строки времени Python в объект
Когда вы работаете со строками, связанными с датой и временем, может быть очень полезно преобразовать временную метку в объект времени.
Чтобы преобразовать строку времени в struct_time
, вы используете strptime()
, что означает "string parse time":
>>> from time import strptime
>>> strptime('2019-03-01', '%Y-%m-%d')
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=60, tm_isdst=-1)
Первым аргументом strptime()
должна быть временная метка, которую вы хотите преобразовать. Второй аргумент - это format
, в котором находится временная метка.
Параметр format
является необязательным и по умолчанию принимает значение '%a %b %d %H:%M:%S %Y'
. Поэтому, если у вас есть временная метка в этом формате, вам не нужно передавать ее в качестве аргумента:
>>> strptime('Fri Mar 01 23:38:40 2019')
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=23, tm_min=38, tm_sec=40, tm_wday=4, tm_yday=60, tm_isdst=-1)
Поскольку struct_time
имеет 9 ключевых компонентов даты и времени, strptime()
должен предоставить разумные значения по умолчанию для тех компонентов, которые он не может разобрать из string
.
В предыдущих примерах tm_isdst=-1
. Это означает, что strptime()
не может определить по метке времени, переходит ли она на летнее время или нет.
Теперь вы знаете, как работать со временем и датами в Python, используя модуль time
различными способами. Однако есть и другие способы использования time
, помимо простого создания объектов времени, получения строк времени Python и использования секунд, прошедших с эпохи.
Приостановка выполнения
Одной из действительно полезных функций времени в Python является sleep()
, которая приостанавливает выполнение потока на заданное время.
Например, вы можете приостановить выполнение вашей программы на 10 секунд следующим образом:
>>> from time import sleep, strftime
>>> strftime('%c')
'Fri Mar 1 23:49:26 2019'
>>> sleep(10)
>>> strftime('%c')
'Fri Mar 1 23:49:36 2019'
Ваша программа напечатает первую отформатированную datetime
строку, затем сделает паузу в 10 секунд и, наконец, напечатает вторую отформатированную datetime
строку.
Вы также можете передавать дробные секунды в sleep()
:
>>> from time import sleep
>>> sleep(0.5)
sleep()
полезен для тестирования или для того, чтобы заставить программу ждать по какой-либо причине, но вы должны быть осторожны и не останавливать ваш производственный код, если у вас нет на то веских причин.
До Python 3.5 сигнал, посланный вашему процессу, мог прервать sleep()
. Однако в версии 3.5 и более поздних sleep()
всегда будет приостанавливать выполнение по крайней мере на указанное время, даже если процесс получит сигнал.
sleep()
- это всего лишь одна временная функция Python, которая может помочь вам протестировать ваши программы и сделать их более надежными.
Измерение производительности
Вы можете использовать time
для измерения производительности вашей программы.
Для этого используется perf_counter()
, который, как следует из названия, представляет собой счетчик производительности с высоким разрешением для измерения коротких промежутков времени.
Чтобы использовать perf_counter()
, вы помещаете счетчик перед началом выполнения кода, а также после завершения его выполнения:
>>> from time import perf_counter
>>> def longrunning_function():
... for i in range(1, 11):
... time.sleep(i / i ** 2)
...
>>> start = perf_counter()
>>> longrunning_function()
>>> end = perf_counter()
>>> execution_time = (end - start)
>>> execution_time
8.201258441999926
Во-первых, start
фиксирует момент до вызова функции. end
фиксирует момент после возврата функции. Общее время выполнения функции заняло (end - start)
секунд.
Технические подробности: В Python 3.7 появилась функция perf_counter_ns()
, которая работает так же, как perf_counter()
, но использует наносекунды вместо секунд.
perf_counter()
(или perf_counter_ns()
) - это наиболее точный способ измерить производительность вашего кода с помощью одного выполнения. Однако если вы пытаетесь точно оценить производительность фрагмента кода, я рекомендую использовать модуль Python timeit
.
timeit
специализируется на многократном выполнении кода для получения более точного анализа производительности и помогает избежать чрезмерного упрощения измерения времени, а также других распространенных ловушек.
Заключение
Поздравляем! Теперь у вас есть отличная основа для работы с датами и временем в Python.
Теперь вы можете:
- Для работы со временем используйте число с плавающей точкой, представляющее секунды, прошедшие с момента эпохи
- Управлять временем с помощью кортежей и
struct_time
объектов - Преобразование между секундами, кортежами и строками временных меток
- Приостановить выполнение потока Python
- Измерьте производительность с помощью
perf_counter()
Кроме того, вы узнали некоторые фундаментальные понятия, связанные с датой и временем, такие как:
- Эпохи
- UTC
- Часовые пояса
- Летнее время
Теперь пришло время применить полученные знания о времени Python в реальных приложениях!
Дальнейшее чтение
Если вы хотите продолжить знакомство с использованием дат и времени в Python, обратите внимание на следующие модули:
datetime
: Более надежный модуль даты и времени в стандартной библиотеке Pythontimeit
: Модуль для измерения производительности фрагментов кодаastropy
: Более высокая точность временных данных, используемых в астрономии