python中各种时间格式的转换

coolpython

共 2999字,需浏览 6分钟

 · 2020-12-20

对于时间的处理,是编程中极为常见的操作,最常规的操作是对时间进行转换。比如下面三个时间

1608085848     # int
'2020-12-16 10:31:08' # 字符串
'11/Nov/2020:00:31:36' # 字符串

第一种时间的格式是时间戳,记录的是从1970年1月1日凌晨开始的秒数。后两种是字符串的形式,其中第二种是我们最喜欢的格式,一看便知具体时间,但第三种就不那么讨人喜欢了,夹杂着英文,看起来十分别扭,可这种格式的时间却十分常见,比如nginx日志里的时间就是这个样子。

不论是int形式,还是字符串形式,绝大多数情况下,都需要转换成python中的datetime对象,这个对象提供了很多对时间的操作方法,若想对数据进行存储和分析,就必须对时间进行转换。

1. 时间戳

时间戳可以用多种方式获取,time和datetime 这两个模块都可以

import time
from datetime import datetime

print(int(time.time())) # 获取当前时间的时间戳
print(int(datetime.now().timestamp())) # 获取当前时间的时间戳

从时间戳转为datetime类型,可以使用fromtimestamp方法

import time
from datetime import datetime

time_now = int(time.time()) # 获取当前时间的时间戳
dt_now = datetime.fromtimestamp(time_now)

print(type(dt_now), dt_now) # 2020-12-16 10:40:34

在mysql中,可以定义timestamp类型的列,它存储的,就是时间戳。

2. 最喜闻乐见的时间格式

'2020-06-16 10:31:08' 是最大家最喜欢的时间格式,一方面是因为在对数据观察时最容易理解,另一方面也最为常见,因此大家都知道如何处理。

from datetime import datetime

# 字符串转datetime
time_str = '2020-06-16 10:31:08'
dt_time = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
print(dt_time)

# datetime转字符串
time_str = dt_time.strftime('%Y-%m-%d %H:%M:%S')
print(time_str) # 2020-06-16 10:31:08

从字符串向datetime转换时,必须根据字符串的格式来定义strptime中的第二个参数format, 反之亦然。如果format格式不正确,那么就不能转换,关于format参数中的%Y,%M,都有着明确的含义与作用,这些符号的作用可以参考python时间格式

这种时间的格式,的确工整,但也有一些让人不习惯的地方,我们日常描述月份时,会说6月,而不会说06月,如果你得到的字符串是下面的样子,也是十分正常的

'2020/6/17'

对于这样的字符串,可以设置format='%Y/%m/%d' 进行转换

from datetime import datetime

# 字符串转datetime
time_str = '2020/6/17'
dt_time = datetime.strptime(time_str, '%Y/%m/%d')
print(dt_time) # 2020-06-17 00:00:00

# datetime转字符串
time_str = dt_time.strftime('%Y/%m/%d')
print(time_str) # 2020/06/17

小于10的月份,从字符串转为datetime类型时,可以使用%m进行转换,但是从datetime向字符串转换时,%m就无法将月份转成单个数值,而是前面要加一个'0'。如果有要求一定要去掉月份前面的0,需要加一个特殊的字符

from datetime import datetime

# 字符串转datetime
time_str = '2020/6/17'
dt_time = datetime.strptime(time_str, '%Y/%m/%d')
print(dt_time) # 2020-06-17 00:00:00

# datetime转字符串
time_str = dt_time.strftime('%Y/%#m/%d')
print(time_str) # 2020/6/17

在%m的中间加一个#字符,就可以转换出前面不加0的月份,这种方法适用于windows系统,如果是linux系统,则需要在中间加- 字符。

3. 带英文的时间字符串

'11/Nov/2020:00:31:36', 这种格式的时间与第二种本无本质区别,只是部分带了英文而已,只要format设置的正确,就可以顺利的进行转换。

from datetime import datetime

now = datetime.now()
print(now.strftime("%d/%b/%Y:%H:%M:%S")) # 16/Dec/2020:11:01:37

%b表示本地简化的月份名称,%B表示本地完整的月份名称,使用这两个符号,得到的就是英文的月份表示。

写到这里,我突然奇想,能否在时间转换时加入中文呢,从datetime转出的字符串,其结果类似于"2020年12月16日",想法有了,试一试。

from datetime import datetime

now = datetime.now()
print(now.strftime("%Y年%#m月%d日"))

这段代码在centos上可以正确执行,但在windows上运行程序报错

UnicodeEncodeError: 'locale' codec can't encode character '\u5e74' in position 2: Illegal byte sequence

python3不应该再有奇怪的编码问题了,问题应该是更深层次的,谷歌了一下,果然如此,windows环境下,底层调用的是C的strftime函数,而这个函数在运行前必须先根据locale的配置来编码格式化字符串,默认使用latin-1(单字节)来编码格式化字符串,而汉字是多字节的,这样就会出错,解决办法倒也简单

import locale
from datetime import datetime

locale.setlocale(locale.LC_CTYPE, 'chinese')
now = datetime.now()
print(now.strftime("%Y年%#m月%d"))

这样就不会报错了,完美。


浏览 69
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报