1. 程式人生 > 其它 >Python:datetime

Python:datetime

學習自:datetime — Basic date and time types — Python 3.10.0b2 documentation

datetime模組用於操作datetime

datetime物件可以分成“感知型”“簡單型”兩種,分類方法取決於這類物件是否包含時區(timezone)資訊。

感知型,代表了一個特定的有意義的時間,比如“北京12:03”、“莫斯科 7:03”

簡單型,並不包含任何的定位資訊,只是表明用於計算的時間,比如“這段路程花費了2小時14分36秒”

在使用“感知型”時間時,datetimetime物件需要包含時區資訊,即在構建這類物件時設定引數tzinfo

,即time zone infomation

Class

  1. datetime.date:日期類,只有year、month、day三個引數;
  2. datetime.time:時間類,引數包含hour、minute、second、microsecond、tzinfo
  3. datetime.datetime:時間和日期的結合,引數有year、month、day、hour、minute、second、microsecond、tzinfo
  4. datetime.timedelta:兩個date、time、datetime間的時間間隔;
  5. datetime.tzinfo:包含時空資訊的抽象類,經常被datetime
    time用於時間轉化
  6. datetime.timezone:用UTC時間實現tzinfo抽象類的類;

這些類的繼承關係:

timedelta
tzinfo        -> timezone
time
date         -> datetime

確定一個class是“感知型”還是“簡單型”

date物件一定是“簡單型”

time、datetime可能是這兩種型別,那麼如何判斷呢?

“感知型” datetimetime物件x

  1. x.tzinfo 不是None
  2. 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物件也支援加減datedatetime物件。

此外,也支援兩個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

如果tzinfoNone,則返回None

否則返回self.tzinfo.utcoffset(self)

dst() None或timedelta

如果tzinfoNone,則返回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',表示datetime間的分隔符

__str__()

實現了這個方法,就可以直接用str(d)的方式將datetime字串化

結果等同於d.isoformat(' ')' 'datetime分隔開來

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'