常用语言的时间模块

在相当长的时间里面,与时间相关的库我总是很不熟练,每次用到总要卡一下,慢慢Google,这次索性直接记下来,这样下次遇到我就可以查自己的博客而不是Google了(反正我是不会记在脑子里面的是吧~)。

Python

Python表示时间可以用float格式的时间戳、time.struct_time和字符串三种表示。

  1. struct_time
    time.struct_time是一个构造struct_time

    time.struct_time(tm_year=2016, tm_mon=4, tm_mday=7, tm_hour=10, tm_min=3, tm_sec=27, tm_wday=3, tm_yday=98, tm_isdst=0)
    
  2. 时间戳
    时间戳是以秒为单位的浮点

时间格式的转换

struct_time是Python中最灵活的表现时间的方式,它是一个不包含时区信息的struct。

  1. 字符串和time.struct_time
    注意,借助于time模块不能Parse秒后面跟着毫秒的情况

    1
    2
    ts = time.strptime("2020-12-12T11:11:11Z", "%Y-%m-%dT%H:%M:%SZ")
    time.strftime("%Y-%m-%dT%H:%M:%S.%fZ", ts)
  2. struct_time和时间戳

    1
    2
    time.mktime(ts)
    time.localtime(time.time())

    如果我们知道自己的localtime是东八区,那么想知道日本当前的时间,就是

    1
    time.localtime(time.time()+60*60)

    如果需要得到当前的utc时间,需要借助于datetime模块,同样返回一个struct_time

    1
    datetime.datetime.utcfromtimestamp(time.time())

    也可以通过下面的方法实现

    1
    time.gmtime(time.time())

    那么如果我们对localtime不信任,要得到一个东八区的struct_time就可以如下操作

    1
    time.gmtime(time.time()+60*60*8)

datetime

datetime模块是基于datetime.datetime类来实现的

  1. 时间戳和datetime

    1
    2
    tz = pytz.timezone('Asia/Shanghai')
    datetime.datetime.fromtimestamp(int(time.time()), tz)

    转换回来没有对应函数,但可以算出来

    1
    2
    t = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
    t = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)
  2. datatime和struct_time
    可以直接获取

    1
    dt.timetuple()

    也可以借助于时间戳中转

    1
    dt = datetime.datetime.fromtimestamp(time.mktime(ts))

    还有一种骚的方法

    1
    2
    st = time.localtime()
    dt = datetime.datetime(*st[:6])

常用需求

  1. 解析一个时间戳,并进行变换
    由于有些场景用UTC时间戳来表示一个东八区时间,所以需要对时间计算偏移,例如回答X小时后的时间是多少的问题。

    1
    2
    datetime.datetime.now() + datetime.timedelta(days=-1)
    datetime.datetime.now() + datetime.timedelta(hours=8)
  2. 比较两个时间
    获得两个时间差,其中seconds是时间差除开days之外的秒数,而total_seconds()是总秒数,如果需要知道两个时间之间差了多少秒,应该用后者

    1
    2
    3
    4
    time_delta = (datetime.datetime(2020,1,1,0,0,0) - datetime.datetime(2020,1,1,1,0,0))
    time_delta.days # -1
    time_delta.seconds # 82800 # 可以看到seconds必须要和days拼起来看,不然就不准
    time_delta.total_seconds() # -3600