datetime是Python处理日期和时间的标准库
from datetime import datetime
1,注意到datetime是模块,datetime模块还包含一个datetime类,通过from datetime import datetime导入的才是datetime这个类。
如果仅导入import datetime,则必须引用全名datetime.datetime。
datetime.now( )当前日期和时间,其类型是datetime。
理解timestamp
> 在计算机中,时间实际上是用数字表示的。我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time,记为0
(1970年以前的时间timestamp为负数),当前时间就是相对于epoch time的秒数,称为timestamp。
> timestamp的值与时区毫无关系,因为timestamp一旦确定,其UTC时间就确定了,转换到任意时区的时间也是完全确定的,这就是为什么计算机存储的当前时间是以timestamp表示的,因为全球各地的计算机在任意时刻的timestamp都是完全相同的(假定时间已校准)。
> 注意Python的timestamp是一个浮点数,整数位表示秒。
> 某些编程语言(如Java和JavaScript)的timestamp使用整数表示毫秒数,这种情况下只需要把timestamp除以1000就得到Python的浮点表示方法。
> timestamp没有时区的概念,而datetime有时区的概念。
datetime与timestamp转换
datetime转换为timestamp:dt.timestamp( )方法 dt表示日期
timestamp转换为datetime:datetime.fromtimestamp( )方法;这个转换是在timestamp和本地时间做转换。
datetime与str转换
字符串str转换为datetime:datetime.strptime(str, 日期格式 )
datetime转换为字符串str:dt.strftime( 格式), dt表示日期
datetime加减
需要使用timedelta这个类,timedelta(days=3) , timedelta(hours=10), timedelta(days=1, hours=8)
1 # 对日期进行加减: 2 print('current datetime =', cday) 3 print('current + 10 hours =', cday + timedelta(hours=10)) 4 print('current - 1 day =', cday - timedelta(days=1)) 5 print('current + 2.5 days =', cday + timedelta(days=2, hours=12))
小结
datetime表示的时间需要时区信息才能确定一个特定的时间,否则只能视为本地时间。
如果要存储datetime,最佳方法是将其转换为timestamp再存储,因为timestamp的值与时区完全无关。
本地时间转换为UTC时间
本地时间是指系统设定时区的时间,例如北京时间是UTC+8:00时区的时间,而UTC时间是指UTC+0:00时区的时间
datetime类型有一个时区属性tzinfo,但默认是None,所以无法区分这个datetime到底是哪个时区,除非给datetime设置一个时区UTC形式
1 from datetime import datetime, timedelta, timezone 2 3 tz_utc_8 = timezone(timedelta(hours=8)) # 创建时区UTC+8:00 4 5 now = datetime.now() #当前时间,不带UTC形式 6 7 dt = datetime.now().replace(tzinfo=tz_utc_8) # 强制设置为UTC+8:00,带UTC形式 8 dt1 = datetime.now().replace(tzinfo=timezone(timedelta(hours=8))) 9 10 print("当前时间,不带UTC,不能确定是哪个时区:",now) 11 print("当前时间,带UTC,可以确定是哪个时区的时间:",dt) 12 print("当前时间,带UTC,可以直接写tzinfo:",dt1)
划红线的说明转换为UTC形式的时间了
时区转换
utcnow( )可以获得UTC+0:00时区的时间,再转换为任意时区的时间:
利用带时区的datetime,通过astimezone( )方法,可以转换到任意时区
注:不是必须从UTC+0:00时区转换到其他时区,任何带时区的datetime都可以正确转换,例如bj_dt到tokyp_dt的转换,依然是hours=9,而不是hours=1
1 # 把时间从UTC+0时区转换为UTC+8: 2 utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc) 3 4 bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8))) 5 6 tokoy_dt = utc_dt.astimezone(timezone(timedelta(hours=9))) 7 8 tokoy1_dt = utc_dt.astimezone(timezone(timedelta(hours=9))) 9 10 print('UTC+0:00 now =', utc_dt) 11 print('UTC+8:00 now =', bj_dt) 12 print('UTC+9:00 now =', tokoy_dt) 13 print('从UTC+8:00转换为UTC+9:00 now =', tokoy1_dt)
实战
题目:假设你获取了用户输入的日期和时间,如2015-1-21 9:01:30,以及一个时区信息如UTC+5:00,均是str,请编写一个函数将其转换为timestamp:
1 from datetime import datetime, timezone, timedelta 2 3 def to_timestamp(dt_str, tz_str): 4 dt=datetime.strptime(dt_str,'%Y-%m-%d %H:%M:%S') 5 tz=int(tz_str[3:-3]) #获取+,包含+以及冒号之前的部分,这是 自己最初的想法 6 # tz=int(tz_str[3:].split(":")[0]) #第二种tz的计算方法,这是参考别人获得 7 dt1=dt.replace(tzinfo=timezone(timedelta(hours=tz))) 8 t=dt1.timestamp() 9 return t 10 11 t1 = to_timestamp('2015-6-1 08:10:30', 'UTC+7:00') 12 assert t1 == 1433121030.0, t1 13 14 t2 = to_timestamp('2015-5-31 16:10:30', 'UTC-09:00') 15 assert t2 == 1433121030.0, t2 16 17 print('ok')