快速入门
- In [1]: import time
- # 获取当前时间
- In [25]: time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
- Out[25]: '2018-06-17_20-05-36'
- # 停顿 0.5 秒
- In [26]: time.sleep(0.5)
简介
功能: 时间访问和转换.
相关模块:
datetime 标准模块.
calendar 标准模块.
下面介绍一些术语和约定:
epoch 是时间开始点. 对于 Unix , 时代是 1970 年 1 月 1 日 0 点. 通过 time.gmtime(0)可以查看时间的起点:
- In [1]: import time
- In [2]: time.gmtime(0)
- Out[2]: 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)
- In [3]: time.gmtime(time.time() + 786041553) # 32 位会报错
- Out[3]: time.struct_time(tm_year=2043, tm_mon=5, tm_mday=8, tm_hour=6, tm_min=26, tm_sec=50, tm_wday=4, tm_yday=128, tm_isdst=0)
对于 32 位的 linux 系统, 时间只能处理到 2038 年. 现在新发布的主流已经全部是 64 位版本.
UTC 是协调世界时(前身为格林威治标准时间或 GMT).
DST 为夏令时, 通常是根据当地法律在一年内的部分时间进行一小时的调整. C 库包含有当地规则的表.
实时函数的精度可能比建议的要低. 例如在大多数 Unix 系统中, 时钟 "滴答" 只有 50 或 100 次每秒.
不过 time()和 sleep()比 Unix 的更好: 时间为浮点数, time()的返回确保最精确 (尽量使用 Unix 的函数 gettimeofday()) ,sleep() 接受的时间为非 0 分数 (尽量用 select() 实现) .
gmtime(), localtime()和 strptime()的返回是包含 9 个整数的序列, 可以作为 asctime(), mktime() and strftime()的输入, 每个域都有自己的属性, 实际上是一个结构体 struct_time, 参见上面的例子.
时间转换: gmtime()把浮点时间转为 UTC 的 struct_time, 反之 calendar.timegm();localtime()把浮点时间转为 local 的 struct_time, 反之 mktime(). 实际上 calendar.timegm()和 mktime()是等效的, 不过前者返回整数, 后者返回浮点数.
时间生成与转换
生成 epoch 的浮点数, 注意不同的系统精度不同, linux 一般是小数点后面 7 为, windows 一般是小数点后 3 位. Time 函数是没有参数的. 可以直接对返回的浮点数进行计算.
gmtime([secs])把浮点时间转为 UTC 的 struct_time, 如果无输入参数为空会调用 time()读取当前时间.
gmtime 显示的是世界协调时间, localtime([secs])可以显示本地时间.
注意夏时制要设置 dst.asctime([t])显示时间为可读性好的格式, 它把 gmtime(), localtime()和 strptime()的返回的 struct_time 类型转换为可读性较好的格式. 如果输入参数为空则调用 localtime()的返回结果. 它和 c 函数不同的地方是末尾不会添加换行. asctime 不会使用 Locale 信息.
ctime([secs])在 asctime 上更进一步, 转换浮点数为可读性较好的格式, 相当于 asctime(localtime(secs)), 这个功能很常用. ctime 不会使用 Locale 信息.
- In [1]: import time
- In [2]: time.gmtime(0)
- Out[2]: 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)
- In [3]: time.gmtime(time.time() + 786041553)
- Out[3]: time.struct_time(tm_year=2043, tm_mon=5, tm_mday=8, tm_hour=6, tm_min=26, tm_sec=50, tm_wday=4, tm_yday=128, tm_isdst=0)
- In [4]: time.time()
- Out[4]: 1528637996.277831
- In [5]: time.gmtime()
- Out[5]: time.struct_time(tm_year=2018, tm_mon=6, tm_mday=10, tm_hour=13, tm_min=42, tm_sec=47, tm_wday=6, tm_yday=161, tm_isdst=0)
- In [6]: time.localtime()
- Out[6]: time.struct_time(tm_year=2018, tm_mon=6, tm_mday=10, tm_hour=21, tm_min=43, tm_sec=54, tm_wday=6, tm_yday=161, tm_isdst=0)
- In [7]: time.asctime()
- Out[7]: 'Sun Jun 10 22:10:14 2018'
- In [8]: time.ctime()
- Out[8]: 'Sun Jun 10 22:12:25 2018'
- Sleep
sleep(secs)暂停执行指定秒数. 参数可以是整数或浮点数. 实际的中止时间可能小于请求时间, 因为例行的信号捕捉可能终止 sleep. 此外中止时间可能长于请求时间, 因为因为系统调度也是需要时间的.
In [36]: time.sleep(3)
处理器时间
clock()在 Unix 上, 返回当前的处理器时间, 为以秒表示的浮点数. 精度决于同名的 C 函数, 通常用于基准 Python 或定时的算法. 我们书写一个不耗 cpu 和耗 cpu 的脚本对比:
- import time
- 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())
- )
执行结果:
- $ python3 time_clock_sleep.py
- Mon Jun 18 01:27:52 2018 - 1529256472.83 - 0.05
- Sleeping 3
- Mon Jun 18 01:27:55 2018 - 1529256475.83 - 0.05
- Sleeping 2
- Mon Jun 18 01:27:57 2018 - 1529256477.83 - 0.05
- Sleeping 1
- Mon Jun 18 01:27:58 2018 - 1529256478.83 - 0.05
- 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.clock()))
- for i in range(300000):
- h.update(data)
- cksum = h.digest()
执行结果:
- $ python3 time_clock.py
- Mon Jun 18 01:31:35 2018 : 1529256695.695 0.048
- Mon Jun 18 01:31:36 2018 : 1529256696.166 0.519
- Mon Jun 18 01:31:36 2018 : 1529256696.635 0.987
- Mon Jun 18 01:31:37 2018 : 1529256697.110 1.461
- Mon Jun 18 01:31:37 2018 : 1529256697.587 1.936
struct_time 类
struct_time 是的命名元组, 结构如下:
| 索引(Index) | 属性(Attribute) | 值(Values) |
| 0 | tm_year(年 | 比如 2013 |
- | 1 | tm_mon(月) | 1 - 12 |
- | 2 | tm_mday(日) | 1 - 31 |
- | 3 | tm_hour(时) | 0 - 23 |
- | 4 | tm_min(分) | 0 - 59 |
- | 5 | tm_sec(秒) | 0 - 61 |
| 6 | tm_wday(weekday | 0 - 6(0 表示周日 |
| 7 | tm_yday(一年中的第几天) | 1 - 366 |
| 8 | tm_isdst(是否是夏令时) | 默认为 - 1 |
- import timedef 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_isdstprint 'gmtime:'show_struct(time.gmtime())print '\nlocaltime:'show_struct(time.localtime())print '\nmktime:', time.mktime(time.localtime())
执行结果:
- $ python3 time_struct.py
- gmtime:
- tm_year : 2018
- tm_mon : 6
- tm_mday : 17
- tm_hour : 17
- tm_min : 32
- tm_sec : 54
- tm_wday : 6
- tm_yday : 168
- tm_isdst: 0
- localtime:
- tm_year : 2018
- tm_mon : 6
- tm_mday : 18
- tm_hour : 1
- tm_min : 32
- tm_sec : 54
- tm_wday : 0
- tm_yday : 169
- tm_isdst: 0
- mktime: 1529256774.0
时区
重置库函数的时间转换规则. 实际上是修改环境变量 TZ,python 2.3 以后类 linux 支持该功能, 这个功能相对不是那么常用. TZ 环境变量的格式如下:
std offset [dst [offset [,start[/time], end[/time]]]]
STD 和 DST 为时区缩写. hh[:mm[:ss]], 表示加上这个时间可以得到 UTC 时间. 偏移量的形式为: HH [ : MM [ : SS] ], 夏时制增加 1 小时.
start http://automationtesting.sinaapp.com/time , end http://automationtesting.sinaapp.com/time 表示使用夏时制的区间. time 和偏移类似, 默认时间是 02:00:00. 比如:
- In [1]: import os
- In [2]: import time
- In [3]: os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0'
- In [4]: time.tzset()
- In [5]: time.strftime('%X %x %Z')
- Out[5]: '13:38:26 06/17/18 EDT'
- In [6]: os.environ['TZ'] = 'AEST-10AEDT-11,M10.5.0,M3.5.0'
- In [7]: time.tzset()
- In [8]: time.strftime('%X %x %Z')
- Out[8]: '03:38:46 06/18/18 AEST'
在许多 Unix 系统(包括 * BSD,Linux 和 Solaris, 和 Darwin), 使用系统时区数据库更方便.
- In [9]: os.environ['TZ'] = 'US/Eastern'
- In [10]: time.tzset()
- In [11]: time.tzname
- Out[11]: ('EST', 'EDT')
- In [12]: os.environ['TZ'] = 'Egypt'
- In [13]: time.tzset()
- In [14]: ('EET', 'EEST')
- Out[14]: ('EET', 'EEST')
另一实例:
- import time
- import os
- def show_zone_info():
- print 'TZ :', os.environ.get('TZ', '(not set)')
- print 'tzname:', time.tzname print 'Zone : %d (%d)' % (time.timezone,
- (time.timezone / 3600))
- print 'DST :', time.daylight print 'Time :', time.ctime()
- printprint 'Default :'show_zone_info()ZONES = [ 'GMT',
- 'Europe/Amsterdam',
- ]for zone in ZONES:
- os.environ['TZ'] = zone
- time.tzset()
- print zone, ':'
- show_zone_info()
执行结果:
- $ python3 time_timezone.py
- Default :
- TZ : (not set)
- tzname: ('CST', 'CST')
- Zone : -28800 (-8.0)
- DST : 0
- Time : Mon Jun 18 01:40:39 2018
- GMT :
- TZ : GMT
- tzname: ('GMT', 'GMT')
- Zone : 0 (0.0)
- DST : 0
- Time : Sun Jun 17 17:40:39 2018
- Europe/Amsterdam :
- TZ : Europe/Amsterdam
- tzname: ('CET', 'CEST')
- Zone : -3600 (-1.0)
- DST : 1
- Time : Sun Jun 17 19:40:39 2018
格式化
time.strftime(format[, t]): 把一个代表时间的元组或者 struct_tim 转为格式化的时间字符串. 如果 t 未指定, 将调用 time.localtime()的返回作为输入. 如果输入中任何一个元素越界将报 ValueError 异常. 格式化参数如下:
| 格式 | 含义 | 备注 |
| %a | 本地简化星期名 | |
| %A | 本地完整星期名 | |
| %b | 本地简化月份名 | |
| %B | 本地完整月份名称 | |
| %c | 本地相应的日期和时间表示 | |
| %d | 日期(01 - 31) | |
| %H | 小时(24 小时制, 00 - 23) | |
| %I | 小时(12 小时制, 01 - 12) | |
| %j | 天数(基于年)(001 - 366) | |
| %m | 月份(01 - 12) | |
| %M | 分钟(00 - 59) | |
| %p | 显示 am 或 pm 的标识 | |
| %S | 秒(01 - 61) | |
| %U | 周数 (基于年)(00 - 53 周日是星期的开始.) 第一个周日之前的所有天数都放在第 0 周. | |
| %w | 星期中的天数(0 - 6,0 是星期天) | |
| %W | 和 %U 基本相同, 以星期一为星期的开始. | |
| %x | 本地相应日期表示 | |
| %X | 本地相应时间表示 | |
| %y | 去掉世纪的年份(00 - 99) | |
| %Y | 完整的年份 | |
| %Z | 时区的名字(如果不存在为空字符) | |
| %% | '%'字符 | |
备注:
"%p" 只有与 "%I" 配合使用才有效果.
秒是 0 - 61, 而不是 59, 以处理闰秒和双闰秒.
当使用 strptime()函数时, 只有当在这年中的周数和天数被确定的时候 %U 和 %W 才会被计算.
比如:
- In [15]: time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
- Out[15]: 'Sun, 17 Jun 2018 17:44:12 +0000'
下面方式在给文件名等添加时间戳比较有用:
- In [17]: time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime())
- Out[17]: '2018-06-17_17:46:18'
显示格式可能因系统而又不同的差异.
time.strptime(string[, format]): 把一个格式化时间字符串转化为 struct_time. 实际上它和 strftime()是逆操作, 参数参见 strftime.Format 默认为 "%a %b %d %H:%M:%S %Y", 和 ctime 的返回格式一致, 没有提供的值会采用默认值(1900, 1, 1, 0, 0, 0, 0, 1, -1).
- In [19]: time.strptime("30 Nov 18", "%d %b %y")
- ...:
- Out[19]: time.struct_time(tm_year=2018, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=334, tm_isdst=-1)
其他
altzone 属性查看当前夏时制时间的偏移. daylight 属性查看是否使用了夏时制. timezone 查看当前时区的偏移. Tzname 返回本地时区和夏时制对应的时区.
- In [3]: time.altzone
- Out[3]: -28800
- In [4]: time.daylight
- Out[4]: 0
- In [5]: time.timezone
- Out[5]: -28800
- In [6]: time.tzname
- Out[6]: ('CST', 'CST')
来源: http://www.jianshu.com/p/5549c833b10d