首页 > 代码库 > Python time.md

Python time.md

time模块

Comparing Clocks

time.clock():在Unix 上,返回当前的处理器时间,以浮点数秒数表示。
time.monotonic():返回一个单调时钟的值(在分秒内),也就是不能倒回去的时钟。时钟不受系统时钟更新的影响。返回值的引用点是未定义的,因此只有连续调用的结果之间的差异是有效的。
time.perf_counter():返回一个性能计数器的值(在分秒内),即一个具有最高可用分辨率的时钟,以测量短时间。它包括了在睡眠期间的时间,并且是系统范围的。返回值的引用点是未定义的,因此只有连续调用的结果之间的差异是有效的。
time.process_time():返回当前进程的系统和用户CPU时间的值(在分秒内)。它不包括sleep时的时间。它是整个过程的定义。返回值的引用点是未定义的,因此只有连续调用的结果之间的差异是有效的。
time.time():返回自epoch以来时间的秒数,为浮点数。注意,即使返回的时间永远是浮点数,但是不是所有的系统都提供精度大于1秒的时间。虽然这个函数通常返回非递减值,如果在两次调用期间系统时钟被往回设置了,它可能返回比前一次调用小的值。
time.get_clock_info(name):获取指定时钟上的信息作为名称空间对象。支持的时钟名称和相应的函数来读取它们的值:

  • ‘clock‘: time.clock()
  • ‘monotonic‘: time.monotonic()
  • ‘perf_counter‘: time.perf_counter()
  • ‘process_time‘: time.process_time()
  • ‘time‘: time.time()

其结果如下:

  • adjustable:True 如果时钟可以自动改变 (e.g. by a NTP daemon)或者由系统管理员手动操作。否则为False。
  • implementation:用于获得时钟值的底层C函数的名称
  • monotonic:True 如果时钟不能倒转。否则为False。
  • resolution:The resolution of the clock in seconds (float)

举例

import textwrap
import time

available_locks = [
    (‘clock‘, time.clock),
    (‘monotonic‘, time.monotonic),
    (‘perf_counter‘, time.perf_counter),
    (‘process_time‘, time.process_time),
    (‘time‘, time.time),
]

for clock_name, func in available_locks:
    print(textwrap.dedent(‘‘‘    {name}:
        adjustable      : {info.adjustable}
        implementation  : {info.implementation}
        monotonic       : {info.monotonic}
        resolution      : {info.resolution}
        current         : {current}
        ‘‘‘).format(name=clock_name,
            info=time.get_clock_info(clock_name),
            current=func())
    )

输出:

clock:
    adjustable      : False
    implementation  : QueryPerformanceCounter()
    monotonic       : True
    resolution      : 3.0917042772491994e-07
    current         : 3.7100451326990392e-06

monotonic:
    adjustable      : False
    implementation  : GetTickCount64()
    monotonic       : True
    resolution      : 0.015600099999999999
    current         : 11395.483

perf_counter:
    adjustable      : False
    implementation  : QueryPerformanceCounter()
    monotonic       : True
    resolution      : 3.0917042772491994e-07
    current         : 0.00010171707072149866

process_time:
    adjustable      : False
    implementation  : GetProcessTimes()
    monotonic       : True
    resolution      : 1e-07
    current         : 0.031200199999999997

time:
    adjustable      : True
    implementation  : GetSystemTimeAsFileTime()
    monotonic       : False
    resolution      : 0.015600099999999999
    current         : 1498969586.3116002

Wall Clock Time

time.time():返回自epoch以来时间的秒数,为浮点数。注意,即使返回的时间永远是浮点数,但是不是所有的系统都提供精度大于1秒的时间。虽然这个函数通常返回非递减值,如果在两次调用期间系统时钟被往回设置了,它可能返回比前一次调用小的值。
time.ctime([secs]):将自epoch以来的时间秒数转换成一个表示当前时间的字符串。如果secs没有提供或者为None,则使用time()返回的当前时间。ctime(secs)等同于asctime(localtime(secs))。ctime()没有使用区域信息。
举例

print(‘The time is     :‘, time.time())
print(‘The ctime is    :‘, time.ctime())
later = time.time() + 15
print(‘15 sec from now :‘, time.ctime(later))

输出:

The time is     : 1498969949.1106
The ctime is    : Sun Jul  2 12:32:29 2017
15 sec from now : Sun Jul  2 12:32:44 2017

Monotonic Clocks

因为time() 查看系统时钟,系统时钟可以由用户或系统服务改变,以便跨多台计算机同步时钟,所以重复调用time()可能产生向前和向后的值。 这可能导致在尝试测量持续时间或以其他方式使用那些计算时的意外行为。 通过使用monotonic()来避免这些情况,它总是返回向前推的值。

time.monotonic():返回一个单调时钟的值(在分秒内),也就是不能倒回去的时钟。时钟不受系统时钟更新的影响。返回值的引用点是未定义的,因此只有连续调用的结果之间的差异是有效的。
time.sleep(secs):挂起执行,时间为给出的秒数。参数可以是浮点数以指明更精确的睡眠时间。真正挂起的时间可能小于要求的时间,因为根据信号捕获程序的执行任何捕获的信号都将终止sleep()。另外,由于系统中其它活动的调动,挂起的时间也可能比要求的时间长一段随机的时间。
举例

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

输出:

start :  12063.65
end   :  12063.76
span  :      0.11

Processor Clock Time

time()函数返回的是现实世界的时间, 而clock()函数返回的是cpu时钟. clock()函数返回值常用作性能测试, benchmarking等. 它们常常反映了程序运行的真实时间, 比time()函数返回的值要精确.
time.clock():在Unix 上,返回当前的处理器时间,以浮点数秒数表示。
举例

data = http://www.mamicode.com/open(__file__, ‘rb‘).read()

for i in range(5):
    h = hashlib.sha1()
    print(time.ctime(), ‘: {:0.3f} {:0.3f}‘.format(
        time.time(), time.clock()))
    for i in range(1000000):
        h.update(data)
    cksum = h.digest()

输出:

Sun Jul  2 12:42:02 2017 : 1498970522.676 0.000
Sun Jul  2 12:42:06 2017 : 1498970526.690 4.015
Sun Jul  2 12:42:10 2017 : 1498970530.747 8.072
Sun Jul  2 12:42:14 2017 : 1498970534.858 12.182
Sun Jul  2 12:42:18 2017 : 1498970538.882 16.206

在这个例子中, ctime()把time()函数返回的浮点型表示转化为标准时间, 每个迭代循环使用了clock(). 如果想在机器上测试这个例子, 那么可以增加循环次数, 或者处理大一点的数据, 这样才能看到不同点.
一般, 如果程序没有做任何事情, 处理器时钟是不会计时.

template = ‘{} - {:0.2f} - {:0.2f}‘
print(template.format(time.ctime(), time.time(), time.clock()))

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

Windows输出:

Sun Jul  2 12:46:10 2017 - 1498970770.79 - 0.00
Sleeping 3
Sun Jul  2 12:46:13 2017 - 1498970773.79 - 3.00
Sleeping 2
Sun Jul  2 12:46:15 2017 - 1498970775.79 - 5.00
Sleeping 1
Sun Jul  2 12:46:16 2017 - 1498970776.79 - 6.00

Unix输出:

Sun Jul  2 12:49:29 2017 - 1498970969.64 - 0.03
Sleeping 3
Sun Jul  2 12:49:32 2017 - 1498970972.65 - 0.03
Sleeping 2
Sun Jul  2 12:49:34 2017 - 1498970974.65 - 0.03
Sleeping 1
Sun Jul  2 12:49:35 2017 - 1498970975.65 - 0.03

Performance Counter

有一个高分辨率的单调时钟来测量性能是很重要的。确定最佳的时钟数据源需要特定于平台的知识,而Python提供了perfcounter()。

time.perf_counter():返回一个性能计数器的值(在分秒内),即一个具有最高可用分辨率的时钟,以测量短时间。它包括了在睡眠期间的时间,并且是系统范围的。返回值的引用点是未定义的,因此只有连续调用的结果之间的差异是有效的。
举例

data = http://www.mamicode.com/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(100000):
        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))

输出:

Sun Jul  2 12:51:39 2017 : 0.409 0.409
Sun Jul  2 12:51:40 2017 : 0.407 0.816
Sun Jul  2 12:51:40 2017 : 0.400 1.216
Sun Jul  2 12:51:40 2017 : 0.408 1.624
Sun Jul  2 12:51:41 2017 : 0.400 2.025

与monotonic()一样,perfcounter()的时间是没有定义的,并且这些值是用来比较和计算值的,而不是绝对的时间.

Time Components

在某些情况下将存储时间作为秒数是有用的,但有时候,程序需要访问日期(年,月等)的各个字段。 时间模块定义了用于保存日期和时间值的struct_time,其中组件被分解,因此它们易于访问。 有几个函数可以使用struct_time值而不是float。

class time.struct_time:由gmtime()、localtime()和strptime()返回的时间值序列的类型。它是一个具有名为tuple接口的对象:值可以通过索引和属性名访问。存在以下值:

Index Attribute Values
0 tm_year (for example, 1993)
1 tm_mon range [1, 12]
2 tm_mday range [1, 31]
3 tm_hour range [0, 23]
4 tm_min range [0, 59]
5 tm_sec range [0, 61]; see (2) in strftime() description
6 tm_wday range [0, 6], Monday is 0
7 tm_yday range [1, 366]
8 tm_isdst 0, 1 or -1; see below
N/A tm_zone abbreviation of timezone name
N/A tm_gmtoff offset east of UTC in seconds

time.gmtime([secs]):将自epoch 以来的时间秒数转换为UTC 的struct_time,它的dst 标记永远为零。如果secs没有提供或者为None,则使用time() 返回的当前时间。秒数的小数部分被忽略。
time.localtime([secs]):类似gmtime() 但是转换成当地时间。如果secs没有提供或者为None,则使用time() 返回的当前时间。当给的时间使用了DST时,dst 标记被设置为1。
time.mktime(t):localtime()相反的函数。它的参数为struct_time 或者表示当地时间 而不是UTC 时间的完整9-元组(因为需要dst 标记;如果不知道就使用-1作为dst 标记)。它返回一个浮点数,以与time()保持一致。如果输入的值不能表示成一个合法的时间,那么将抛出OverflowError或者ValueError(这依赖于非法的值是被Python还是底层的C库捕获)。它能生成的最早日期依赖于具体的平台。
举例

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:
  tm_year : 2017
  tm_mon  : 7
  tm_mday : 2
  tm_hour : 10
  tm_min  : 20
  tm_sec  : 25
  tm_wday : 6
  tm_yday : 183
  tm_isdst: 0

localtime:
  tm_year : 2017
  tm_mon  : 7
  tm_mday : 2
  tm_hour : 18
  tm_min  : 20
  tm_sec  : 25
  tm_wday : 6
  tm_yday : 183
  tm_isdst: 0

mktime: 1498990825.0

Working with Time Zones

无论是你的程序, 还是为系统使用一个默认的时区, 检测当前时间的函数依赖于当前Time Zone(时间域)的设置. 改变时区设置是不会改变实际时间, 只会改变表示时间的方法.
通过设置环境变量TZ可以改变时区, 然后调用tzset(). 环境变量TZ可以对时区来详细的设置, 比如白天保存时间的起始点. 通常使用时区名称是比较简单的, 如果需要了解更多信息可以参考库.

time.timezone:本地(非DST)时区的偏移量,以UTC以内的秒为单位(西欧大部分地区为负,美国为正,英国为零)。
time.tzname:两个字符串的元组:第一个是本地非DST时区的名称,第二个是本地DST时区的名称。如果未定义DST时区,则不应使用第二个字符串。
time.tzset():重置库例程使用的时间转换规则。环境变量 TZ指定如何完成此操作。
time.daylight:如果定义了DST时区,则为非零。
举例

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‘, ‘Asia/Shanghai‘,]

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

Unix输出:

Default :
  TZ    : (not set)
  tzname: (‘CST‘, ‘CST‘)
  Zone  : -28800 (-8.0)
  DST   : 0
  Time  : Sun Jul  2 18:59:51 2017

GMT :
  TZ    : GMT
  tzname: (‘GMT‘, ‘GMT‘)
  Zone  : 0 (0.0)
  DST   : 0
  Time  : Sun Jul  2 10:59:51 2017

Asia/Shanghai :
  TZ    : Asia/Shanghai
  tzname: (‘CST‘, ‘CST‘)
  Zone  : -28800 (-8.0)
  DST   : 0
  Time  : Sun Jul  2 18:59:51 2017

Parsing and Formatting Times

函数strptime()和strftime()可以使struct_time和时间值字符串相互转化. 有一个很长的格式化说明列表可以用来支持输入和输出不同的风格. 完整的列表在time模块的的库文档中有介绍.
time.strptime(string[, format]):根据格式解析表示时间的字符串。返回值是由gmtime()或localtime()返回的struct_time。
time.strftime(format[, t]):将表示由gmtime()或localtime()返回的时间的元组或struct_time转换为由格式指定的字符串参数。如果未提供t,则使用localtime()返回的当前时间。格式必须是字符串。如果t中的任何字段超出允许范围,则会引发ValueError。
以下指令可以嵌入格式字符串中。它们没有可选的字段宽度和精度规范,并由strftime()结果中指示的字符替换:

指示 含义
%a Locale的缩写工作日名称。
%A Locale的整个工作日名称。
%b 语言环境的缩写月份名称。
%B Locale的完整月份名称。
%c 语言环境的适当日期和时间表示。
%d 一个十进制数字[01,31]。
%H 小时(24小时制),十进制数[00,23]。
%I 小时(12小时制)十进制数[01,12]。
%j 一年中的十进制数[001,366]。
%m 月为十进制数[01,12]。
%M 以十进制数分钟[00,59]。
%p Locale相当于AM或PM。
%S 秒为十进制数[00,61]。
%U 年的星期数(星期日为星期的第一天)为十进制数[00,53]。在第一个星期日之前的新的一年的所有天被认为是在第0周。
%w 工作日为十进制数[0(星期日),6]。
%W 年的星期数(星期一作为星期的第一天)作为十进制数[00,53]。在第一个星期一之前的新的一年中的所有天被认为是在第0周。
%x 语言环境的适当日期表示。
%X 语言环境的适当时间表示。
%y 年,无世纪作为十进制数[00,99]。
%Y 年份以世纪为十进制数。
%z 指示与+ HHMM或-HHMM形式的UTC / GMT的正或负时差的时区偏移,其中H表示十进制小时数字,M表示十进制分数字[-23:59,+23:59]。
%Z 时区名称(如果没有时区,则不包含字符)。
%% 字面值‘%‘字符。

举例

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

Unix输出:

(‘Now:‘, ‘Tue Jan  3 05:17:27 2017‘)

Parsed:
(‘  tm_year :‘, 2017)
(‘  tm_mon  :‘, 1)
(‘  tm_mday :‘, 3)
(‘  tm_hour :‘, 5)
(‘  tm_min  :‘, 17)
(‘  tm_sec  :‘, 27)
(‘  tm_wday :‘, 1)
(‘  tm_yday :‘, 3)
(‘  tm_isdst:‘, -1)
(‘\nFormatted:‘, ‘Tue Jan 03 05:17:27 2017‘)

参考:https://pymotw.com/3/time/index.html#module-time

Python time.md