0. 引言
故事同样起源于工作:
- 前两天的一个任务当中,需要获取从当前的时间点到一周前的时间段,这个任务本身其实挺简单的,不过坑的是,我们在本地测试成功之后,就推到了线上,结果在线上的服务当中获取的当前时间是没有经过校准的,然后就获取了设备的出场设置时间,然后就杯具了。。。
针对这个坑,事实上处理的方法也比较简单:
- 我们只要先取用世界时间,然后转换为北京时间即可。
但是,其中却也暴露了我对于datetime库使用上的不熟练,因此,这里就搞篇小水文来整理一下下面两个和时间相关的库吧:
- time库
- datetime库
为了避免又像之前的文章那样变成文档翻译,这里,我们先大致介绍一下其中的一些常用函数,然后用两个实际的case来进行一下说明。
1. 基本函数介绍
1. time库
这里,我们先来看一下time库当中的一些常用的函数。
time.time()
- 获取当前的机器时间,返回为一个float小数,单位为秒。
time.sleep(secs)
- 暂停当前线程,等待
secs
秒后重启线程继续运行程序。
- 暂停当前线程,等待
time.asctime([t])
- 用默认的string表达方式展示t表达的时间,如果t为空,则取默认值为当前的时间;
time.localtime([secs])
- 将一个float类型的时间转换为一个
struct_time
类型的时间进行返回,如果secs为空,则默认值为当前的时间,即time.time()
的结果。
- 将一个float类型的时间转换为一个
time.strftime(format, [t])
- 将时间t(
tuple
或者struct_time
类型)转换为string类型并进行答应,其中format为自定义的显示格式,如:"%Y-%m-%d %H:%M:%S %a %Z(%z)"
,展示为:2021-01-28 13:44:07 Thu CST(+0800)
,更多的参数定义可以参考官网文档。
- 将时间t(
2. datetime库
同样的,我们给出一些常用的datetime库中的方法如下:
datetime.datetime.now()
- 获取当前时间,datetime数据格式
datetime.datetime.utcnow()
- 获取utc时间,datetime数据格式
datetime.datetime.timedelta()
- 获取时间差,datetime数据格式
datetime.strftime()
- 类方法,将datetime类转换为string进行打印
datetime.timestamp()
- 类方法,将datetime类转换为float类型时间戳
2. 实例考察
1. retry实现
这里,我们来给出一个简单的装饰器,用以实现函数运行失败时的自动retry过程。
def retry(retry_time=3, fix_time=5):
def decorator(func):
def fn(*args, **kwargs):
for i in range(retry_time):
try:
return func(*args, **kwargs)
except:
print(f"function {func.__name__ } failed {i+1} times.")
time.sleep(fix_time)
raise Exception(f"function {func.__name__ } still failed after {retry_time} times retry.")
return fn
return decorator
2. 对任意一个函数进行耗时计算
同样,我们同样可以使用装饰器的方式对任意一个函数返回执行时间。
def count_time(func):
def fn(*args, **kwargs):
t1 = time.time()
res = func(*args, **kwargs)
t2 = time.time()
print(f"function {func.__name__} cost time: {t2-t1:.2} secs")
return res
return fn
3. 获取北京时间
我们给出一个获取北京时间的通用方法如下:
def get_time(time_format="%Y-%m-%d %H:%M:%S"):
peiking_time = datetime.timezone(
datetime.timedelta(hours=8),
name='PeiKing Time',
)
utc_time = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
return utc_time.strftime(time_format)
特别地,如果需要获取的时间上有一个平移量,我们只需要稍微调整一下代码即可:
def get_time(delta=0, time_format="%Y-%m-%d %H:%M:%S"):
peiking_time = datetime.timezone(
datetime.timedelta(hours=8),
name='PeiKing Time',
)
utc_time = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
t = utc_time.astimezone(peiking_time) + datetime.timedelta(delta)
return t.strftime(time_format)