详解Python获取时间和计时器

Last Updated: 2023-05-28 07:41:36 Sunday

-- TOC --

本文总结一些在python中常用的与时间计算有关的知识点。

获取毫秒微秒纳秒

虽然秒已经够短的了,但是人类操作键盘鼠标的时间间隔却是在毫秒级(millisecond)。有的时候为了应用的需要,需要使用毫秒级的时间,甚至微秒。

获取毫秒

在Python中获取毫秒时间,基本思路就是转换time.time()函数返回的时间浮点数,来获取当前毫秒时间。代码如下:

import time

def getMS():
    """get millisecond of now in string of length 3"""
    a = str(int(time.time()*1000)%1000)
    if len(a) == 1: return '00'+a
    if len(a) == 2: return '0'+a
    return a

def getTime():
    """get time in format HH:MM:SS:MS"""
    now = time.strftime('%H:%M:%S', time.localtime())
    return now+':'+getMS()

先import time模块。getMS函数的返回值,就是一个长度为3的毫秒时间字符串,getTime函数将这个毫秒时间与小时分钟秒合并成一个用冒号(:)分割的时间字符串。拿走不谢!

获取微秒

获取毫秒的思路与获取毫秒是一样的,代码如下:

>>> int(time.time()*1000*1000)%1000
555
>>> int(time.time()*1000*1000)%1000
612
>>> int(time.time()*1000*1000)%1000
495
>>> int(time.time()*1000*1000)%1000
396

秒,毫秒,微秒相互之间都是10^3的关系,以上代码将时间转换成微秒代码,然后用1000去取余,就得到了当前时间的微秒值。这段代码得到的是int,请按自己需要转换成string。

获取纳秒

从python3.7开始,time模块多了一个直接得到从epoch开始的纳秒数,time.time_ns()函数:

>>> time.time_ns()
1580637675389882900
>>> time.time_ns()
1580637675666898800
>>> time.time_ns()
1580637675939914400
>>> time.time_ns()
1580637676217930300

观察上面的函数返回值,我们发现了一个细节,time.time_ns()函数得到的纳秒数,最后两位总是0!这应该时更底层的系统调用返回造成的,我后来再另一个系统上测试,就不是这样了:

>>> time.time_ns()
1685252290614100384
>>> time.time_ns()
1685252291072464503
>>> time.time_ns()
1685252291541300850
>>> time.time_ns()
1685252291999035920

自制接口

下面是我自己积累的一组时间计算函数接口,放入工具箱里,随用随取:

def getMilliS():
    """Return millisecond of now in string of length 3."""
    a = str(int(time.time()*1000)%1000)
    return a.rjust(3, '0')


def getTime():
    """Return time in format of HH:MM:SS.MS. len(MS)=3."""
    now = time.strftime('%H:%M:%S', time.localtime())
    return now + '.' + getMilliS()


def getDate():
    """Return date of today in ISO format YYYY-MM-DD."""
    return datetime.date.today().isoformat()


def getDateTime():
    """Return datetime of now in format YYYY-MM-DD HH:MM:SS.MS. len(MS)=3."""
    return getDate() + ' ' + getTime()


def valid_date(dateStr):
    """Determine if dateStr (YYYY-MM-DD) is valid."""
    datetime.date.fromisoformat(dateStr)


def getYMD(dateStr=None):
    """Return year, month, day tuple of now or from dataStr, in str type."""
    if dateStr:
        valid_date(dateStr)
    else:
        dateStr = getDate()
    return dateStr[:4], dateStr[5:7], dateStr[8:]

Python计时器

在python time模块中,有好几组不同的计时器。

time.timetime.time_ns

这可能是我们最常用的time模块的接口。

time.time函数返回系统UNIX时间,time.time_ns以纳秒的形式返回系统UNIX时间。

>>> import time
>>> time.time()
1591235079.9658196
>>> time.time()
1591235083.2702475
>>> time.time_ns()
1591235087053414000
>>> time.time_ns()
1591235089100793500

什么是UNIX时间戳?什么是epoch?

UNIX系统,以及现在Linux系统,有一个约定俗成的关于时间的定义,就是UNIX时间戳。这个时间戳的开始时点是:1970-01-01 00:00:00 UTC。很多文献中使用since epoch,即表示从1970-01-01 00:00:00这个时候开始的秒数,不考虑润秒。

Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。Unix时间戳不仅被使用在Unix系统、类Unix系统中,也在许多其他操作系统中被广泛采用。

计算时间间隔,不应该使用time.time()这个时间,要规避系统时间调整带来的问题!

time.monotonictime.monotonic_ns

monotonic时间是指系统启动后从0开始递增的时间,它不会因为我们调整系统时间而发生回调这种情况。

>>> time.monotonic()
13711.17540948
>>> time.monotonic()
13712.234018621
>>> time.monotonic_ns()
13717008028282
>>> time.monotonic_ns()
13719255652629

什么是monotonic time?

从字面上来看,monotonic time就是单调递增的时间。monotonic time从系统启动开始计时,从0开始,单调递增。系统时间不是从0开始,而且,有可能因为时间错了而回调。

在一些系统调用中,需要指定时间是用CLOCK_MONOTONIC还是CLOCK_REALTIME,CLOCK_MONOTONIC是monotonic time,而CLOCK_REALTIME是wall time。monotonic time字面意思是单调时间,实际上它指的是系统启动以后流逝的时间,这是由变量jiffies来记录的。系统每次启动时jiffies初始化为0,每来一个timer interrupt,jiffies加1,也就是说它代表系统启动后流逝的tick数。jiffies一定是单调递增的,因为时间不可逆!

time.perf_countertime.perf_counter_ns

这个计时器记录的是python解释器启动后经过的时间。timeit模块默认就是使用这个计时器来计算性能。

C:\Users\xinli>python
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.perf_counter()
5.8445583
>>> time.perf_counter()
8.9713227
>>> time.perf_counter()
11.7148052
>>> time.perf_counter_ns()
14650963900
>>> time.perf_counter_ns()
16739663700

这个时间就是wall clock,只是从Python解释器启动时开始tick。

time.process_timetime.process_time_ns

CPU time,包括了内核态和用户态。(类似C语言中的clock(),仅在Linux下。)

time.thread_timetime.thread_time_ns

本文链接:https://cs.pynote.net/sf/python/202203134/

-- EOF --

-- MORE --