python的時間及相互轉換

前幾天搞了下時間各種格式之間的轉換,記錄一下。

Python表示時間主要有兩個庫,分別是time和datetime。time模塊更接近於操作系統,所以其屬性也是和Unix timestamp相關比較多。比如其能表示的年份爲1970-2038。因爲時間戳含義就是從1970-1-1到現在的秒數,用int類型表示,int類型爲32bit,表示範圍是[-2^31+1 ~2^31-1],即[-2147483648, 2147483648],換成成年大概68年,所以最大有效期爲1970+68=2038。

如果想用更大的年份,最好用datetime。其最大年份可以用datetime.MAXYEAR查看,爲9999。

time模塊介紹

1. struct_time類。此類就是一個完整時間的元組,共有9個元素。如果調用time模塊的其他函數,如gmtime(),localtime()和strptime(),那麼返回的就是一個struct_time對象,9個元素分別爲:

屬性
tm_year(年) 如2019
tm_mon(月) 如11
tm_mday(日) 如31,每個月的日有區別
tm_hour(小時) 0-23
tm_min(分) 0-59
tm_sec(秒) 0-59
tm_wday(周幾) 0-6(0爲週日)
tm_yday(一年中的第幾天) 1-365
tm_isdst(是否夏令時) 默認爲-1

2. time.time() 獲取當前時間的時間戳

3. time.localtime() 將時間戳轉化爲struct_time格式,時區爲當前時區

4. time.gmtime() 將時間戳轉化爲UTC時間的struct_time

5. time.mktime() 將struck_time轉化爲時間戳

6. time.sleep() 睡眠時間,單位是秒

7.time.asctime() 將struct_time表示爲這種形式"Fri Nov 08 14:47:02 2019"。默認以time.localtime()爲參數

8. print time.ctime() 將時間戳表示爲這種形式"Fri Nov 08 14:47:02 2019"。默認以time.time()爲參數

9. time.strftime(format[,t]) 將時間元組struct_time轉化爲format格式的字符串, 如果t沒有指定,那麼默認以time.localtime()爲時間。時間格式爲:

時間格式 含義
%a 本地(locale)簡化星期名稱
%A 本地完整星期名稱
%b 本地簡化月份名稱
%B 本地完整月份名稱
%c 本地相應的日期和時間表示
%d 一個月中的第幾天(01 - 31)
%H 一天中的第幾個小時(24小時制,00 - 23)
%I 第幾個小時(12小時制,01 - 12)
%j 一年中的第幾天(001 - 366)
%m 月份(01 - 12)
%M 分鐘數(00 - 59)
%p 本地am或者pm的相應符
%S 秒(01 - 61)
%U 一年中的星期數。(00 - 53星期天是一個星期的開始。)第一個星期天之前的所有天數都放在第0周。
%w 一個星期中的第幾天(0 - 6,0是星期天)
%W 和%U基本相同,不同的是%W以星期一爲一個星期的開始。
%x 本地相應日期
%X 本地相應時間
%y 去掉世紀的年份(00 - 99)
%Y 完整的年份
%Z 時區的名字(如果不存在爲空字符)
%% ‘%’字符

如:time.strptime('%Y-%m-%d %H:%M:%S', time.localtime())

注:

“%p”只有與“%I”配合使用纔有效果。

當使用strptime()函數時,只有當在這年中的週數和天數被確定的時候%U和%W纔會被計算。

10. time.strptime() 於time.strftime()相反,這個函數將字符串時間轉化爲時間元組struct_time。

如: time.strptime('2019-10-18 16:04:36', '%Y-%m-%d %H:%M:%S')

三者關係如圖:

datetime模塊介紹

datetime功能相比time更加豐富,模塊下又包含了幾個類:

類名 功能說明
date 日期對象
time 時間對象
datetime 日期時間對象
datetime_CAPI 日期時間對象C語言接口
timedelta 時間間隔,即兩個時間點之間的長度
tzinfo 時區信息對象

1. date

date類基本元素由年月日組成。可以通過datetime.date.max和datetime.date.min查看其表示的範圍

1) 構造函數datetime。可以這樣搞

d = datetime.date(2019,8,7)
print d

打印2019-08-07,注意的是這個2019-08-07並不是字符串,而是datetime類的對象

2) datetime.date.today() 返回當前日期,如:

datetime.date.today()
Out[217]: datetime.date(2019, 11, 8)

3)datetime.date.fromtimestamp() 根據給定的時間戳,返回一個date對象, 如:

datetime.date.fromtimestamp(1569895835)
Out[218]: datetime.date(2019, 10, 1)

4) datetime.date.weekday() 參數是一個datetime對象,返回今天是一週的第幾天,從週一(0)開始算

t = datetime.date.today()  //今天是週五
datetime.date.weekday(t)
Out[221]: 4

5) datetime.date.isoweekday() 以date對象爲參數,返回今天是周幾,週一返回1,週二返回2...

t = datetime.date.today()  //今天是週五
datetime.date.isoweekday(t)
Out[223]: 5

6) datetime.date.isocalendar() 以date對象爲參數,返回一個元組,包括年,今天是本年第幾周,今天是星期幾

t = datetime.date.today()  //今天是2019.11.8
datetime.date.isocalendar(t)
Out[224]: (2019, 45, 5)

7) datetime.date.strftime(format) 參數爲格式化的字符串,比如'%Y-%m-%d %H:%M:%S',返回值是一個字符串

d = datetime.date(2019,8,7)
format = '%Y-%m-%d %H:%M:%S'
print d.strftime(format)

8)datetime.date.replace() 參數爲要替換的新值,返回替換後的datetime對象

d = datetime.date(2019,8,7)
format = '%Y-%m-%d %H:%M:%S'
d1 = d.replace(2018)
print d1.strftime(format)  //2018-08-07 00:00:00
d1 = d.replace(month=5)
print d1.strftime(format)  //2019-05-07 00:00:00 

9) datetime.date.year month day 輸出當前datatime對象的年月日

d = datetime.date(2019,8,7)
print d.year, d.month, d.day  //2019 8 7

也可以通過getattribute方法來獲取屬性值:

d = datetime.date(2019,1,1)
print d.__getattribute__('year'), d.__getattribute__('month'), d.__getattribute__('day')

10) datetime.date.isoformat() 返回yyyy-mm-dd格式的字符串

print datetime.date(2019,8,7).isoformat()  //2019-08-07

11) datetime.date.timetuple()  返回time模塊的struct_time格式元組

d = datetime.date(2019,8,7)
print d.timetuple() // time.struct_time(tm_year=2019, tm_mon=8, tm_mday=7, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=219, tm_isdst=-1)

12) datetime.date.toordinal() 返回公元元歷(1年1月1日)開始到現在的天數。

d = datetime.date(2019,1,1)
print d.toordinal()  //737060。不知道它怎麼算的,如果1年1月1日是1,那麼2019.1.1和這個日期相差了2018 * 365 天,結果應該是736570而不是737060,理解有問題

13) datetime.date.fromordinal() toordinal的相反操作,傳入一個天數,返回日期

d = datetime.date(2019,1,1)
a = d.toordinal()
print datetime.date.fromordinal(a)

14)日期的比較,例子如下:

d1 = datetime.date(2019,1,1)
d2 = datetime.date(2019,1,2)
d3 = datetime.date(2019,1,1)
print d1.__ge__(d3)  //True
print d1.__gt__(d2)  //False
print d1.__eq__(d2)  //False
print d1.__eq__(d3)  //True
print d1.__le__(d2)  //True 
print d2.__lt__(d3)  //False

15) 能表示的最大和最小值min(),max()

print datetime.date.min  //0001-01-01
print datetime.date.max  //9999-12-31

16) 能表示的最小單位datetime.date.resolution

print datetime.date.resolution  //1 day, 0:00:00

2. time

datetime.date類最小單位爲天,datetime.time類爲毫秒

time類由小時,分鐘,秒,微妙和tzinfo組成。類似的,其構造函數爲:

time([hour[, minute[, second[, microsecond[, tzinfo]]]]])

1) datetime.time(15,23,45,368) 返回值爲time類的對象

datetime.time(hour=15,minute=23,second=45,microsecond=36800) //結果爲15:23:45.036800

2) 獲取time對象的屬性值

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.hour,d.minute,d.second,d.microsecond,d.tzname() //輸出結果爲15 23 45 36800 None

與datetime.date類似,也可以通過getattribute方法獲取, 如:

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.__getattribute__('hour'), d.__getattribute__('minute'), d.__getattribute__('second'), d.__getattribute__('microsecond')

3) 按照格式轉爲爲字符串對象datetime.time.strftime('%H:%M:%S')

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.strftime('%H:%M:%S')

4)查看時區信息d.tzname()

d.tzname()

5) 替換某個時間datetime.time.replace(),與date類似

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.strftime('%H:%M:%S')
d1 = d.replace(hour=19)  
print d1  //19:23:45.036800
d1 = d.replace(minute=35)  
print d1  //15:35:45.036800
d1 = d.replace(second=36)
print d1  //15:23:36.036800
d1 = d.replace(microsecond=66000)
print d1  //15:23:45.066000

6) datetime.date.isoformat() 返回'%H:%M:%S'格式的字符串

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.isoformat()  //15:23:45.036800

7) 最大最小值min, max

print datetime.time.min  //00:00:00
print datetime.time.max  //23:59:59.999999

8) 能表示的最小單位datetime.time.resolution

print datetime.time.resolution  //0:00:00.000001

3. datetime

datetime.datetime類是date類和time類的合體,函數的類型和含義都很類似,只是相較於date或者time進行了擴充。比如說datetime類的構造函數:

datetime(self, year, month, day, hour=None, minute=None, second=None, microsecond=None, tzinfo=None)

1) datetime.resolution 能表示的最小時間單位

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.resolution  //0:00:00.000001

2) datetime.date() 獲取表示日期的部分

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.date() //2019-11-11

3) datetime.time() 獲取表示時間的部分:

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.time()

4)datetime.isoformat() 返回iso格式時間串

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.isoformat()  //2019-11-11T16:33:24.666000

5) datetime.utcfromtimestamp(timestamp) 參數爲時間戳,返回值爲datetime對象

print datetime.utcfromtimestamp(time.time()) //返回utc時間2019-11-12 08:04:54.660000,當前時間爲2019-11-12 16:04:54

6)datetime.replace 用法date和time

7)datetime.strftime() 將datetime時間格式化爲字符串

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.strftime('%Y-%m-%d %H:%M:%S') //2019-11-11 16:33:24

8) datetime.strptime() 參數爲時間字符串,和時間格式,返回datetime對象

print datetime.datetime.strptime('2019-3-26 7:18:16', format) //2019-03-26 07:18:16

9) datetime.timetuple() 將datetime對象轉化爲time模塊的struct_time

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.timetuple() //time.struct_time(tm_year=2019, tm_mon=11, tm_mday=11, tm_hour=16, tm_min=33, tm_sec=24, tm_wday=0, tm_yday=315, tm_isdst=-1)

10) datetime.today() 獲取今天的時間,返回值爲datetime對象

print datetime.datetime.today() //2019-11-12 11:43:35.904000

11) datetime.weekday(),fromordinal(), toordinal(), isoweekday(), isocalendar() 同date

12) datetime.utcnow() 返回當前標準時區的時間對象

print datetime.datetime.utcnow() //返回值爲2019-11-12 03:52:00.943000;當前北京時間爲2019-11-12 11:52:00.943000

13)可以通過datetime.year/month/day/hour/minute/second/microsecond 來獲取datetime對象的具體某個時間值:

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.month, d.hour, d.second

14) datetime.fromtimestamp() 參數爲timestamp, 返回datetime對象

datetime.datetime.fromtimestamp(time.time()) //返回2019-11-12 16:06:16.437000,即當前時間

15)datetime.ctime() 同date類

16)datetime.astimezone() 傳入參數是一個timezone,根據時區設置,返回datetime對象。需要注意的是,轉化前的datetime是需要有時區信息纔可以的。

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
print d.astimezone(UTC(7)) //2019-11-11 15:33:24.666000+07:00, 此處UTC是一個自己創建的類,詳見tzinfo章節

17)datetime.combine() 將date和time組合成datetime對象

a1 = datetime.date(2019,1,1)
d1 = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
datetime.datetime.combine(a1, d1) //2019-01-01 15:23:45.036800

18) datetime.now() 返回當前時間的datetime對象(帶時區)

print datetime.datetime.now() //2019-11-12 17:22:00.501000

19) datetime.tzname(),datetime.utcoffset, datetime.dst() 見tzinfo

20) datetime.utctimetuple() 創建utc時間的time模塊的struct_time結構

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
print d.utctimetuple()

21) 類似於date模塊,datetime模塊也可以用__gt__等進行比較

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
d1 = datetime.datetime(2019,11,12,16,33,24,666000,tzinfo=UTC(8))
print d1.__gt__(d)  //返回True

3. timedelta類

timedelta類用來進行日期時間的運算,最大單位是天,最小單位是微妙。其構造函數爲:

datetime.timedelta(days=0, seconds=0, microseconds=0,milliseconds=0, minutes=0, hours=0, weeks=0)

1) timedelta的使用

timedelta中參數的值分爲正負,正值爲加,負值爲減。比如先創建了一個datetime對象d

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))

如果要計算時間d之後一天,一小時,一分鐘,一秒,一毫秒和一微妙後的時間是多少就可以這麼做:

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
print d + datetime.timedelta(days=-1,hours=1,minutes=1,seconds=1,microseconds=1,milliseconds=1) //2019-11-10 17:34:25.667001+08:00

2) timedelta.days 返回timedelta有多少整天,不包含小時和分鐘, 如:

td = datetime.timedelta(days=13,hours=2,minutes=3,seconds=1,microseconds=1,milliseconds=1)
print td.days //返回13

4. tzinfo

tzinfo類是一個虛擬類,如果要使用的話,需要創建一個子類,並實現相關方法。需要重寫的方法有name(),utcoffset(),dst()這三個方法。

class UTC(tzinfo):
    """UTC"""
    def __init__(self,offset = 0):
        self._offset = offset

    def utcoffset(self, dt):
        return timedelta(hours=self._offset)

    def tzname(self, dt):
        return "UTC+%s" % self._offset

    def dst(self, dt):
        return timedelta(hours=self._offset)

創建一個北京時間的datetime

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
print d.tzname(), d.utcoffset(), d.dst()  #打印結果:UTC+8 8:00:00 8:00:00

需要注意的是,tzinfo是要和datetime一起使用的,如果直接創建一個UTC對象,打印tzname需要同時傳入一個datetime對象纔可以,看定義就比較明白了。

如果不想自己實現tzinfo,可以用現成的庫pytz

pytz中可以直接通過pytz.timezone()獲取一個對象,比如要獲取上海的,可以是:

pytz.timezone('Asia/Shanghai')

5. 實用舉例

1. 獲取Linux時間戳

1) 獲取當前時間的時間戳

print time.time()

2)獲取特定時間的時間戳

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=pytz.UTC)
print time.mktime(d.timetuple())  #1573461204.0

或者這樣

timeStr = '2019-10-01 10:10:35'  //指定一個時間
timearray = time.strptime(timeStr, '%Y-%m-%d %H:%M:%S') //將時間按照格式轉化爲time.struct_time格式
print timestemp = time.mktime(timearray)  //生成時間戳1569895835.0

廖雪峯老師的網站上有一種方法是調用

>>> dt = datetime(2015, 4, 19, 12, 20) # 用指定日期時間創建datetime
>>> dt.timestamp() # 把datetime轉換爲timestamp

但是這種方法我這邊沒有不成功,可能是庫不對

2. 獲取時間字符串

1) 利用time模塊獲取當前時間字符串

format = '%Y-%m-%d %H:%M:%S'
print time.strftime(format)

這種方法利用了strftime默認以time.localtime()爲第二個參數,獲取當前時間

2) 利用datetime模塊獲取當前時間字符串

format = '%Y-%m-%d %H:%M:%S'
dt = datetime.datetime.now()
print dt.strftime(format)

datetime.now()返回的是datetime對象,再利用strftime轉化爲字符串

3)將timestamp轉化爲時間字符串

print datetime.datetime.fromtimestamp(timestamp)

也可以利用time模塊轉化爲字符串格式

format = '%Y-%m-%d %H:%M:%S'
timestamp = 1573461204
print time.strftime(format, time.localtime(timestamp))

4)時區轉化

有一點需要明確,就是timestamp是和時區沒有關係的,就是說,無論哪個時區,時間確定了,那麼時間戳就是固定的。

首先定義一下epoch time,對於格林威治時間,epoch time就是1970年01月01日00時00分00秒,對於北京時間就是1970年01月01日08時00分00秒

如果現在是北京時間2019-11-29 15:00:00,北京時間屬於UTC+8時區,那麼此時,UTC+0時區的時間就是2019-11-29 07:00:00。此時北京時間的時間戳爲2019-11-29 15:00:00 - 1970-1-1 08:00:00的秒數,UTC+0時間的時間戳爲2019-11-29 07:00:00 - 1970-1-1 07:00:00的秒數,二者是相等的

反過來,對於一個給定的timestamp,對於不同的時區,就是不同的時間,因爲不同的時間epoch time就是不同的了

a. 可以通過datetime的函數astimezone轉化

dt = datetime.datetime.now().replace(tzinfo=pytz.timezone('Asia/Shanghai'))
print dt   #print 2019-11-29 15:34:49.802000+08:06
print dt.astimezone(pytz.timezone('UTC')) #print 2019-11-29 07:28:49.802000+00:00
發佈了11 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章