本文出现的名称解释:
UTC——协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。(摘自百科协调世界时)
GMT——格林尼治标准时间(参见百科世界时)
时间戳——格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数
Unix时间戳(Unix timestamp)——格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数。
参考链接:datetime ,time
python中有两个模块都可以用来处理时间,分别是datetime和time,代码如下:
from datetime import datetime
import time
print(datetime.now())
# 2019-11-30 15:19:30.266853
print(datetime.today())
# 2019-11-30 15:19:30.266853
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
# 2019-11-30 15:19:30
struct_time结构中包含时间的各维度信息,常用来作为日期与时间戳转换的中介,代码如下
import time
tt = time.localtime()
print(tt)
for i in tt:
print(i)
结果如下:
time.struct_time(tm_year=2019, tm_mon=11, tm_mday=30, tm_hour=16, tm_min=30, tm_sec=7, tm_wday=5, tm_yday=334, tm_isdst=0)
2019
11
30
16
30
7
5
334
0
直接获取当前UTC时间笔者只找到了datetime使用方式,代码如下:
from datetime import datetime, timezone
print(datetime.now(timezone.utc)) # 2019-11-30 07:25:02.883826+00:00
print(datetime.utcnow()) # 2019-11-30 07:25:02.883826
import time
time.gmtime()
# time.struct_time(tm_year=2019, tm_mon=11, tm_mday=30, tm_hour=15, tm_min=29, tm_sec=31, tm_wday=5, tm_yday=334, tm_isdst=0)
获取时间戳用time模块,返回结果单位为秒(s),代码如下:
import time
time.time()
# 1575100421.8757198
time.strptime将输入字符串(需同时输入字符串格式形式)转换为time.struct_time结构,然后time.strftime将其转换为指定的日期格式,代码如下:
t1 = time.strptime("20191130",'%Y%m%d') # time.struct_time
print(t1) # time.struct_time(tm_year=2019, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=334, tm_isdst=-1)
t2 = time.strftime("%Y/%m/%d",t1)
print(t2) # 2019/11/30
datetime.strptime将输入时间字符串(需同时输入字符串格式形式)转换为datetime.datetime结构,然后通过该结构的strftime属性得到指定格式的日期时间字符串,代码如下所示。需要说明的是,datetime.datetime结构在使用print打印时会显示日期格式,而在python交互环境中不适用print时,可以显示datetime.datetime形式。
from datetime import datetime
t1 = datetime.strptime("30/11/19 16:00", "%d/%m/%y %H:%M") # datetime.datetime(2019, 11, 30, 16, 0)
t2 = datetime.strptime("20191130 16:00","%Y%m%d %H:%M") # datetime.datetime(2019, 11, 30, 16, 0)
print(t1) # 2019-11-30 16:00:00
print(t2) # 2019-11-30 16:00:00
time1 = t1.strftime("%Y/%m/%d %H:%M:%S")
time2 = t2.strftime("%Y/%m/%d %H:%M:%S")
print(time1) # 2019/11/30 16:00:00
print(time2) # 2019/11/30 16:00:00
time模块先通过time.strptime将日期字符串转换为一个time.struct_time,然后用time.mktime将其转换为时间戳。此处有一个很重要的点需要注意,time.mktime会默认输入的时间为本地时间,因此自动将其转为UTC时间然后再转时间戳。例如笔者所在时区为UTC+8,意思就是本地时间在UTC时间基础上会加上8小时。也就是说time.mktime会先将获取的时间减去8小时,然后转时间戳。代码如下:
import time
ts = time.mktime(time.strptime("2019-07-01", "%Y-%m-%d"))
ts2 = time.mktime(time.strptime("2019-07-01 00:00:00", "%Y-%m-%d %H:%M:%S"))
print(ts) # 1561910400.0
print(ts2) # 1561910400.0
注意,如果不输入时分秒的信息,默认就是零时零分零秒,这一点通过ts和ts2的结果可以看出
datetime.strptime将输入日期转为datetime.datetime结构,然后由timestamp()方法获得时间戳,代码如下:
from datetime import datetime
time1 = datetime.strptime("20190701","%Y%m%d")
ts = time1.timestamp() # py3.3以后才有
print(ts) # 1561910400.0
该问题的应用场景是当你需要获取UTC时间2019-07-01以前的数据时,就需要通过数据中的时间戳字段进行比较,那么此处计算的就应该时UTC时间2019-07-01对应的时间戳。
解决方法就是获取本地的时差。python中time.timezone用来表示时区偏移量,单位为秒,与一般的时差符号相反,因此需要减去time.timezone,代码如下:
import time
print(time.timezone/3600) # -8.0
ts = time.mktime(time.strptime("2019-07-01", "%Y-%m-%d"))-time.timezone
ts2 = time.mktime(time.strptime("2019-07-01 00:00:00", "%Y-%m-%d %H:%M:%S"))-time.timezone
print(ts) # 1561939200.0
print(ts2) # 1561939200.0
datetime.strptime将输入日期转为datetime.datetime结构,然后由tzinfo=timezone.utc指定该日期为UTC时间,最后由timestamp()方法获得时间戳,代码如下:
from datetime import datetime, timezone
time1 = datetime.strptime("20190701","%Y%m%d")
ts = time1.replace(tzinfo=timezone.utc).timestamp() # py3.3以后才有
print(ts) # 1561939200.0
datetime.utcfromtimestamp(timestamp)
datetime.utcfromtimestamp可直接将时间戳转为UTC时间,得到一个datetime.datetime对象,然后通过其strftime属性获取指定格式的时间字符串。
datetime.fromtimestamp(timestamp, tz=None)
datetime.fromtimestamp则需要指定tz为timezone.utc,才可以将时间戳转为UTC时间。
from datetime import datetime, timezone
utc = datetime.utcfromtimestamp(1561939200) ## datetime.datetime
time_ = utc.strftime("%Y-%m-%d %H:%M:%S") # '2019-07-01 00:00:00'
print(time_)
time1 = datetime.fromtimestamp(1561939200, timezone.utc)
time2 = time1.strftime("%Y-%m-%d %H:%M:%S") ## '2019-07-01 00:00:00'
print(time2)
time.gmtime([secs])
time.gmtime将时间戳转为time.struct_time对象,然后通过time.strftime指定输出的时间字符串格式。
import time
time1 = time.gmtime(1561939200) # time.struct_time
time2 = time.strftime("%Y/%m/%d",time1) # '2019/07/01'
print(time2)
datetime.fromtimestamp在不指定tz的情况下,会默认转为本地时间.
timedelta可以指定时差,返回结果为datetime.timedelta
from datetime import datetime
time1 = datetime.fromtimestamp(1561939200)
time2 = time1.strftime("%Y-%m-%d %H:%M:%S") # '2019-07-01 08:00:00'
print(time2)
from datetime import datetime, timedelta
time1 = datetime.utcfromtimestamp(1561939200) + timedelta(hours = 8) # datetime.timedelta(seconds=28800)
time2 = time1.strftime("%Y-%m-%d %H:%M:%S") # '2019-07-01 08:00:00'
print(time2)
time.localtime可以直接将时间戳转为本地时间,得到time.struct_time对象。
import time
time1 = time.localtime(1561939200) # time.struct_time
print(time1) # time.struct_time(tm_year=2019, tm_mon=7, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=182, tm_isdst=0)
time2 = time.strftime("%Y/%m/%d %H:%M:%S",time1)
print(time2) # 2019/07/01 08:00:00
from datetime import datetime
utc = datetime.utcfromtimestamp(1561939200) # datetime.datetime(2019, 7, 1, 0, 0)
print(utc)
tt = utc.timetuple() # datetime.datetime转为time.struct_time
print(tt) # time.struct_time(tm_year=2019, tm_mon=7, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=182, tm_isdst=-1)
大家发现没有,不管是时间戳转日期还是日期转时间戳,或者不论是通过datetime还是time模块处理,他们都是通过一个中介对象进行转换。在datetime模块中,通过datetime.datetime对象转换时间戳和日期;在time模块中,通过time.struct_time对象转换时间戳和日期。