• 5.Python3标准库-日期和时间


    1
    2
    3
    4
    5
    6
    7
    8
    9
    '''
    不同于int,str,float,Python没有包含对应日期和时间的原生类型,不过提供了3个相应的模块,可以采用多种表示来管理日期和时间值
     
    time模块由底层C库提供与时间相关的函数。它包含一些函数,可以用于获取时钟时间和处理器运行时间,还提供了基本的解析和字符串格式化工具
     
    datetime模块为日期、时间以及日期时间值提供了一个更高层接口。datetime中的类支持算术、比较和时区配置
     
    calendar模块可以创建周、月、年的格式化表示。它还可以用来计算重复事件,给定日期的话是星期几,以及其他基于日历的值
    '''

      

    (一)time:时钟时间

    1
    2
    3
    4
    5
    '''
    time模块允许访问多种类型的时钟,分别用于不同的用途。
    标准系统调用(如time())会报告系统"墙上时钟"时间。monotonic()时钟可以用于测量一个长时间运行的进程的耗用时间,因为即使系统时间有改变,也能保证这个时间不会逆转。
    以及其他的功能我们慢慢介绍
    '''

      

    1.比较时钟

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    import time
    import textwrap
     
     
    '''
    时钟的实现细节因平台而异。可以使用get_clock_info()获得当前实现的基本信息,包括时钟的分辨率
    '''
    available_clocks = [
        ("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_clocks:
        info = time.get_clock_info(clock_name)
     
        print(textwrap.dedent(f'''
            {clock_name}:
                adjustable:     {info.adjustable}
                implementation: {info.implementation}
                monotonic:      {info.monotonic}
                resolution:     {info.resolution}
                current:        {func()}   
        '''))
     
     
    '''
    clock:
        adjustable:     False
        implementation: QueryPerformanceCounter()
        monotonic:      True
        resolution:     4.109233282817159e-07
        current:        0.239568711   
     
     
    monotonic:
        adjustable:     False
        implementation: GetTickCount64()
        monotonic:      True
        resolution:     0.015600099999999999
        current:        20896.24   
     
     
    perf_counter:
        adjustable:     False
        implementation: QueryPerformanceCounter()
        monotonic:      True
        resolution:     4.109233282817159e-07
        current:        0.239739244   
     
     
    process_time:
        adjustable:     False
        implementation: GetProcessTimes()
        monotonic:      True
        resolution:     1e-07
        current:        0.2808018   
     
     
    time:
        adjustable:     True
        implementation: GetSystemTimeAsFileTime()
        monotonic:      False
        resolution:     0.015600099999999999
        current:        1552032134.9916494  
    '''

      

    2.墙上时钟时间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import time
     
     
    '''
    time模块的核心函数之一是time(),它会把从"纪元"开始以来的秒数作为一个浮点值返回
    '''
    print("the time is:", time.time())  # the time is: 1552033201.089945
    '''
    纪元是时间测量的起点,对于Unix平台系统这个起点时间就是1970年1月1日0点0分0秒。
    time.time()得到结果就是当前时间相对于起点过了多少秒。这个值是一个浮点数,具体的精度依赖于具体的平台
    '''
     
    # 浮点数表示对于存储或比较日期很有用,但是对于生成人类可读的表示就有些差强人意了。要记录或打印时间,ctime()或许是更好的选择。
    print("the time is:", time.ctime())  # the time is: Fri Mar  8 17:22:59 2019
    later = time.time() + 15
    # time.ctime可以接收一个时间戳,不传参数的话,默认是当前的时间戳
    print("15 secs from now:", time.ctime(later))  # 15 secs from now: Fri Mar  8 17:23:14 2019

      

    3.单调时钟

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import time
     
     
    '''
    由于time()查看系统时钟,并且用户或系统服务可能改变系统时钟来同步多个计算机上的时钟,所以反复调用time()所产生的的值可能向前或向后。
    试图测量持续时间或者使用这些时间来完成计算时,这可能会导致意想不到的行为。为了避免这些情况,可以使用monotonic,它总是返回向前的值。
    '''
    start = time.monotonic()
    time.sleep(0.1)
    end = time.monotonic()
     
    print(f"start: {start:>9.2f}")  # start:  27083.08
    print(f"end  : {end:>9.2f}")  # end  :  27083.18
    print(f"span : {end-start:>9.2f}")  # span :      0.1
    '''
    单调时钟的起始点没有被定义,所以返回值只是在与其他时钟值完成计算时完成计算时有用。
    在这个例子中,使用monotonic来测量睡眠持续时间
    '''

      

    4.处理器时钟时间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import time
    import hashlib
     
     
    '''
    time()返回的是一个墙上的时钟时间,而clock()返回处理器时钟时间。
    clock()返回的值反映了程序运行时使用的实际时间
    '''
    # 但是不推荐这个方法为什么呢?
    '''
    DeprecationWarning: time.clock has been deprecated in Python 3.3
                        and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
    '''
    # 所以这个就跳过了

      

    5.性能计数器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    import time
    import hashlib
     
     
    '''
    在测量性能时,高分辨率时钟是必不可少的。
    要确定最好的时钟数据源,需要有平台特定的知识,Python通过perf_counter()来提供所需的这些知识
    '''
     
     
    data = open(__file__, "rb").read()
    loop_start = time.perf_counter()
     
     
    for in range(5):
        iter_start = time.perf_counter()
        = hashlib.sha1()
        for in range(100000):
            h.update(data)
        cksum = h.hexdigest()
        now = time.perf_counter()
        # 叠加计算循环时间
        loop_elapsed = now - loop_start
        # 计算每一次的循环时间
        iter_elapsed = now - iter_start
        print(f"{time.time(): .3f} : {iter_elapsed: .3f} : {loop_elapsed: .3f}")
    '''
     1552040433.357 :  0.269 :  0.269
     1552040433.632 :  0.275 :  0.543
     1552040433.901 :  0.269 :  0.812
     1552040434.172 :  0.271 :  1.083
     1552040434.495 :  0.323 :  1.407
    '''
    # 类似于monotonic,perf_counter的纪元未定义,所以返回值只用于比较和计算值,而不作为绝对时间

      

    6.时间组成

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    import time
     
     
    '''
    有些情况下需要把时间存储为过去了多少秒(秒数),但是另外一些情况下,程序需要访问一个时期的各个字段(例如,年月日)。
    time模块定义了struct_time来保存日期和时间值,其中分解了各个组成部分以便于访问。
    很多函数都要处理struct_time值而不是浮点值
    '''
    print(time.gmtime())
    # time.struct_time(tm_year=2019, tm_mon=3, tm_mday=8, tm_hour=10, tm_min=27, tm_sec=29, tm_wday=4, tm_yday=67, tm_isdst=0)
     
    print(time.localtime())
    # time.struct_time(tm_year=2019, tm_mon=3, tm_mday=8, tm_hour=18, tm_min=27, tm_sec=53, tm_wday=4, tm_yday=67, tm_isdst=0)
     
    print(time.mktime(time.gmtime()))  # 1552012197.0
    '''
    gmtime函数以UTC格式返回当前时间。localtime会返回应用了当前的时区的系统时间,mktime取一个time_struct实例,返回时间戳
    '''
     
     
    def show_struct(s: time.struct_time):
        print(f"年:", s.tm_year)
        print(f"月:", s.tm_mon)
        print(f"日:", s.tm_mday)
        print(f"时:", s.tm_hour)
        print(f"分:", s.tm_min)
        print(f"秒:", s.tm_sec)
        print(f"这一周的第几天,从0开始,0是周一:", s.tm_wday)
        print(f"这一年的第几天:", s.tm_yday)
        print(f"是否时夏令时的旗帜:", s.tm_isdst)
     
     
    show_struct(time.localtime())
    '''
    年: 2019
    月: 3
    日: 8
    时: 18
    分: 36
    秒: 4
    这一周的第几天,从0开始,0是周一: 4
    这一年的第几天: 67
    是否时夏令时的旗帜: 0
    '''
     
    # 此外我再补充一下gmtime和localtime,这个和ctime一样。可以接收一个时间戳,如果不传参,那么默认是当前系统的时间戳
    print(time.localtime(1))
    # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=1, tm_wday=3, tm_yday=1, tm_isdst=0)
    '''
    相当于从纪元过了1秒钟
    '''

      

    7.处理时区

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    import time
    import os
     
     
    '''
    用于确定当前时间的函数有一个前提,即已经设置了时区,其可以由程序设置,也可以使用系统的默认时区。
    修改时区不会改变具体的时间,只会改变时间的方式。
     
    要改变时区,需要设置环境变量tz,然后调用tzset()。设置时区时可以指定很多细节,甚至细致到夏令时的开始和结束时间。
    不过通常更容易的做法是使用时区名,由底层库推导出其他信息。
    '''
     
     
    def show_zone_info():
        print("TZ:", os.environ.get("TZ""not set"))
        print("tzname:", time.tzname)
        print("Zone:", time.timezone, time.timezone/3600)
        print("DST:", time.daylight)
        print("Time:", time.ctime())
        print("-"*20)
     
     
    print("Default")
    show_zone_info()
     
    ZONES = ["GMT""Europe/Amsterdam"]
    for zone in ZONES:
        # 这两行代码是为了让我们改变时区的,先设置环境变量TZ,然后调用time.tzset()
        os.environ["TZ"= zone
        time.tzset()  # 此方法不适用于Windows
        print("zone:")
        show_zone_info()

      

    8.解析和格式化时间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import time
     
     
    '''
    函数strptime和strftime可以在时间值的struct_time表示和字符串表示之间进行转换。
    这两个函数支持大量格式化指令,允许不同方式的输入和输出
    '''
    # 接收一个字符串格式的日期,和以及格式化的参数,得到struct_time
    parsed = time.strptime("2018-5-12 16:14:25""%Y-%m-%d %H:%M:%S")  # %H-%M-%S也可以写成%X
    print(parsed)  # time.struct_time(tm_year=2018, tm_mon=5, tm_mday=12, tm_hour=16, tm_min=14, tm_sec=25, tm_wday=5, tm_yday=132, tm_isdst=-1)
     
    # 传入一个格式化的参数,和一个struct_time,得到一个字符串格式的日期
    print(time.strftime("%m-%d-%Y %X", parsed))  # 05-12-2018 16:14:25
     
    # strptime:将字符串格式的日期转为struct_time
    # strftime:将struct_time转为字符串格式的日期

      

    (二)datetime:日期和时间值管理

    1
    2
    3
    '''
    datetime包含一些函数和类,用于完成日期和时间的解析、格式化和算术运算
    '''

      

    1.时间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import datetime
    '''
    时间值可以用time表示。time实例包含hour,minute,second和microsecond属性,还可以包含时区信息。
    '''
     
     
    = datetime.time(123)
    print(f"hour: {t.hour}")  # hour: 1
    print(f"minute: {t.minute}")  # minute: 2
    print(f"second: {t.second}")  # second: 3
    print(f"microsecond: {t.microsecond}")  # microsecond: 0
    print(f"tzinfo: {t.tzinfo}")  # tzinfo: None
    # time实例只包含时间值,而不包含和时间值关联的日期值
     
    print(f"earliest: {datetime.time.min}")  # earliest: 00:00:00
    print(f"latest: {datetime.time.max}")  # latest: 23:59:59.999999
    print(f"resolution: {datetime.time.resolution}")  # resolution: 0:00:00.000001

      

    2.日期

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import datetime
    '''
    日期日历值用date类表示。date实例包含year,month,day等属性。使用date()类方法很容易创建一个表示当前日期的日期实例
    '''
    today = datetime.datetime.today()
    print(today)  # 2019-03-18 17:07:53.787871
    print(f"ctime: {today.ctime()}")  # ctime: Mon Mar 18 17:07:53 2019
    # 得到的是一个时间元组
    print(today.timetuple())  # time.struct_time(tm_year=2019, tm_mon=3, tm_mday=18, tm_hour=17, tm_min=7, tm_sec=53, tm_wday=0, tm_yday=77, tm_isdst=-1)
    print(f"original: {today.toordinal()}")  # original: 737136
    print(f"year: {today.year}")  # year: 2019
    print(f"month: {today.month}")  # month: 3
    print(f"day: {today.day}")  # day: 18
     
     
    # 创建指定年月的日期,如果不包含时分秒,那么可以使用date函数。
    # 包含时分秒使用datetime函数
    print(datetime.date(20181112))  # 2018-11-12
    print(datetime.datetime(20181112))  # 2018-11-12 00:00:00
    print(datetime.datetime(201811122312))  # 2018-11-12 23:12:00
     
    # 还可以对date进行替换
    = datetime.date(20181115)
    print(d.replace(year=1999))  # 1999-11-15
    print(d.replace(year=1999, month=5))  # 1999-05-15

      

    3.日期的运算和比较

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import datetime
    '''
    先来介绍一下时间间隔,timedelta,顾名思义就是隔了多长时间
    可以对两个timedelta进行算术运算,也可以结合datetime和timedelta得到一个新的datetime
    '''
    = datetime.date(20181211)
    delta1 = datetime.timedelta(days=1)
    print(f"next_day: {d+delta1}")  # next_day: 2018-12-12
    delta2 = datetime.timedelta(weeks=1)
    print(f"next_week: {d+delta2}")  # next_week: 2018-12-18
    delta3 = datetime.timedelta(days=-1)
    print(f"last_day: {d+delta3}")  # last_day: 2018-12-10
    '''
    timedelta支持的参数如下:
        days, seconds, microseconds, milliseconds, minutes, hours, weeks
    '''
     
     
    # 日期也可以进行比较
    d1 = datetime.date(2018121)
    d2 = datetime.date(2018819)
    print(d1 > d2)  # True
     
     
    # 日期也可以进行运算
    print(d1-d2)  # 104 days, 0:00:00
    print((d1-d2).days)  # 104

      

    4.结合日期和时间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    import datetime
    '''
    使用datetime类可以存储由日期和时间分量构成的值。
    date只是包含年月日
    datetime则是年月日时分秒
    '''
    print(f"Now: {datetime.datetime.now()}")  # Now: 2019-03-18 17:33:57.287297
    print(f"Today: {datetime.datetime.today()}")  # Today: 2019-03-18 17:33:57.287297
    # 由于咱们在东八区,所以差了八个小时
    print(f"UTC Now: {datetime.datetime.utcnow()}")  # UTC Now: 2019-03-18 09:33:57.287297
     
     
    = datetime.datetime.now()
    print(d.month)  # 3
    print(d.year)  # 2019
    print(d.day)  # 18
    print(d.hour)  # 17
    print(d.minute)  # 33
    print(d.second)  # 57
     
     
    # 此外还可以通过combine方法创建datetime实例
    = datetime.time(123)
    = datetime.date(20111211)
    print(datetime.datetime.combine(d, t))  # 2011-12-11 01:02:03
     
     
    # 或者通过时间戳来创建
    import time
    = time.time() + 1000000
    print(datetime.datetime.fromtimestamp(t))  # 2019-03-30 07:23:53.256506
    # 当然通过时间戳的话,date也是可以的
    print(datetime.date.fromtimestamp(t))  # 2019-03-30

      

    5.格式化和解析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import datetime
    '''
    datetime模块和time模块一样也提供了strptime和strftime函数来对字符串和datetime对象进行解析
    '''
     
    now = datetime.datetime.now()
    print(now)  # 2019-03-18 17:44:06.537144
    # 可以使用datetime实例对象调用,当然也可以使用datetime.datetime.strftime(now, format)方法
    = now.strftime("%Y-%m-%d ----  %X")
    print(type(s))  # <class 'str'>
    print(s)  # 2019-03-18 ----  17:44:06
     
    # 此外还可以将字符串格式的日期转换成datetime对象
    = "2018-12-11 14:25:25"
    = datetime.datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
    print(type(d))  # <class 'datetime.datetime'>
    print(d)  # 2018-12-11 14:25:25
     
     
    '''
    time.strftime: 传入format和struct_time,得到format格式的字符串
    datetime.datetime.strftime:传入datetime对象和format,得到format格式的字符串。此外这个方法也可以使用实例去调用
     
    time.strptime:传入日期格式的字符串和format,得到struct_time
    datetime.datetime.strptime:传入日期格式的字符串和format,得到datetime对象
    '''

      

    6.时区

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import datetime
    '''
    关于设置时区,不推荐datetime模块。可以使用一个第三方模块叫pytz
    '''
    import pytz
    # 可以看到全部的时区有591个
    print(len(pytz.all_timezones))  # 591
    # 可以看到中国的时区有两个,分别是上海和乌鲁木齐
    print(pytz.country_timezones("cn"))  # ['Asia/Shanghai', 'Asia/Urumqi']
     
    print(datetime.datetime.now())  # 2019-03-18 18:10:45.735613
    # 设置时区
    tz = pytz.timezone("Asia/Shanghai")
    print(datetime.datetime.now(tz=tz))  # 2019-03-18 18:10:45.736613+08:00
    tz = pytz.timezone("Asia/Urumqi")
    print(datetime.datetime.now(tz=tz))  # 2019-03-18 16:09:35.343587+06:00
    '''
    可以看到我所处的时区时Asia/Shanghai,所以设置不设置是一样的,
    然而当我设置为乌鲁木齐的时候,会发现早了两个小时。说明当我们这里十二点的时候,乌鲁木齐那里是十点
    '''

      

    (三)calendar:处理日期

    1
    2
    3
    4
    5
    import calendar
    '''
    calendar模块定义了Calendar类,其中封装了一些值的计算,如给定的一个月或一年中的周日期。
    另外,TextCalendar和HTMLCalendar类可以生成经过预格式化的输出
    '''
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    import calendar
    '''
    prmonth方法是一个简单的函数,可以生成月的格式化文本输出
    '''
    = calendar.TextCalendar()
    c.prmonth(20177)
    '''
         July 2017
    Mo Tu We Th Fr Sa Su
                    1  2
     3  4  5  6  7  8  9
    10 11 12 13 14 15 16
    17 18 19 20 21 22 23
    24 25 26 27 28 29 30
    31
    '''
     
    # 如果想按照美国的方式,将TextCalendar配置为一周从星期日开始的话,怎么做呢?
    # 只需要加上一个参数即可,当然也可以指定其它,比如星期五,星期六什么的
    calendar.TextCalendar(calendar.SUNDAY).prmonth(20177)
    '''
         July 2017
    Su Mo Tu We Th Fr Sa
                       1
     2  3  4  5  6  7  8
     9 10 11 12 13 14 15
    16 17 18 19 20 21 22
    23 24 25 26 27 28 29
    30 31
    '''
     
    # 此外还有更简单的方法,直接调用模块下的month方法,输入年和月,但需要加上print
    print(calendar.month(20177))
    '''
         July 2017
    Mo Tu We Th Fr Sa Su
                    1  2
     3  4  5  6  7  8  9
    10 11 12 13 14 15 16
    17 18 19 20 21 22 23
    24 25 26 27 28 29 30
    31
    '''

      

  • 相关阅读:
    Day 15 模块
    Day 14 三元运算符,列表推导式,内置函数
    Day 13 可迭代对象,迭代器对象,for循环迭代,生成器对象,枚举对象
    Day 12 开放封闭原则,装饰器初识
    Day 11 函数对象,函数嵌套,作用域,闭包
    Day 10 函数的形参,实参
    Day 09 函数基础
    Day 08 文件操作模式,文件复制,游标
    HTTP协议
    11,.JS-DOM价绍
  • 原文地址:https://www.cnblogs.com/valorchang/p/11395743.html
Copyright © 2020-2023  润新知