在Python常用日期处理,内置模块datetime探讨了Python如何使用datetime,如果是一个跨时区的应用(Web应用都是),就不能只存储一个时间而不带时区,如此,全球用户将会看到一个相同的时间字符串,白天黑夜就错乱了。比说用户信息的更新时间存储为2020-07-07 13:46:08,上海的用户和芝加哥的用户看到的是同一个时间字符串,实质上却相差好多个小时。
我们可以这么做,在服务端只存储一个时间戳长整型值或UTC时间,时间戳是无关乎时区的,它总是相对于一个UTC时间的偏移值;然后由客户端根据本地时区来显示当地时间。不过在服务端存储为UTC时间戳或可读性就不强了,打开文件看到时间戳整形值,大脑是无法直接转换为日期,UTC时间略好一些。
另一种做法可在服务端存储为开发者便于理解的带时区的时间,如2020 - 07年- 07 - t13:46:08.342 +喂饲,客户获得该时间,因为带有时区信息也就能转换为客户端本地时间。
客户端请求时还可以把本地的时区信息传送给服务端,由服务端转换为相应的本地时间发送给客户端,但HTTP头信息默认不带时区信息,客户端必须主动发送它。
本人倾向于在服务端存为带时区的时间,2020 - 07年- 07 - t13:46:08.342 +喂饲是一个标准的存储格式(ISO_OFFSET_DATE_TIME),客户端收到它再转换本地时间,JavaScript的一个很好的组件时刻处理时间。
<强>探索Python对时区的处理强>
Python内置组件不能像Java的<代码> ZoneId.of(“亚洲/上海”)代码>直接以时区名获得区,而需要知道与标准时区的偏移,如上海是东八区,在Python中要用<代码>时区(timedelta(小时=+ 8))> 代码。
那么来看Python中输出带时区信息,以下是一些应用Pytho时区时区的例子
从进口datetime datetime,时区,timedelta tz=时区(timedelta(小时=+ 8)) fmt=' % Y - % m - H % dT %: % m: % s % f % z ' zoned_time1=datetime.today () .astimezone (tz) 打印(zoned_time1.strftime (fmt)) # 2020 - 07 - 08 - t04:30:26.221450 + 0800 zoned_time2=datetime.now (tz) 打印(zoned_time2.strftime (fmt)) # 2020 - 07 - 08 - t04:30:26.221543 + 0800 zoned_time3=datetime.utcnow () 打印(zoned_time3.isoformat()) # 2020 - 07年- 07 - t20:30:26.221848 打印(4 zoned_time2.strftime (' % Y - % - % dT % H: % m: % s % f % Z ')) # 2020 - 07 - 08 - t04:30:26.221543utc +喂饲 时间戳=datetime.today () .timestamp () 打印(5,时间戳)# 1594153826.221895 打印(datetime.fromtimestamp(时间戳,tz=tz)) # 2020-07-08 04:30:26.221895 +喂饲 zoned_time4=datetime(2020年,7、8、4、23日,53岁,112年,tzinfo=tz) 打印(7,zoned_time4.isoformat ()) # 2020 - 07 - 08 - t04:23:53.000112 +喂饲 打印(8,zoned_time2.isoformat ()) # 2020 - 07 - 08 - t04:30:26.221543 +喂饲
输出为,已加到上面源代码中
1 2020 - 07 - 08 - t04:30:26.221450 + 0800
引用>
2 2020 - 07 - 08 - t04:30:26.221543 + 0800
3 2020 - 07年- 07 - t20:30:26.221848
4 2020 - 07 - 08 - t04:30:26.221543utc +喂饲
5 1594153826.221895
6 2020-07-08 04:30:26.221895 +喂饲
7 2020 - 07 - 08 - t04:23:53.000112 +喂饲
8 2020 - 07 - 08 - t04:30:26.221543 +喂饲时间字符串中要带有时区信息,首先时间要转换为带时区的,如用
datetime.astimezone (tz) #已有时间转换为带时区的 datetime.fromtimestamp(时间戳,tz=tz) #从时间戳构建datetime时加上时区<强>找到Python输出标准格式的方法强>
从上面的输出结果看第8行2020 - 07 - 08 - t04:30:26.221543 +喂饲接近于Java的ISO_OFFSET_DATE_TIME格式,只是毫秒段Python用了6位数字,参考strftime-strptime-behavior的Python datetime格式字符串定义找不到如何把毫秒段收缩为3位。
不过注意到datetime.isoformat()方法还有一个timespec可用,执行下面的代码
从进口datetime datetime,时区,timedelta tz=时区(timedelta(小时=+ 8)) 现在=datetime.now (tz) print (now.isoformat (timespec=毫秒))输出为
2020 - 07 - 08 - t04:41:10.793 +喂饲
引用>这正式我们想要的。还不仅仅是,继续往下读,我们还需要让Python支持夏令时,否则对于芝加哥时间夏天和冬天看到的都是5,那是不对的。
<强> pytz组件构建时区
Python datetime如何处理时区信息