python 学习笔记 13 -- 常用的时间模块之time

Python 没有包含对应日期和时间的内置类型,不过提供了3个相应的模块,可以采用多种表示管理日期和时间值:

*    time 模块由底层C库提供与时间相关的函数。它包含一些函数用于获取时钟时间和处理器的运行时间,还提供了基本解析和字符串格式化工具  
*    datetime 模块为日期、时间以及日期时间值提供一个更高层接口。datetime 中的类支持算术、比较和时区配置
*    calendar 模块可以创建周、月和年的格式化表示。它还可以用来计算重复事件、给定日期是星期几,以及其他基于日历的值


time - 时钟时间模块。我们使用apihelper.info(可以参考系列前面文章Python 学习笔记 9 -- Python强大的自省简析查看time 类,可以得知time 模块主要有以下方法:


1. time

核心函数,返回值是以浮点数计的自纪元开始以来的秒数,用于比较或者计算还是比较方便。


2. ctime

如果你想打印日期或者时间信息,使用 ctime 要比time 更加方便:

    >>> time.ctime()
    ‘Tue Jul  8 15:26:21 2014‘

我们可以看到 ctime 返回的是可读的可直接用于记录时间的字符串形式时间信息。


我们还可以使用 ctime 来格式化打印一个由 time 计算的时间值
    >>> print "Now time is   :",time.ctime() ;  later = time.time()+15 ;  print "15 secs later :", time.ctime(later)
    结果是:
        Now time is   : Tue Jul  8 15:28:54 2014
        15 secs later : Tue Jul  8 15:29:09 2014

3. clock

处理器时钟,可以用来计算程序使用的实际时间,评估性能。

    >>> print 123456789*123456789/987654, time.clock()      
    15432103500 0.08
    >>> print 123456789*123456789/987654321, time.clock()
    15432098 0.09
    >>> print (123456789*123456789+ 1234567890/987654321)*123456, time.clock()
    1881664346183521084032 0.11

    >>> print (123456789*123456789+ 1234567890/987654321)*123456, time.clock()     # 与上面同样复杂的运算,放在主频比较低的树莓派上运行,cpu 耗时要长很多
    1881664346183521084032 3.49


4. gmtime, localtime 和tzset

先统一介绍一下这几个函数(后面结合实例会了解的更加清楚):

time.gmtime([secs])  --参数为一个以秒表示的时间值,gmtime 函数将参数转化并返回一个 struct_time 结构(见本文最后一节)的时间信息gmtime转化得到的时间是UTC 时间(世界统一时间)。如果没有使用一个秒数作为参数,将会默认使用并转化当前时间(即time.time()), 所以直接使用 time.gmtime() 会得到当前UTC 时间,效果同 time.gmtime(time.time())。

time.localtime([secs])  -- 函数使用以及作用都与gmtime 类似,但是转化的结果是本地时间。也就是说它转化的结果是符合当前设置的时区信息的本地时间。同样,如果没有参数,默认转化的也是当前时间(即time.time()),所以直接使用 time.localtime() 会得到当前的本地时间,效果同 time.localtime(time.time())。

time.tzset()  -- 设置时区从而改变了上面两个函数的时间转化的规则


而对于 时区的选择,我们可以查看参考Linux 的 "/usr/share/zoneinfo/" 目录:

$ ls /usr/share/zoneinfo/
Africa      Australia  Cuba     Etc      GMT0       Iceland      Japan      MST      Poland      right      UCT        zone.tab
America     Brazil     EET      Europe   GMT-0      Indian       Kwajalein  MST7MDT  Portugal    ROC        Universal  Zulu
Antarctica  Canada     Egypt    Factory  GMT+0      Iran         Libya      Navajo   posix       ROK        US
Arctic      CET        Eire     GB       Greenwich  iso3166.tab  localtime  NZ       posixrules  Singapore  UTC
Asia        Chile      EST      GB-Eire  Hongkong   Israel       MET        NZ-CHAT  PRC         SystemV    WET
Atlantic    CST6CDT    EST5EDT  GMT      HST        Jamaica      Mexico     Pacific  PST8PDT     Turkey     W-SU
此外,对于时区的划分以及使用我可能解释不清,而且也不想占用此篇文章的篇幅,想了解的请点这里


你需要理解的是:

UTC 指的是Coordinated Universal Time- 世界协调时间(又称世界标准时间、世界统一时间),是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密。
中国一般使用CST 时间,解释为“China Standard Time UT+8:00” ,即标准的UTC 时间加8


对于时区的设置以及localtime 显示的信息:

    >>> time.gmtime()       # 直接使用,默认转化当前时间time.time()并返回 struct_time 结构的 UTC 时间
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=1, tm_min=56, tm_sec=28, tm_wday=2, tm_yday=190, tm_isdst=0)
    >>> time.localtime()    # 返回当前的本地时间
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=9, tm_min=56, tm_sec=32, tm_wday=2, tm_yday=190, tm_isdst=0)
    >>> os.environ[‘TZ‘] =  ‘Brazil/East‘    # 既然在世界杯期间,不妨设置看看巴西时间
    >>> time.tzset()        # 设置时区
    >>> time.gmtime()       # 我们可以看到设置时区后对UTC 时间并无干扰
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=1, tm_min=57, tm_sec=42, tm_wday=2, tm_yday=190, tm_isdst=0)
    >>> time.localtime()    # 本地时间已经显示的不同了,因为当前输出的是巴西时间
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=8, tm_hour=22, tm_min=57, tm_sec=49, tm_wday=1, tm_yday=189, tm_isdst=0)
    >>> os.environ[‘TZ‘] =  ‘Asia/Shanghai‘     #重新设置时区为上海(好像没有北京时间,安装Linux 时小伙伴应该都注意过这个问题。),回到北京时间
    >>> time.tzset()
    >>> time.gmtime()
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=1, tm_min=58, tm_sec=7, tm_wday=2, tm_yday=190, tm_isdst=0)
    >>> time.localtime()
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=9, tm_min=58, tm_sec=10, tm_wday=2, tm_yday=190, tm_isdst=0)
    >>> time.tzname         # 中国的时区名为 CST,理解为“China Standard Time UT+8:00”
    (‘CST‘, ‘CST‘)


5. strptime 和 strftime

这两个函数用来解析和格式化输出时间。用作字符串格式的时间与 struct_time 结构的时间之间的转化。


对于上面的localtime ,我们可以看到输出结果是一个 struct_time 结构体并以元组格式打印,我们可以使用" time.localtime().tm_year " 这样单独取其中一项

所以我们打印日期时可以这样:

>>> print "%s-%s-%s" % (time.localtime().tm_year, time.localtime().tm_mon, time.localtime().tm_mday)
2014-7-8

而ctime 输出的结果是字符串形式, 对于这种的我们可以使用这两个函数来解析/格式化:


strftime 用于将元组转化为字符串, 它将指定的struct_time(默认为当前时间),根据指定的格式化字符串输出。
    >>> time.localtime()    # 我们可以知道,localtime 打印的结果是元组形式的时间结构体

    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=8, tm_hour=16, tm_min=13, tm_sec=9, tm_wday=1, tm_yday=189, tm_isdst=0)

    >>> time.strftime(‘%Y-%m-%d %H:%M:%S‘, time.localtime())    # 使用格式化打印,我们可以看到比上面使用元组项要方便很多

    ‘2014-07-08 16:13:10‘


strptime 用于将字符串格式的格式化为元组
    >>> time.ctime()
    ‘Tue Jul  8 16:16:32 2014‘
    >>> time.strptime(time.ctime())
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=8, tm_hour=16, tm_min=16, tm_sec=45, tm_wday=1, tm_yday=189, tm_isdst=-1)
    >>> time.strftime( ‘%Y-%m-%d %H:%M:%S‘, time.strptime(time.ctime())       # 格式化之后我们再使用strftime 格式化打印成我们想要的格式就很方便了!!!
    ‘2014-07-08 16:17:29‘


time.strftime 的使用格式为:
        strftime(format[, tuple])
里面有很多参数,可以让你能够更随意的输出自己想要的东西
        %y 两位数的年份表示(00-99)
        %Y 四位数的年份表示(000-9999)
        %m 月份(01-12)
        %d 月内中的一天(0-31)
        %H 24小时制小时数(0-23)
        %I 12小时制小时数(01-12)
        %M 分钟数(00=59)
        %S 秒(00-59)
        
        %a 本地简化星期名称
        %A 本地完整星期名称
        %b 本地简化的月份名称
        %B 本地完整的月份名称
        %c 本地相应的日期表示和时间表示
        %j 年内的一天(001-366)
        %p 本地A.M.或P.M.的等价符
        %U 一年中的星期数(00-53)星期天为星期的开始
        %w 星期(0-6),星期天为星期的开始
        %W 一年中的星期数(00-53)星期一为星期的开始
        %x 本地相应的日期表示
        %X 本地相应的时间表示
        %Z 当前时区的名称
        %% %号本身


6. sleep

休眠函数, 任何语言中基本上都会有休眠函数,而python 中对应的就是 time.sleep(n)。携带的参数指定挂起执行程序的秒数。

为了更精确休眠的时间参数可以是一个浮点数。实际的挂起时间可能小于请求的数,因为捕获其他信号会终止休眠并执行信号对应的捕获程序。挂起时间也有可能比要求的更长,因为可能会调度系统中的其他活动。


7. mktime

这是 localtime 的逆函数。它的参数是 struct_time 结构或者完整的9 元素的元组(如果使用元组,需要dst 标识,如果不知可以使用-1)。为了兼容time(),它会返回一个浮点数。如果参数不能被表示为一个有效的时间,会引发OverflowError 或者 ValueError错误。
    >>> t = time.time()
    >>> t
    1404867269.117389
    >>> time.localtime(t)   # 上面已说过,使用time.localtime 可以将time() 生成的浮点数转化为 struct_time 结构
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=8, tm_min=54, tm_sec=29, tm_wday=2, tm_yday=190, tm_isdst=0)
    >>> time.mktime(time.localtime(t))
    1404867269.0            # 我们可以看到time.mktime 将 struct_time 结构再次还原为浮点数,其中因为 struct_time 结构中最小值为 tm_sec,也就是说最小时间精度为秒。所以使用 mktime 得到的浮点数中,秒以下的数(毫秒,微秒)被抹去

    >>> time.mktime( (2014, 7, 9, 8, 54, 29, 2, 190, -1) )    # 使用上面结构体中的数(dst使用-1表示未知)组成的9元素的元组,mktime 能够还原出同样的值
    1404867269.0


8. struct_time 结构

最后介绍一下 time.struct_time 类:
    time 的gmtime(), localtime(), 以及 strptime()方法获取的时间值类型是一个struct_time 类它是一个命名的元组对象:元素可以通过index获取,或者是通过属性名称

    >>> time.localtime()
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=8, tm_hour=22, tm_min=9, tm_sec=1, tm_wday=1, tm_yday=189, tm_isdst=0)
    >>> time.localtime()[1]
    7
    >>> time.localtime().tm_mon
    7

    目前这个结构中有以下元素:


time.struct_time 结构
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](下注
6 tm_wday range [0, 6], Monday is 0
7 tm_yday range [1, 366]
8 tm_isdst 0, 1 or -1; see below












  

如果在函数中使用该元组时使用了错误的长度或者使用错误的类型,会引发TypeError 错误。

注:

上面表中,tm_sec 中的取值范围为 0~61, 这并不是写错了!是考虑了闰秒和双闰秒的因素(非常少见)。(关于闰秒,英文leap seconds,这是来自百度百科的解释: 闰秒是指为保持协调世界时接近于世界时时刻,由国际计量局统一规定在年底或年中对协调世界时增加或减少1秒>的调整。由于地球自转的不均匀性和长期变慢性,会使世界时(民用时)和原子时之间相差超过到±0.9秒时,就把世界时向前拨1秒(负闰秒,最后一分钟为59秒)或向后拨1秒(正闰秒,最后一分钟为61秒))

与C 结构不同,月对应的值范围是1~12,而不是0~11。

年的值需要注意以下问题:Python 依赖于平台的C 库,C 库一般是没有2000年的问题的,因为所有的日期和时间都内在的代表自时代以来的秒。函数接收上面一个struct_time 结构,其中需要4位来表示年。为了向后兼容,如果模块变量accept2dyear 是一个非零整数,支持使用2位来表示年;而这个变量会被初始化为1,除非环境变量PYTHONY2K 被设置为一个非空的字符串,之后PYTHONY2K 被设置时变量 accept2dyear 才会被初始化为0。
因此,你可以将PYTHONY2K 设置为一个非空字符串从而使得python 对于任何年的输入都使用4位来表示。否则,如果使用的是2位表示年,将会根据POSIX 或者X/Open 标准来转换:69~99 被映射为1969~1999,而0~68 被映射为2000~2068。(此问题在Python的 time模块介绍中标记为“Year 2000 (Y2K) issues” )



=======================================

注:本文只介绍了 time 模块,其他的时间模块还有 datetime 和calendar 迫于篇幅限制(排版过于繁琐),以及电脑配置限制(AMD速龙+2G内存,即使跑的Linux太长的文章上下翻动感觉页很卡)将于本系列下面两篇介绍。

更多关于 time 模块的相关内容请参考Python 官方文档

=======================================

注: 转载注明出处: http://blog.csdn.net/longerzone

python 学习笔记 13 -- 常用的时间模块之time,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。