Python:datetime
學習自:datetime — Basic date and time types — Python 3.10.0b2 documentation
datetime模組用於操作date和time。
date和time物件可以分成“感知型”和“簡單型”兩種,分類方法取決於這類物件是否包含時區(timezone)資訊。
感知型,代表了一個特定的有意義的時間,比如“北京12:03”、“莫斯科 7:03”
簡單型,並不包含任何的定位資訊,只是表明用於計算的時間,比如“這段路程花費了2小時14分36秒”
在使用“感知型”時間時,datetime和time物件需要包含時區資訊,即在構建這類物件時設定引數tzinfo
Class
- datetime.date:日期類,只有year、month、day三個引數;
- datetime.time:時間類,引數包含hour、minute、second、microsecond、tzinfo;
- datetime.datetime:時間和日期的結合,引數有year、month、day、hour、minute、second、microsecond、tzinfo;
- datetime.timedelta:兩個date、time、datetime間的時間間隔;
- datetime.tzinfo:包含時空資訊的抽象類,經常被datetime
- datetime.timezone:用UTC時間實現tzinfo抽象類的類;
這些類的繼承關係:
timedelta tzinfo -> timezone time date -> datetime
確定一個class是“感知型”還是“簡單型”
date物件一定是“簡單型”;
time、datetime可能是這兩種型別,那麼如何判斷呢?
“感知型” datetime或time物件x:
- x.tzinfo 不是None;
- x.tzinfo.utcoffset(d)不返回None。
其他時候,x都是簡單型。
timedelta
timedelta物件代表兩個date、time之間的持續時間。
構造方法
datetime.timedelta( days=0,seconds=0,microseconds=0, milliseconds=0,minutes=0,weeks=0 )
所有的引數都是可選的,預設值都為0。所有的引數可以是整型或浮點型,整數或浮點數;
記憶體中儲存的只有days、seconds、microseconds,其他引數都可以被轉化:
- 1ms = 1000 microseconds;
- 1min = 60 s;
- 1hour = 3600 s;
- 1week= 7 days;
days、seconds、microseconds會被規格化儲存,這樣它們的值都是唯一的,規則是:
- 0 <= microseconds < 100000;
- 0 <= seconds < 3600*24;
- -99999999<= days <= 99999999;
下邊這個例子展示了除了days、seconds、microseconds之外的引數如何被轉化為上述這三個引數:
delta = timedelta( days=50,seconds=27,microseconds=10, milliseconds=29000,minutes=5,hours=8,weeks=2 ) delta datetime.timedelta(days=64, seconds=29156, microseconds=10)
類屬性
timedelta.resolution:精度(兩個不等的timedelta物件之間的可能的最小時間間隔),預設是1μs,即timedelta( microseconds = 1 )
運算
在看以下的運算時,一定要把下邊的時間想成這種概念,從A到B需要 t小時
運算 | 說明 |
t1 = t2 + t3 | t2、t3時間之和 |
t1 = t2 - t3 | t2、t3時間之差 |
t1 = t2 * i | t1是t2的整數倍 |
t1 = t2 * f | t1是t2的f倍,結果如果在精度之外就四捨五入 |
f = t2 / t3 | |
t1 = t2 / f 或 t1 = t2 / i | |
t1 = t2 // i 或 t1 = t2 // t3 | 商 |
t1 = t2 % t3 | 餘數 |
q,r = divmod ( t1 , t2 ) | 同時計算商和餘數 |
+t1 |
前邊的符號是正負號,不是加減號 返回一個有著相同值的timedelta物件 |
-t1 | 返回 timedelta(-t1.days , -t1.seconds , -t1.microseconds)或者t1 * (-1) |
abs( t ) | 只看t.days,如果>=0就返回+t,否則就返回-t |
str ( t ) | 以格式" Ddays, H:MM:SS.UUUUUU"返回字串str,如果t是負數時D就是負數 |
repr( t ) | 返回一個String,表示構造該timedelta時,建構函式的寫法 |
除了以上所說的運算,timedelta物件也支援加減date和datetime物件。
此外,也支援兩個timedelta間用比較運算子進行比較。
例項方法
timedelta.total_seconds():返回持續時間的總秒數。
例子
關於規格化的例子:
>>> from datetime import timedelta >>> year = timedelta(days=365) >>> another_year = timedelta(weeks=40, days=84, hours=23, ... minutes=50, seconds=600) >>> year == another_year True >>> year.total_seconds() 31536000.0
關於timedelta計算的例子:
>>> from datetime import timedelta >>> year = timedelta(days=365) >>> ten_years = 10 * year >>> ten_years datetime.timedelta(days=3650) >>> ten_years.days // 365 10 >>> nine_years = ten_years - year >>> nine_years datetime.timedelta(days=3285) >>> three_years = nine_years // 3 >>> three_years, three_years.days // 365 (datetime.timedelta(days=1095), 3)
date
一個date物件代表了一個有著year、month、day的date。
建構函式
datetime.date(year,month,day)
所有引數都需要明確指定,且這些引數必須是整型且需要在指定範圍內:
- MINYEAR <= year <= MAXYEAR
- 1 <= month <= 12
- 1<= day <= 該年該月最大天數
類方法:用法date.xxx(...)
today() | 返回當前date |
fromtimestamp(timestamp) | 返回timestamp對應的date |
fromisoformat(date_string) | 返回格式為'YYYY-MM-DD'的字串對應的date |
frommisocalendar(year,week,day) | 返回用year、week、day指定的ISO calendar對應的date;是date.isocalendar()的反函式 |
類屬性:用法date.xxx
resolution | 精度,預設timedelta(days=1) |
year | 年 |
month | 月 |
day | 日 |
運算
date2 = date1 + timedelta | |
date2 = date1 - timedelta | |
timedelta = date1 - date2 | |
date1 < date2 |
例項方法:用法d.xxx(...)
replace(year=self.year,month=self.month,day=self.day) |
如果不寫引數,就返回一個相同的date物件; 否則就用指定引數代替原來的date中的相關值,並返回新的date |
timetuple() | 返回一個time.struct_time物件,其中hours、minutes、seconds都是0,DST為1 |
weekday() | 返回date指定的日期是一週的哪天:0代表週一,6代表周天 |
isoweekday() | 返回date指定的日期是一週的哪天:1代表週一,7代表周天 |
isocalendar() | 返回一個named tuple(year , week , weekday) |
isoformat() | 將一個date轉化為"YYYY-MM-DD"的String型別 |
__str__() |
這個方法說明該date物件可以用str()字串化,即通過str(d)將d轉化為字串; 等同於d.isoformat() |
ctime() | 跟time.ctime()相同,只是除了年月日外的變數都是0 |
strftime(format) | 根據format指定的格式,將date轉化為String;hour、minute、second都會轉為0 |
例子
計算到某個日期的天數差:
from datetime import date today=date.today() my_birthday=date(today.year,5,24) if my_birthday < today:#如果生日已經過完 my_birthday=my_birthday.replace(year=today.year+1) time2birthday=my_birthday-today print(time2birthday.days)
time
time物件代表了一個獨立的時間。如果想要與真實的時間關聯(比如“北京 12:00”),需要通過tzinfo物件。
建構函式
time( hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0 )
所有的引數都是可選的;引數tzinfo要麼是None,要麼是tzinfo物件;其他引數必須是整數而且必須在指定的範圍內:
- 0 <= hour < 24;
- 0 <= minute < 60;
- 0 <= second <60;
- 0 <= microsecond < 1000000;
- fold in [ 0 , 1 ];
類屬性:用法time.xxx
resolution | 精度,timedelta(microseconds=1) |
物件屬性:用法t.xxx
hour | 時 |
minute | 分 |
second | 秒 |
microsecond | 微秒 |
tzinfo | 時空資訊 |
需要注意的是,tzinfo標識一個time物件是“感知型”還是“簡單型”,沒有tzinfo屬性(“簡單型”)和有tzinfo屬性(“感知型”)的兩個time無法比較。
如果兩個time都有tzinfo屬性,表明它們都是“感知型”。如果它們的tzinfo屬性相同,那麼在比較時會忽略tzinfo而只比較基本時間;如果它們的tzinfo不同,那麼它們在比較時會轉化為UTC時間再進行比較。
類方法:用法time.xxx(...)
方法 | 返回值 | 說明 |
fromisoformat(str) | time | 返回一個格式為"HH[:MM[:SS[.fff[fff]]]] [+HH:MM[:SS[.ffffff]]]"的string對應的time物件,前邊每一個中括號[ ]都代表一個可省略項 |
例項方法:用法t.xxx(...)
方法 | 返回值 | 說明 |
replace( hour=self.hour,minute=self.minute,second=self.second, microsecond=self.microsecond,tzinfo=self.tzinfo,*,fold=0 ) |
time | 用引數中指定的time屬性代替原time中的指定屬性,構成新的time,沒指定屬性則會直接用原time的屬性 |
isoformat(timespec='auto') | string |
以ISO格式返回一個time對應的string; ISO格式: microsecond != 0時——HH:MM:SS.ffffff microsecond == 0 時——HH:MM:SS 引數timespec指定了具體的ISO格式,一般情況下用"auto"就夠了,其他的引數可以去官方文件中自行檢視 |
__str__() | 因為實現了這個方法,所以可以直接用str(t)將time物件t字串化,功能和isoformat()相同 | |
strftime(format) | string | 返回一個format格式指定的time對應的string |
utcoffset() | None或timedelta |
如果tzinfo是None,就返回None 否則返回self.tzinfo.utcoffset(None),這是一個timedelta物件 |
dst() |
None或timeleta |
如果tzinfo是None,就返回None 否則返回self.tzinfo.dst(None),這是一個timedelta物件 |
tzname() | None或string |
如果tzinfo為None,則返回None 否則返回self.tzinfo.tzname(None),這是一個string |
此外,格式化字串時也可以提取time物件的屬性之一進行格式化:
'{:%H:%M}'.format(t) '12:10'
第一個:是格式化字串的標誌,第二個:是時間屬性分隔符。
例子
time.fromisoformat( str )
from datetime import time
time.fromisoformat('04:23:01') datetime.time(4, 23, 1)
time.fromisoformat('04:23:01.000384') datetime.time(4, 23, 1, 384)
time.fromisoformat('04:23:01+04:00') datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
time物件的相關方法
from datetime import time,tzinfo,timedelta class TZ1(tzinfo): #TZ1是tzinfo的子類 def utcoffset(self,dt): return timedelta(hours=1) def dst(self,dt): return timedelta(0) def tzname(self,dt): return '+01:00' def __repr__(self): return f'{self.__class__.__name__}()' t = time(12,10,30,tzinfo=TZ1()) t datetime.time(12, 10, 30, tzinfo=TZ1()) t.isoformat() '12:10:30+01:00' t.dst() datetime.timedelta(0) t.tzname() '+01:00' t.strftime("%H:%M%S %Z") '12:10:30 +01:00' 'The {} is {:%H:%M}'.format('time',t) 'The time is 12:10'
datetime
datetime物件同時包含了time和date資訊。
建構函式
datetime.datetime( year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0 )
各項的範圍:
-
MINYEAR<=year<=MAXYEAR
, -
1<=month<=12
, -
1<=day<=numberofdaysinthegivenmonthandyear
, -
0<=hour<24
, -
0<=minute<60
, -
0<=second<60
, -
0<=microsecond<1000000
, -
foldin[0,1]
.
類方法:用法datetime.xxx( ... )
類方法 | 返回值 | 說明 |
today() | datetime |
返回本地datetime,其中tzinfo=None; 等同於datetime.fromtimestamp( time.time()) |
now(tz=None) | datetime | 類似today(),只是可以指定tzinfo |
utcnow() | datetime | UTC datetime,其中tzinfo=None |
fromtimestamp(timestamp,tz=None) | datetime | 返回timestamp對應的datetime,可指定tzinfo |
utcfromtimestamp(timestamp) | datetime | 返回timestamp對應的UTC datetime |
combine(date,time,tzinfo=self.tzinfo) | datetime | 將一個date和time結合成為一個datetime |
fromisoformat(date_string) | datetime |
返回string對應的datetime string格式為: YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]] *號處可以用任何一個字元 |
fromisocalendar(year,week,day) | datetime | 返回一個ISO Calendar對應的datetime |
strptime(date_string,format) | datetime |
返回由format指定的date_string對應的datetime 等同於datetime(*(time.strptime(date_string,format)[0:6])) |
關於fromisoformat的例子:
>>> from datetime import datetime
>>> datetime.fromisoformat('2011-11-04') datetime.datetime(2011, 11, 4, 0, 0)
>>> datetime.fromisoformat('2011-11-04T00:05:23') datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('2011-11-04T00:05:23+04:00') datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
類屬性
time.resolution:精度,預設timedelta( microsecond=1 )
物件屬性:用法t.xxx
year | 年 |
month | 月 |
day | 日 |
hour | 時 |
minute | 分 |
second | 秒 |
microsecond | 微秒 |
tzinfo | tzinfo物件 |
運算
datetime2 = datetime1 + timedelta |
datetime2 = datetime1 - timedelta |
timedelta = datetime1 - datetime2 |
datetime1 < datetime2 |
例項方法:用法t.xxx(...)
方法 | 返回型別 | 說明 |
date() | date | 返回組成該datetime的date物件,包括year、month、day屬性 |
time() | time | 返回組成該datetime的time物件,包括hour、minute、second、microsecond、fold、tzinfo=None |
timetz() | time | 返回組成該datetime的time物件,包括上一個函式所說的那些屬性,其中tzinfo是datetime的tzinfo |
replace(...) | datetime | 返回一個用某些屬性代替原屬性的datetime,沒有修改的屬性將採用原屬性 |
astimezone(tz=None) | datetime | 修改tzinfo屬性,date和time同樣會修改為對應時區的date與time |
utcoffset | None或timedelta |
如果tzinfo是None,則返回None 否則返回self.tzinfo.utcoffset(self) |
dst() | None或timedelta |
如果tzinfo是None,則返回None 否則返回self.tzinfo.dst(self) |
tzname() | None或string |
如果tzinfo是None,則返回None 否則返回self.tzinfo.tzname(self) |
timetuple() | time.struct_time |
等價於返回該datetime對應的time.struct_time,即 time.struct_time(( d.year, d.month, d.day, d.hour, d.minute, d.second, d.weekday(), yday, dst)) |
utctimetuple() | time.struct_time |
轉化為UTC時間下的struct_time; 如果tzinfo=None,則等同於timetuple()函式 |
timestamp() | timestamp | 返回該datetime對應的timestamp |
weekday() | int | 返回datetime對應一週的哪天(週一到周天 0-6) |
isoweekday() | int | 返回datetime對應一週的哪天(週一到周天 1-7) |
isocalendar() | named tuple |
返回有著三元素的named tuple(year , week , weekday) 等同於方法self.date().isocalendar() |
isoformat(sep='T',timespec='auto') | string |
返回datetime對應的string,format採用ISO format: 當microsecond != 0時,YYYY-MM-DDTHH:MM:SS.ffffff 當microsecond == 0時,YYYY-MM-DDTHH:MM:SS 還有有tzinfo的形式,這裡不表,有需要的可以自行去官網檢視 引數sep預設是'T',表示date和time間的分隔符 |
__str__() |
實現了這個方法,就可以直接用str(d)的方式將datetime字串化 結果等同於d.isoformat(' ')用' '將date和time分隔開來 |
|
ctime() | string | 返回datetime對應的string,類似'Wed Dec 4 20:30:40 2002'這種 |
strftime(format) | string | 返回datetime對應的string,可以指定格式 |
__format__(format) | string | 實現了這個功能,就可以直接用一個datetime對一個string進行格式化(見下邊的最後一個例子) |
例子
from datetime import datetime,date,time d=date(2005,7,14) t=time(12,30) datetime.combine(d,t) datetime.datetime(2005, 7, 14, 12, 30) datetime.now() datetime.datetime(2021, 6, 10, 15, 24, 1, 58813) dt = datetime.strptime("21/11/06 16:30","%d/%m/%y %H:%M") dt datetime.datetime(2006, 11, 21, 16, 30) tt=dt.timetuple() tt time.struct_time(tm_year=2006, tm_mon=11, tm_mday=21, tm_hour=16, tm_min=30, tm_sec=0, tm_wday=1, tm_yday=325, tm_isdst=-1) ic = dt.isocalendar() ic (2006, 47, 2) dt.strftime("%A, %d. %B %Y %I:%M%p") 'Tuesday, 21. November 2006 04:30PM' 'The {1} is {0:%d},the {2} is {0:%B}, the {3} is {0:%I:%M%p}'.format(dt,'day','month','year') 'The day is 21,the month is November, the year is 04:30PM'