Рубрики
Без рубрики

время – Часы Время

Автор оригинала: Doug Hellmann.

Цель:

Функции для управления временем на часах.

Модуль time обеспечивает доступ к нескольким различным типам часов, каждый из которых используется для разных целей. Стандартные системные вызовы, такие как time () , сообщают системное время “настенных часов”. Часы monotonic () можно использовать для измерения прошедшего времени в длительном процессе, потому что они гарантированно никогда не будут двигаться назад, даже если системное время изменилось. Для тестирования производительности perf_counter () предоставляет доступ к часам с самым высоким доступным разрешением, чтобы сделать короткие измерения более точными. Время ЦП доступно через clock () , а process_time () возвращает объединенное время процессора и системное время.

Примечание

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

Сравнение часов

Детали реализации часов зависят от платформы. Используйте get_clock_info () для доступа к основной информации о текущей реализации, включая разрешение часов.

time_get_clock_info.py

import textwrap
import time

available_clocks  [
    ('monotonic', time.monotonic),
    ('perf_counter', time.perf_counter),
    ('process_time', time.process_time),
    ('time', time.time),
]

for clock_name, func in available_clocks:
    print(textwrap.dedent('''\
    {name}:
        adjustable    : {info.adjustable}
        implementation: {info.implementation}
        monotonic     : {info.monotonic}
        resolution    : {info.resolution}
        current       : {current}
    ''').format(
        nameclock_name,
        infotime.get_clock_info(clock_name),
        currentfunc())
    )

Этот вывод для macOS показывает, что часы monotonic и perf_counter реализованы с использованием одного и того же базового системного вызова.

$ python3 time_get_clock_info.py

monotonic:
    adjustable    : False
    implementation: mach_absolute_time()
    monotonic     : True
    resolution    : 1e-09
    current       : 0.047857746

perf_counter:
    adjustable    : False
    implementation: mach_absolute_time()
    monotonic     : True
    resolution    : 1e-09
    current       : 0.047930006

process_time:
    adjustable    : False
    implementation: getrusage(RUSAGE_SELF)
    monotonic     : True
    resolution    : 1e-06
    current       : 0.074122

time:
    adjustable    : True
    implementation: gettimeofday()
    monotonic     : False
    resolution    : 1e-06
    current       : 1544377423.803307

Настенные часы время

Одной из основных функций модуля time является time () , который возвращает количество секунд с начала «эпохи» в виде значения с плавающей запятой.

time_time.py

import time

print('The time is:', time.time())

Эпоха – это начало измерения времени, которое для систем Unix составляет 0:00 1 января 1970 года. Хотя значение всегда является плавающим, фактическая точность зависит от платформы.

$ python3 time_time.py

The time is: 1544377423.849656

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

time_ctime.py

import time

print('The time is      :', time.ctime())
later  time.time() + 15
print('15 secs from now :', time.ctime(later))

Второй вызов print () в этом примере показывает, как использовать ctime () для форматирования значения времени, отличного от текущего времени.

$ python3 time_ctime.py

The time is      : Sun Dec  9 12:43:43 2018
15 secs from now : Sun Dec  9 12:43:58 2018

Монотонные часы

Поскольку time () смотрит на системные часы, а системные часы могут быть изменены пользователем или системными службами для синхронизации часов на нескольких компьютерах, повторный вызов time () может производят значения, которые идут вперед и назад. Это может привести к неожиданному поведению при попытке измерить продолжительность или иным образом использовать это время для вычислений. Избегайте таких ситуаций, используя monotonic () , который всегда возвращает значения, которые идут вперед.

time_monotonic.py

import time

start  time.monotonic()
time.sleep(0.1)
end  time.monotonic()
print('start : {:>9.2f}'.format(start))
print('end   : {:>9.2f}'.format(end))
print('span  : {:>9.2f}'.format(end - start))

Начальная точка для монотонных часов не определена, поэтому возвращаемые значения полезны только для выполнения вычислений с другими значениями часов. В этом примере продолжительность сна измеряется с помощью monotonic () .

$ python3 time_monotonic.py

start :      0.02
end   :      0.13
span  :      0.10

Время процессора

В то время как time () возвращает время настенных часов, process_time () возвращает время процессора. Значения, возвращаемые функцией process_time () , отражают фактическое время, используемое программой при ее запуске.

time_process_time.py

import hashlib
import time

# Data to use to calculate md5 checksums
data  open(__file__, 'rb').read()

for i in range(5):
    h  hashlib.sha1()
    print(time.ctime(), ': {:0.3f} {:0.3f}'.format(
        time.time(), time.process_time()))
    for i in range(300000):
        h.update(data)
    cksum  h.digest()

В этом примере форматированный ctime () печатается вместе со значениями с плавающей запятой из time () и clock () для каждой итерации. через петлю.

Примечание

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

$ python3 time_process_time.py

Sun Dec  9 12:43:44 2018 : 1544377424.095 0.056
Sun Dec  9 12:43:44 2018 : 1544377424.423 0.675
Sun Dec  9 12:43:44 2018 : 1544377424.790 1.376
Sun Dec  9 12:43:45 2018 : 1544377425.108 1.997
Sun Dec  9 12:43:45 2018 : 1544377425.422 2.594

Обычно часы процессора не тикают, если программа ничего не делает.

time_clock_sleep.py

import time

template  '{} - {:0.2f} - {:0.2f}'

print(template.format(
    time.ctime(), time.time(), time.process_time())
)

for i in range(3, 0, -1):
    print('Sleeping', i)
    time.sleep(i)
    print(template.format(
        time.ctime(), time.time(), time.process_time())
    )

В этом примере цикл выполняет очень мало работы, переходя в спящий режим после каждой итерации. Значение time () увеличивается, даже когда приложение спит, а значение process_time () – нет.

$ python3 -u time_clock_sleep.py

Sun Dec  9 12:43:45 2018 - 1544377425.83 - 0.06
Sleeping 3
Sun Dec  9 12:43:48 2018 - 1544377428.83 - 0.06
Sleeping 2
Sun Dec  9 12:43:50 2018 - 1544377430.84 - 0.06
Sleeping 1
Sun Dec  9 12:43:51 2018 - 1544377431.84 - 0.06

Вызов sleep () дает управление текущему потоку и просит его дождаться, пока система снова разбудит его. Если программа имеет только один поток, это эффективно блокирует приложение, и оно не работает.

Счетчик производительности

Для измерения производительности важно иметь монотонные часы с высоким разрешением. Для определения наилучшего источника данных часов требуется знание платформы, которое Python предоставляет в perf_counter () .

time_perf_counter.py

import hashlib
import time

# Data to use to calculate md5 checksums
data  open(__file__, 'rb').read()

loop_start  time.perf_counter()

for i in range(5):
    iter_start  time.perf_counter()
    h  hashlib.sha1()
    for i in range(300000):
        h.update(data)
    cksum  h.digest()
    now  time.perf_counter()
    loop_elapsed  now - loop_start
    iter_elapsed  now - iter_start
    print(time.ctime(), ': {:0.3f} {:0.3f}'.format(
        iter_elapsed, loop_elapsed))

Как и в случае с monotonic () , эпоха для perf_counter () не определена, и значения предназначены для использования для сравнения и вычисления значений, а не как абсолютное время.

$ python3 time_perf_counter.py

Sun Dec  9 12:43:52 2018 : 0.366 0.366
Sun Dec  9 12:43:52 2018 : 0.338 0.704
Sun Dec  9 12:43:52 2018 : 0.350 1.054
Sun Dec  9 12:43:53 2018 : 0.315 1.369
Sun Dec  9 12:43:53 2018 : 0.306 1.675

Компоненты времени

Сохранение времени в виде прошедших секунд полезно в некоторых ситуациях, но бывают случаи, когда программе требуется доступ к отдельным полям даты (год, месяц и т. Д.). Модуль time определяет struct_time для хранения значений даты и времени с разделенными компонентами, чтобы к ним было легко получить доступ. Есть несколько функций, которые работают со значениями struct_time вместо float.

time_struct.py

import time


def show_struct(s):
    print('  tm_year :', s.tm_year)
    print('  tm_mon  :', s.tm_mon)
    print('  tm_mday :', s.tm_mday)
    print('  tm_hour :', s.tm_hour)
    print('  tm_min  :', s.tm_min)
    print('  tm_sec  :', s.tm_sec)
    print('  tm_wday :', s.tm_wday)
    print('  tm_yday :', s.tm_yday)
    print('  tm_isdst:', s.tm_isdst)


print('gmtime:')
show_struct(time.gmtime())
print('\nlocaltime:')
show_struct(time.localtime())
print('\nmktime:', time.mktime(time.localtime()))

Функция gmtime () возвращает текущее время в формате UTC. localtime () возвращает текущее время с применением текущего часового пояса. mktime () принимает struct_time и преобразует его в представление с плавающей запятой.

$ python3 time_struct.py

gmtime:
  tm_year : 2018
  tm_mon  : 12
  tm_mday : 9
  tm_hour : 17
  tm_min  : 43
  tm_sec  : 53
  tm_wday : 6
  tm_yday : 343
  tm_isdst: 0

localtime:
  tm_year : 2018
  tm_mon  : 12
  tm_mday : 9
  tm_hour : 12
  tm_min  : 43
  tm_sec  : 53
  tm_wday : 6
  tm_yday : 343
  tm_isdst: 0

mktime: 1544377433.0

Работа с часовыми поясами

Функции определения текущего времени зависят от того, установлен ли часовой пояс программой или используется часовой пояс по умолчанию, установленный для системы. Изменение часового пояса не влияет на фактическое время, а только на то, как оно представлено.

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

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

time_timezone.py

import time
import os


def show_zone_info():
    print('  TZ    :', os.environ.get('TZ', '(not set)'))
    print('  tzname:', time.tzname)
    print('  Zone  : {} ({})'.format(
        time.timezone, (time.timezone / 3600)))
    print('  DST   :', time.daylight)
    print('  Time  :', time.ctime())
    print()


print('Default :')
show_zone_info()

ZONES  [
    'GMT',
    'Europe/Amsterdam',
]

for zone in ZONES:
    os.environ['TZ']  zone
    time.tzset()
    print(zone, ':')
    show_zone_info()

Часовой пояс по умолчанию в системе, используемой для подготовки примеров, – США/Восток. Другие зоны в примере изменяют tzname, флаг дневного света и значение смещения часового пояса.

$ python3 time_timezone.py

Default :
  TZ    : (not set)
  tzname: ('EST', 'EDT')
  Zone  : 18000 (5.0)
  DST   : 1
  Time  : Sun Dec  9 12:43:53 2018

GMT :
  TZ    : GMT
  tzname: ('GMT', 'GMT')
  Zone  : 0 (0.0)
  DST   : 0
  Time  : Sun Dec  9 17:43:53 2018

Europe/Amsterdam :
  TZ    : Europe/Amsterdam
  tzname: ('CET', 'CEST')
  Zone  : -3600 (-1.0)
  DST   : 1
  Time  : Sun Dec  9 18:43:53 2018

Время синтаксического анализа и форматирования

Две функции strptime () и strftime () выполняют преобразование между struct_time и строковыми представлениями значений времени. Существует длинный список инструкций по форматированию для поддержки ввода и вывода в различных стилях. Полный список задокументирован в документации библиотеки для модуля time .

В этом примере текущее время преобразуется из строки в экземпляр struct_time и обратно в строку.

time_strptime.py

import time


def show_struct(s):
    print('  tm_year :', s.tm_year)
    print('  tm_mon  :', s.tm_mon)
    print('  tm_mday :', s.tm_mday)
    print('  tm_hour :', s.tm_hour)
    print('  tm_min  :', s.tm_min)
    print('  tm_sec  :', s.tm_sec)
    print('  tm_wday :', s.tm_wday)
    print('  tm_yday :', s.tm_yday)
    print('  tm_isdst:', s.tm_isdst)


now  time.ctime(1483391847.433716)
print('Now:', now)

parsed  time.strptime(now)
print('\nParsed:')
show_struct(parsed)

print('\nFormatted:',
      time.strftime("%a %b %d %H:%M:%S %Y", parsed))

Выходная строка не совсем такая, как входная, поскольку день месяца имеет префикс нуля.

$ python3 time_strptime.py

Now: Mon Jan  2 16:17:27 2017

Parsed:
  tm_year : 2017
  tm_mon  : 1
  tm_mday : 2
  tm_hour : 16
  tm_min  : 17
  tm_sec  : 27
  tm_wday : 0
  tm_yday : 2
  tm_isdst: -1

Formatted: Mon Jan 02 16:17:27 2017

Смотрите также

  • стандартная документация библиотеки времени
  • Заметки о переносе Python 2 на 3 на время
  • datetime – модуль datetime включает другие классы для выполнения вычислений с датой и временем.
  • календарь – Работа с функциями даты более высокого уровня для создания календарей или расчета повторяющихся событий.