python中各種時間格式的轉換
對于時間的處理,是編程中極為常見的操作,最常規(guī)的操作是對時間進行轉換。比如下面三個時間
1608085848 # int
'2020-12-16 10:31:08' # 字符串
'11/Nov/2020:00:31:36' # 字符串第一種時間的格式是時間戳,記錄的是從1970年1月1日凌晨開始的秒數(shù)。后兩種是字符串的形式,其中第二種是我們最喜歡的格式,一看便知具體時間,但第三種就不那么討人喜歡了,夾雜著英文,看起來十分別扭,可這種格式的時間卻十分常見,比如nginx日志里的時間就是這個樣子。
不論是int形式,還是字符串形式,絕大多數(shù)情況下,都需要轉換成python中的datetime對象,這個對象提供了很多對時間的操作方法,若想對數(shù)據(jù)進行存儲和分析,就必須對時間進行轉換。
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' 是最大家最喜歡的時間格式,一方面是因為在對數(shù)據(jù)觀察時最容易理解,另一方面也最為常見,因此大家都知道如何處理。
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轉換時,必須根據(jù)字符串的格式來定義strptime中的第二個參數(shù)format, 反之亦然。如果format格式不正確,那么就不能轉換,關于format參數(shù)中的%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就無法將月份轉成單個數(shù)值,而是前面要加一個'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系統(tǒng),如果是linux系統(tǒng),則需要在中間加- 字符。
3. 帶英文的時間字符串
'11/Nov/2020:00:31:36', 這種格式的時間與第二種本無本質區(qū)別,只是部分帶了英文而已,只要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上可以正確執(zhí)行,但在windows上運行程序報錯
UnicodeEncodeError: 'locale' codec can't encode character '\u5e74' in position 2: Illegal byte sequence
python3不應該再有奇怪的編碼問題了,問題應該是更深層次的,谷歌了一下,果然如此,windows環(huán)境下,底層調用的是C的strftime函數(shù),而這個函數(shù)在運行前必須先根據(jù)locale的配置來編碼格式化字符串,默認使用latin-1(單字節(jié))來編碼格式化字符串,而漢字是多字節(jié)的,這樣就會出錯,解決辦法倒也簡單
import locale
from datetime import datetime
locale.setlocale(locale.LC_CTYPE, 'chinese')
now = datetime.now()
print(now.strftime("%Y年%#m月%d日"))
這樣就不會報錯了,完美。
