datetime
— 基本的日期和時間型別¶
原始碼: Lib/datetime.py
datetime
模組提供了用於處理日期和時間的類。
雖然支援日期和時間算術運算,但實現的重點是高效的屬性提取,以用於輸出格式化和操作。
提示
跳轉到 格式化程式碼。
參見
感知型和幼稚型物件¶
日期和時間物件可以分為“感知型 (aware)”或“幼稚型 (naive)”兩類,取決於它們是否包含時區資訊。
透過充分了解適用的演算法和政治性時間調整,例如時區和夏令時資訊,一個 感知型 (aware) 物件可以確定自身相對於其他感知型物件的位置。一個感知型物件代表一個確切的時間點,沒有解釋的餘地。[1]
一個 幼稚型 (naive) 物件不包含足夠的資訊來明確地確定其相對於其他日期/時間物件的位置。幼稚型物件是表示協調世界時 (UTC)、本地時間還是其他時區的時間完全取決於程式,就像程式決定一個特定的數字是表示米、英里還是質量一樣。幼稚型物件易於理解和使用,但代價是忽略了現實世界的某些方面。
對於需要感知型物件的應用程式,datetime
和 time
物件有一個可選的時區資訊屬性 tzinfo
,可以將其設定為抽象 tzinfo
類的子類的例項。這些 tzinfo
物件捕獲有關 UTC 時間偏移、時區名稱以及夏令時是否有效的資訊。
datetime
模組只提供了一個具體的 tzinfo
類,即 timezone
類。timezone
類可以表示與 UTC 有固定偏移量的簡單時區,例如 UTC 本身或北美的 EST 和 EDT 時區。支援更深層次細節的時區取決於應用程式。世界各地的時間調整規則更多是政治性的而非理性的,而且經常變化,除了 UTC 之外,沒有適用於每個應用的標準。
常量¶
datetime
模組匯出以下常量:
- datetime.UTC¶
UTC 時區單例
datetime.timezone.utc
的別名。在 3.11 版本中新增。
可用的型別¶
- class datetime.time
一個理想化的時間,與任何特定的日期無關,假設每天恰好有 24*60*60 秒。(這裡沒有“閏秒”的概念。)屬性:
hour
、minute
、second
、microsecond
和tzinfo
。
- class datetime.timezone
一個實現了
tzinfo
抽象基類的類,表示與 UTC 的固定偏移量。在 3.2 版本加入。
這些型別的物件是不可變的。
子類關係
object
timedelta
tzinfo
timezone
time
date
datetime
共同屬性¶
判斷物件是感知型還是幼稚型¶
date
型別的物件總是幼稚型的。
time
或 datetime
型別的物件可能是感知型或幼稚型。
一個 datetime
物件 d
是感知型的,如果以下兩個條件都成立:
d.tzinfo
不為None
d.tzinfo.utcoffset(d)
不返回None
否則,d
是幼稚型的。
一個 time
物件 t
是感知型的,如果以下兩個條件都成立:
t.tzinfo
不為None
t.tzinfo.utcoffset(None)
不返回None
。
否則,t
是幼稚型的。
感知型和幼稚型之間的區別不適用於 timedelta
物件。
timedelta
物件¶
一個 timedelta
物件表示一個持續時間,即兩個 datetime
或 date
例項之間的差值。
- class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)¶
所有引數都是可選的,預設為 0。引數可以是整數或浮點數,可以是正數或負數。
內部只儲存 days、seconds 和 microseconds。引數會轉換為這些單位:
1 毫秒轉換為 1000 微秒。
1 分鐘轉換為 60 秒。
1 小時轉換為 3600 秒。
1 週轉換為 7 天。
然後對天、秒和微秒進行標準化,以使表示唯一,其中:
0 <= microseconds < 1000000
0 <= seconds < 3600*24
(一天中的秒數)-999999999 <= days <= 999999999
以下示例說明了除 days、seconds 和 microseconds 之外的任何引數是如何被“合併”並標準化為這三個結果屬性的:
>>> from datetime import timedelta >>> delta = timedelta( ... days=50, ... seconds=27, ... microseconds=10, ... milliseconds=29000, ... minutes=5, ... hours=8, ... weeks=2 ... ) >>> # Only days, seconds, and microseconds remain >>> delta datetime.timedelta(days=64, seconds=29156, microseconds=10)
如果任何引數是浮點數並且存在小數微秒,則來自所有引數的小數微秒會被合併,它們的和會使用四捨六入五成雙的規則舍入到最近的微秒。如果沒有引數是浮點數,轉換和標準化過程是精確的(不會丟失資訊)。
如果標準化的天數值超出了指定範圍,則會引發
OverflowError
。請注意,負值的標準化起初可能令人驚訝。例如:
>>> from datetime import timedelta >>> d = timedelta(microseconds=-1) >>> (d.days, d.seconds, d.microseconds) (-1, 86399, 999999)
由於
timedelta
物件的字串表示形式可能會令人困惑,請使用以下方法生成更易讀的格式:>>> def pretty_timedelta(td): ... if td.days >= 0: ... return str(td) ... return f'-({-td!s})' ... >>> d = timedelta(hours=-1) >>> str(d) # not human-friendly '-1 day, 23:00:00' >>> pretty_timedelta(d) '-(1:00:00)'
類屬性:
- timedelta.max¶
最正的
timedelta
物件,timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999)
。
注意,由於標準化,timedelta.max
大於 -timedelta.min
。-timedelta.max
不能表示為 timedelta
物件。
例項屬性(只讀):
- timedelta.days¶
介於 -999,999,999 和 999,999,999 之間(含)。
- timedelta.seconds¶
介於 0 和 86,399 之間(含)。
注意
一個常見的錯誤是,程式碼在實際上想獲取
total_seconds()
值時,無意中使用了這個屬性:>>> from datetime import timedelta >>> duration = timedelta(seconds=11235813) >>> duration.days, duration.seconds (130, 3813) >>> duration.total_seconds() 11235813.0
- timedelta.microseconds¶
介於 0 和 999,999 之間(含)。
支援的操作:
操作 |
結果 |
---|---|
|
|
|
|
|
時間差乘以一個整數。之後,當 |
通常, |
|
|
時間差乘以一個浮點數。結果會使用四捨六入五成雙的規則舍入到 timedelta.resolution 的最近倍數。 |
|
總持續時間 |
|
時間差除以一個浮點數或整數。結果會使用四捨六入五成雙的規則舍入到 timedelta.resolution 的最近倍數。 |
|
計算向下取整的結果,並丟棄餘數(如果有的話)。在第二種情況下,返回一個整數。(3) |
|
餘數以 |
|
計算商和餘數: |
|
返回一個值相同的 |
|
等價於 |
|
當 |
|
返回一個格式為 |
|
返回一個 |
備註
這是精確的,但可能溢位。
這是精確的,不會溢位。
除以零會引發
ZeroDivisionError
。-timedelta.max
不能表示為一個timedelta
物件。timedelta
物件的字串表示形式與其內部表示類似地進行標準化。這導致負的 timedelta 出現一些不尋常的結果。例如:>>> timedelta(hours=-5) datetime.timedelta(days=-1, seconds=68400) >>> print(_) -1 day, 19:00:00
表示式
t2 - t3
將總是等於表示式t2 + (-t3)
,除非 t3 等於timedelta.max
;在這種情況下,前者會產生一個結果,而後者會溢位。
除了上面列出的操作外,timedelta
物件還支援與 date
和 datetime
物件的某些加法和減法運算(見下文)。
在 3.2 版本發生變更: 現在支援一個 timedelta
物件與另一個 timedelta
物件的整除和真除法,以及取餘運算和 divmod()
函式。現在支援一個 timedelta
物件與一個 float
物件的真除法和乘法。
timedelta
物件支援相等和順序比較。
在布林上下文中,一個 timedelta
物件當且僅當它不等於 timedelta(0)
時被認為是真的。
例項方法:
- timedelta.total_seconds()¶
返回持續時間中包含的總秒數。等價於
td / timedelta(seconds=1)
。對於除秒之外的時間間隔單位,直接使用除法形式(例如td / timedelta(microseconds=1)
)。注意,對於非常大的時間間隔(在大多數平臺上大於 270 年),此方法將失去微秒精度。
在 3.2 版本加入。
用法示例:timedelta
¶
一個額外的標準化示例:
>>> # Components of another_year add up to exactly 365 days
>>> 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
物件表示一個理想化日曆中的日期(年、月、日),即當前的公曆(格里高利曆)向兩個方向無限延伸。
公元 1 年 1 月 1 日被稱為第 1 天,公元 1 年 1 月 2 日被稱為第 2 天,以此類推。[2]
- class datetime.date(year, month, day)¶
所有引數都是必需的。引數必須是整數,且在以下範圍內:
MINYEAR <= year <= MAXYEAR
1 <= month <= 12
1 <= day <= 給定月份和年份的天數
如果給定的引數超出這些範圍,會引發
ValueError
。
其他建構函式,均為類方法:
- classmethod date.today()¶
返回當前的本地日期。
這等價於
date.fromtimestamp(time.time())
。
- classmethod date.fromtimestamp(timestamp)¶
返回與 POSIX 時間戳對應的本地日期,例如
time.time()
返回的時間戳。如果時間戳超出了平臺 C 語言
localtime()
函式支援的值範圍,可能會引發OverflowError
;如果localtime()
失敗,則會引發OSError
。通常,這被限制在 1970 年到 2038 年之間。請注意,在非 POSIX 系統中,如果時間戳概念包含閏秒,fromtimestamp()
會忽略閏秒。在 3.3 版本發生變更: 如果時間戳超出了平臺 C 語言
localtime()
函式支援的值範圍,則引發OverflowError
而非ValueError
。如果localtime()
失敗,則引發OSError
而非ValueError
。
- classmethod date.fromordinal(ordinal)¶
返回對應於前推公曆序數的日期,其中公元 1 年 1 月 1 日的序數為 1。
除非
1 <= ordinal <= date.max.toordinal()
,否則會引發ValueError
。對於任何日期d
,date.fromordinal(d.toordinal()) == d
。
- classmethod date.fromisoformat(date_string)¶
返回一個與 date_string 對應的
date
物件,該字串以任何有效的 ISO 8601 格式給出,但有以下例外:目前不支援降低精度的日期(
YYYY-MM
,YYYY
)。目前不支援擴充套件日期表示法(
±YYYYYY-MM-DD
)。目前不支援序數日期(
YYYY-OOO
)。
示例:
>>> from datetime import date >>> date.fromisoformat('2019-12-04') datetime.date(2019, 12, 4) >>> date.fromisoformat('20191204') datetime.date(2019, 12, 4) >>> date.fromisoformat('2021-W01-1') datetime.date(2021, 1, 4)
在 3.7 版本加入。
在 3.11 版本發生變更: 以前,此方法僅支援
YYYY-MM-DD
格式。
- classmethod date.fromisocalendar(year, week, day)¶
返回一個與由年、周和日指定的 ISO 日曆日期相對應的
date
。這是date.isocalendar()
函式的逆操作。在 3.8 版本加入。
- classmethod date.strptime(date_string, format)¶
返回一個與 date_string 對應的
date
,根據 format 進行解析。這等價於:date(*(time.strptime(date_string, format)[0:3]))
如果 date_string 和 format 無法被
time.strptime()
解析,或者如果它返回的值不是一個時間元組,則會引發ValueError
。另請參見 strftime() 和 strptime() 的行為 和date.fromisoformat()
。備註
如果 format 指定了月份中的某一天但沒有年份,會發出一個
DeprecationWarning
。這是為了避免在尋求僅解析月份和日期的程式碼中出現四年一次的閏年錯誤,因為在格式中缺少年份時使用的預設年份不是閏年。從 Python 3.15 開始,這樣的 format 值可能會引發錯誤。解決方法是在您的 format 中始終包含年份。如果解析的 date_string 值沒有年份,請在解析前明確新增一個閏年:>>> from datetime import date >>> date_string = "02/29" >>> when = date.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug. >>> when.strftime("%B %d") 'February 29'
在 3.14 版本加入。
類屬性:
- date.min¶
最早的可表示日期,
date(MINYEAR, 1, 1)
。
- date.max¶
最晚的可表示日期,
date(MAXYEAR, 12, 31)
。
- date.resolution¶
非相等日期物件之間可能的最小差值,
timedelta(days=1)
。
例項屬性(只讀):
- date.month¶
介於 1 和 12 之間(含)。
- date.day¶
介於 1 和給定年份給定月份的天數之間。
支援的操作:
操作 |
結果 |
---|---|
|
|
|
計算 |
|
(3) |
date1 == date2 date1 != date2 |
相等性比較。(4) |
date1 < date2 date1 > date2 date1 <= date2 date1 >= date2 |
順序比較。(5) |
備註
如果
timedelta.days > 0
,date2 會在時間上向前移動;如果timedelta.days < 0
,則向後移動。之後date2 - date1 == timedelta.days
。timedelta.seconds
和timedelta.microseconds
被忽略。如果date2.year
小於MINYEAR
或大於MAXYEAR
,則會引發OverflowError
。timedelta.seconds
和timedelta.microseconds
被忽略。這是精確的,不會溢位。
timedelta.seconds
和timedelta.microseconds
為 0,並且之後date2 + timedelta == date1
。如果兩個
date
物件表示相同的日期,則它們相等。非
datetime
例項的date
物件永遠不等於datetime
物件,即使它們表示相同的日期。當 date1 在時間上先於 date2 時,date1 被認為小於 date2。換句話說,
date1 < date2
當且僅當date1.toordinal() < date2.toordinal()
。
在 3.13 版本發生變更: datetime
物件與非 datetime
子類的 date
子類的例項之間的比較,不再將後者轉換為 date
,從而忽略時間部分和時區。可以透過在子類中重寫特殊的比較方法來更改預設行為。
在布林上下文中,所有 date
物件都被認為是真的。
例項方法:
- date.replace(year=self.year, month=self.month, day=self.day)¶
返回一個具有相同值的新
date
物件,但更新了指定的引數。示例
>>> from datetime import date >>> d = date(2002, 12, 31) >>> d.replace(day=26) datetime.date(2002, 12, 26)
通用函式
copy.replace()
也支援date
物件。
- date.timetuple()¶
返回一個
time.struct_time
,類似於time.localtime()
返回的型別。小時、分鐘和秒為 0,DST 標誌為 -1。
d.timetuple()
等價於:time.struct_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1))
其中
yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1
是當前年份中的天數,1 月 1 日為 1。
- date.toordinal()¶
返回日期的前推公曆序數,其中公元 1 年 1 月 1 日的序數為 1。對於任何
date
物件d
,date.fromordinal(d.toordinal()) == d
。
- date.weekday()¶
以整數形式返回星期幾,其中星期一為 0,星期日為 6。例如,
date(2002, 12, 4).weekday() == 2
,表示星期三。另請參見isoweekday()
。
- date.isoweekday()¶
以整數形式返回星期幾,其中星期一為 1,星期日為 7。例如,
date(2002, 12, 4).isoweekday() == 3
,表示星期三。另請參見weekday()
、isocalendar()
。
- date.isocalendar()¶
返回一個包含三個元件的命名元組物件:
year
、week
和weekday
。ISO 日曆是公曆(格里高利曆)的一種廣泛使用的變體。[3]
ISO 年由 52 或 53 個完整週組成,每週從星期一開始,到星期日結束。一個 ISO 年的第一週是一年中包含星期四的第一個(公曆)日曆周。這被稱為第 1 周,該星期四的 ISO 年與其公曆年份相同。
例如,2004 年從星期四開始,所以 ISO 2004 年的第一週從 2003 年 12 月 29 日星期一開始,到 2004 年 1 月 4 日星期日結束:
>>> from datetime import date >>> date(2003, 12, 29).isocalendar() datetime.IsoCalendarDate(year=2004, week=1, weekday=1) >>> date(2004, 1, 4).isocalendar() datetime.IsoCalendarDate(year=2004, week=1, weekday=7)
在 3.9 版本發生變更: 結果從元組更改為命名元組。
- date.isoformat()¶
返回一個表示日期的字串,格式為 ISO 8601,
YYYY-MM-DD
:>>> from datetime import date >>> date(2002, 12, 4).isoformat() '2002-12-04'
- date.__str__()¶
對於一個日期
d
,str(d)
等價於d.isoformat()
。
- date.ctime()¶
返回一個表示日期的字串:
>>> from datetime import date >>> date(2002, 12, 4).ctime() 'Wed Dec 4 00:00:00 2002'
d.ctime()
等價於:time.ctime(time.mktime(d.timetuple()))
在本地 C 語言
ctime()
函式(time.ctime()
會呼叫,但date.ctime()
不會呼叫)符合 C 標準的平臺上。
- date.strftime(format)¶
返回一個表示日期的字串,由顯式格式字串控制。引用小時、分鐘或秒的格式程式碼將看到 0 值。另請參見 strftime() 和 strptime() 的行為 和
date.isoformat()
。
- date.__format__(format)¶
與
date.strftime()
相同。這使得在格式化字串字面量和使用str.format()
時可以為date
物件指定格式字串。另請參見 strftime() 和 strptime() 的行為 和date.isoformat()
。
用法示例:date
¶
計算距離某事件天數的示例:
>>> import time
>>> from datetime import date
>>> today = date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == date.fromtimestamp(time.time())
True
>>> my_birthday = date(today.year, 6, 24)
>>> if my_birthday < today:
... my_birthday = my_birthday.replace(year=today.year + 1)
...
>>> my_birthday
datetime.date(2008, 6, 24)
>>> time_to_birthday = abs(my_birthday - today)
>>> time_to_birthday.days
202
更多使用 date
的示例:
>>> from datetime import date
>>> d = date.fromordinal(730920) # 730920th day after 1. 1. 0001
>>> d
datetime.date(2002, 3, 11)
>>> # Methods related to formatting string output
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'
>>> d.ctime()
'Mon Mar 11 00:00:00 2002'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
'The day is 11, the month is March.'
>>> # Methods for to extracting 'components' under different calendars
>>> t = d.timetuple()
>>> for i in t:
... print(i)
2002 # year
3 # month
11 # day
0
0
0
0 # weekday (0 = Monday)
70 # 70th day in the year
-1
>>> ic = d.isocalendar()
>>> for i in ic:
... print(i)
2002 # ISO year
11 # ISO week number
1 # ISO day number ( 1 = Monday )
>>> # A date object is immutable; all operations produce a new object
>>> d.replace(year=2005)
datetime.date(2005, 3, 11)
datetime
物件¶
一個 datetime
物件是一個包含來自 date
物件和 time
物件所有資訊的單一物件。
像 date
物件一樣,datetime
假設當前的公曆(格里高利曆)向兩個方向無限延伸;像 time
物件一樣,datetime
假設每天恰好有 3600*24 秒。
建構函式:
- class datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)¶
year、month 和 day 引數是必需的。tzinfo 可以是
None
,也可以是tzinfo
子類的例項。其餘引數必須是以下範圍內的整數:MINYEAR <= year <= MAXYEAR
,1 <= month <= 12
,1 <= day <= 給定月份和年份的天數
,0 <= hour < 24
,0 <= minute < 60
,0 <= second < 60
,0 <= microsecond < 1000000
,fold in [0, 1]
.
如果給定的引數超出這些範圍,會引發
ValueError
。在 3.6 版本發生變更: 添加了 fold 引數。
其他建構函式,均為類方法:
- classmethod datetime.today()¶
返回當前的本地日期和時間,
tzinfo
為None
。等價於:
datetime.fromtimestamp(time.time())
另請參見
now()
、fromtimestamp()
。此方法在功能上等同於
now()
,但沒有tz
引數。
- classmethod datetime.now(tz=None)¶
返回當前的本地日期和時間。
如果可選引數 tz 為
None
或未指定,這類似於today()
,但如果可能,它提供的精度比透過time.time()
時間戳獲得的精度更高(例如,在提供 C 語言gettimeofday()
函式的平臺上可能如此)。如果 tz 不為
None
,它必須是tzinfo
子類的例項,並且當前的日期和時間會轉換為 tz 的時區。備註
後續對
datetime.now()
的呼叫可能返回相同的時間點,具體取決於底層時鐘的精度。
- classmethod datetime.utcnow()¶
返回當前的 UTC 日期和時間,
tzinfo
為None
。這類似於
now()
,但返回的是當前的 UTC 日期和時間,作為一個幼稚型datetime
物件。可以透過呼叫datetime.now(timezone.utc)
來獲得一個感知型的當前 UTC 日期時間。另請參見now()
。警告
由於幼稚型
datetime
物件被許多datetime
方法視作本地時間,因此推薦使用感知型 datetime 來表示 UTC 時間。因此,建立表示當前 UTC 時間的物件的推薦方法是呼叫datetime.now(timezone.utc)
。自 3.12 版本起不推薦使用: 請改用帶
UTC
的datetime.now()
。
- classmethod datetime.fromtimestamp(timestamp, tz=None)¶
返回與 POSIX 時間戳對應的本地日期和時間,例如
time.time()
返回的時間戳。如果可選引數 tz 為None
或未指定,時間戳會轉換為平臺的本地日期和時間,返回的datetime
物件是幼稚型的。如果 tz 不為
None
,則它必須是tzinfo
子類的例項,並且時間戳會轉換為 tz 所在的時區。如果時間戳超出了平臺 C 的
localtime()
或gmtime()
函式所支援的值範圍,fromtimestamp()
可能會引發OverflowError
;如果localtime()
或gmtime()
失敗,則會引發OSError
。這個範圍通常被限制在 1970 年到 2038 年之間。請注意,在那些將閏秒包含在其時間戳概念中的非 POSIX 系統上,閏秒會被fromtimestamp()
忽略,因此可能出現兩個相差一秒的時間戳產生相同的datetime
物件。此方法優於utcfromtimestamp()
。在 3.3 版更改: 如果時間戳超出了平臺 C 的
localtime()
或gmtime()
函式支援的值範圍,則會引發OverflowError
而不是ValueError
。如果localtime()
或gmtime()
失敗,則會引發OSError
而不是ValueError
。在 3.6 版更改:
fromtimestamp()
可能會返回fold
屬性設定為 1 的例項。
- classmethod datetime.utcfromtimestamp(timestamp)¶
返回與 POSIX 時間戳對應的 UTC
datetime
,其中tzinfo
為None
。(結果物件是樸素的。)如果時間戳超出了平臺 C 的
gmtime()
函式所支援的值範圍,此方法可能會引發OverflowError
;如果gmtime()
失敗,則會引發OSError
。這個範圍通常被限制在 1970 年到 2038 年之間。要獲取一個感知的
datetime
物件,請呼叫fromtimestamp()
。datetime.fromtimestamp(timestamp, timezone.utc)
在遵循 POSIX 標準的平臺上,它等價於以下表達式:
datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=timestamp)
不同之處在於後者公式總是支援完整的年份範圍:從
MINYEAR
到MAXYEAR
(包含邊界)。警告
由於許多
datetime
方法將樸素的datetime
物件視為本地時間,因此推薦使用感知的 datetime 物件來表示 UTC 時間。因此,建立代表 UTC 特定時間戳的物件的推薦方法是呼叫datetime.fromtimestamp(timestamp, tz=timezone.utc)
。在 3.3 版更改: 如果時間戳超出了平臺 C 的
gmtime()
函式支援的值範圍,則會引發OverflowError
而不是ValueError
。如果gmtime()
失敗,則會引發OSError
而不是ValueError
。自 3.12 版本起棄用: 請改用帶
UTC
的datetime.fromtimestamp()
。
- classmethod datetime.fromordinal(ordinal)¶
返回對應於預期公曆序數的
datetime
,其中第 1 年的 1 月 1 日的序數為 1。除非1 <= ordinal <= datetime.max.toordinal()
,否則會引發ValueError
。結果的小時、分鐘、秒和微秒都為 0,且tzinfo
為None
。
- classmethod datetime.combine(date, time, tzinfo=time.tzinfo)¶
返回一個新的
datetime
物件,其日期部分等於給定的date
物件的日期部分,時間部分等於給定的time
物件的時間部分。如果提供了 tzinfo 引數,其值將用於設定結果的tzinfo
屬性,否則將使用 time 引數的tzinfo
屬性。如果 date 引數是datetime
物件,其時間部分和tzinfo
屬性將被忽略。對於任何
datetime
物件d
,d == datetime.combine(d.date(), d.time(), d.tzinfo)
成立。在 3.6 版更改: 添加了 tzinfo 引數。
- classmethod datetime.fromisoformat(date_string)¶
返回與任何有效的 ISO 8601 格式的 date_string 對應的
datetime
,但有以下例外:時區偏移量可以有小數秒。
T
分隔符可以被任何單個 unicode 字元替換。不支援小數小時和分鐘。
目前不支援降低精度的日期(
YYYY-MM
,YYYY
)。目前不支援擴充套件日期表示法(
±YYYYYY-MM-DD
)。目前不支援序數日期(
YYYY-OOO
)。
示例:
>>> from datetime import datetime >>> datetime.fromisoformat('2011-11-04') datetime.datetime(2011, 11, 4, 0, 0) >>> datetime.fromisoformat('20111104') 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-04T00:05:23Z') datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc) >>> datetime.fromisoformat('20111104T000523') datetime.datetime(2011, 11, 4, 0, 5, 23) >>> datetime.fromisoformat('2011-W01-2T00:05:23.283') datetime.datetime(2011, 1, 4, 0, 5, 23, 283000) >>> 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)))
在 3.7 版本加入。
在 3.11 版更改: 以前,此方法只支援
date.isoformat()
或datetime.isoformat()
可以生成的格式。
- classmethod datetime.fromisocalendar(year, week, day)¶
返回與由年、周和日指定的 ISO 日曆日期相對應的
datetime
。datetime 的非日期部分將使用其正常的預設值填充。這是datetime.isocalendar()
函式的逆操作。在 3.8 版本加入。
- classmethod datetime.strptime(date_string, format)¶
返回一個根據 format 解析 date_string 後得到的
datetime
物件。如果 format 不包含微秒或時區資訊,這等同於:
datetime(*(time.strptime(date_string, format)[0:6]))
如果 date_string 和 format 無法被
time.strptime()
解析,或者它返回的值不是一個時間元組,則會引發ValueError
。另請參見 strftime() 和 strptime() 的行為 和datetime.fromisoformat()
。在 3.13 版更改: 如果 format 指定了月份中的某一天但沒有指定年份,現在會發出一個
DeprecationWarning
。這是為了避免在尋求僅解析月份和日期的程式碼中出現四年一次的閏年錯誤,因為在格式中缺少年份時使用的預設年份不是閏年。這樣的 format 值可能會在 Python 3.15 版本中引發錯誤。解決方法是在你的 format 中始終包含年份。如果解析的 date_string 值沒有年份,請在解析前明確新增一個閏年:>>> from datetime import datetime >>> date_string = "02/29" >>> when = datetime.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug. >>> when.strftime("%B %d") 'February 29'
類屬性:
例項屬性(只讀):
- datetime.month¶
介於 1 和 12 之間(含)。
- datetime.day¶
介於 1 和給定年份給定月份的天數之間。
- datetime.hour¶
在
range(24)
範圍內。
- datetime.minute¶
在
range(60)
範圍內。
- datetime.second¶
在
range(60)
範圍內。
- datetime.microsecond¶
在
range(1000000)
範圍內。
- datetime.fold¶
在
[0, 1]
範圍內。用於在重複的時間區間內消除時鐘時間的歧義。(當夏令時結束時鐘回撥,或當前時區的 UTC 偏移因政治原因減少時,會出現重複的時間區間。)值 0 和 1 分別表示具有相同牆上時鐘時間表示的兩個時刻中較早和較晚的一個。在 3.6 版本加入。
支援的操作:
操作 |
結果 |
---|---|
|
(1) |
|
(2) |
|
(3) |
datetime1 == datetime2 datetime1 != datetime2 |
相等性比較。(4) |
datetime1 < datetime2 datetime1 > datetime2 datetime1 <= datetime2 datetime1 >= datetime2 |
順序比較。(5) |
datetime2
是從datetime1
移除了timedelta
持續時間後的結果,如果timedelta.days > 0
則時間向前移動,如果timedelta.days < 0
則向後移動。結果具有與輸入 datetime 相同的tzinfo
屬性,並且之後datetime2 - datetime1 == timedelta
。如果datetime2.year
會小於MINYEAR
或大於MAXYEAR
,則會引發OverflowError
。請注意,即使輸入是感知的物件,也不會進行時區調整。計算
datetime2
使得datetime2 + timedelta == datetime1
。與加法一樣,結果具有與輸入 datetime 相同的tzinfo
屬性,並且即使輸入是感知的,也不會進行時區調整。從一個
datetime
減去另一個datetime
的操作僅在兩個運算元都是樸素的,或都是感知的情況下才被定義。如果一個是感知的而另一個是樸素的,則會引發TypeError
。如果兩者都是樸素的,或者兩者都是感知的且具有相同的
tzinfo
屬性,那麼tzinfo
屬性將被忽略,結果是一個timedelta
物件t
,使得datetime2 + t == datetime1
。在這種情況下不進行時區調整。如果兩者都是感知的且具有不同的
tzinfo
屬性,a-b
的行為就好像a
和b
首先被轉換成了樸素的 UTC datetime。結果是(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())
,但實現上不會溢位。datetime
物件如果表示相同的日期和時間(考慮到時區),則它們是相等的。樸素和感知的
datetime
物件永遠不相等。如果兩個比較物件都是感知的,並且具有相同的
tzinfo
屬性,那麼tzinfo
和fold
屬性將被忽略,只比較基礎的 datetime。如果兩個比較物件都是感知的,但具有不同的tzinfo
屬性,比較的行為就好像比較物件首先被轉換成了 UTC datetime,但實現上不會溢位。處於重複時間區間內的datetime
例項永遠不等於其他時區中的datetime
例項。當 datetime1 在時間上早於 datetime2 時(考慮到時區),認為 datetime1 小於 datetime2。
在樸素和感知的
datetime
物件之間進行順序比較會引發TypeError
。如果兩個比較物件都是感知的,並且具有相同的
tzinfo
屬性,那麼tzinfo
和fold
屬性將被忽略,只比較基礎的 datetime。如果兩個比較物件都是感知的,但具有不同的tzinfo
屬性,比較的行為就好像比較物件首先被轉換成了 UTC datetime,但實現上不會溢位。
在 3.13 版本發生變更: datetime
物件與非 datetime
子類的 date
子類的例項之間的比較,不再將後者轉換為 date
,從而忽略時間部分和時區。可以透過在子類中重寫特殊的比較方法來更改預設行為。
例項方法:
- datetime.time()¶
返回具有相同小時、分鐘、秒、微秒和 fold 的
time
物件。tzinfo
為None
。另請參見timetz()
方法。在 3.6 版更改: fold 值被複制到返回的
time
物件中。
- datetime.timetz()¶
返回具有相同小時、分鐘、秒、微秒、fold 和 tzinfo 屬性的
time
物件。另請參見time()
方法。在 3.6 版更改: fold 值被複制到返回的
time
物件中。
- datetime.replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)¶
返回一個具有相同屬性的新
datetime
物件,但更新了指定的引數。注意,可以指定tzinfo=None
從一個感知的 datetime 建立一個樸素的 datetime,而無需轉換日期和時間資料。datetime
物件也受通用函式copy.replace()
支援。在 3.6 版本發生變更: 添加了 fold 引數。
- datetime.astimezone(tz=None)¶
返回一個帶有新
tzinfo
屬性 tz 的datetime
物件,並調整日期和時間資料,使結果與 self 表示的 UTC 時間相同,但在 tz 的本地時間中。如果提供了 tz,它必須是
tzinfo
子類的例項,並且其utcoffset()
和dst()
方法不能返回None
。如果 self 是樸素的,則假定它表示系統時區中的時間。如果不帶引數呼叫(或使用
tz=None
),則假定目標時區為系統本地時區。轉換後的 datetime 例項的.tzinfo
屬性將被設定為一個timezone
的例項,其時區名稱和偏移量從作業系統獲取。如果
self.tzinfo
是 tz,則self.astimezone(tz)
等於 self:不執行日期或時間資料的調整。否則,結果是時區 tz 中的本地時間,表示與 self 相同的 UTC 時間:在astz = dt.astimezone(tz)
之後,astz - astz.utcoffset()
將具有與dt - dt.utcoffset()
相同的日期和時間資料。如果你只想將一個
timezone
物件 tz 附加到一個 datetime dt 上,而不調整日期和時間資料,請使用dt.replace(tzinfo=tz)
。如果你只想從一個感知的 datetime dt 中移除timezone
物件,而不轉換日期和時間資料,請使用dt.replace(tzinfo=None)
。請注意,預設的
tzinfo.fromutc()
方法可以在tzinfo
子類中被重寫,以影響astimezone()
返回的結果。忽略錯誤情況,astimezone()
的行為類似於:def astimezone(self, tz): if self.tzinfo is tz: return self # Convert self to UTC, and attach the new timezone object. utc = (self - self.utcoffset()).replace(tzinfo=tz) # Convert from UTC to tz's local time. return tz.fromutc(utc)
在 3.3 版更改: tz 現在可以省略。
在 3.6 版更改:
astimezone()
方法現在可以在被假定為表示系統本地時間的樸素例項上呼叫。
- datetime.utcoffset()¶
如果
tzinfo
是None
,則返回None
,否則返回self.tzinfo.utcoffset(self)
,如果後者沒有返回None
或一個大小小於一天的timedelta
物件,則引發異常。在 3.7 版更改: UTC 偏移量不再限制為整數分鐘。
- datetime.dst()¶
如果
tzinfo
是None
,則返回None
,否則返回self.tzinfo.dst(self)
,如果後者沒有返回None
或一個大小小於一天的timedelta
物件,則引發異常。在 3.7 版更改: DST 偏移量不再限制為整數分鐘。
- datetime.tzname()¶
如果
tzinfo
是None
,則返回None
,否則返回self.tzinfo.tzname(self)
,如果後者沒有返回None
或一個字串物件,則引發異常。
- datetime.timetuple()¶
返回一個
time.struct_time
,類似於time.localtime()
返回的型別。d.timetuple()
等價於:time.struct_time((d.year, d.month, d.day, d.hour, d.minute, d.second, d.weekday(), yday, dst))
其中
yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1
是當前年份中的天數,1 月 1 日為 1。結果的tm_isdst
標誌根據dst()
方法設定:如果tzinfo
是None
或dst()
返回None
,則tm_isdst
設定為-1
;否則如果dst()
返回一個非零值,tm_isdst
設定為 1;否則tm_isdst
設定為 0。
- datetime.utctimetuple()¶
如果
datetime
例項d
是樸素的,這與d.timetuple()
相同,只是無論d.dst()
返回什麼,tm_isdst
都會被強制為 0。UTC 時間永遠不會有夏令時。如果
d
是感知的,d
會透過減去d.utcoffset()
被標準化為 UTC 時間,並返回標準化時間的time.struct_time
。tm_isdst
被強制為 0。請注意,如果d.year
是MINYEAR
或MAXYEAR
並且 UTC 調整跨越了年份邊界,可能會引發OverflowError
。警告
因為許多
datetime
方法將樸素的datetime
物件視為本地時間,所以推薦使用感知的 datetime 來表示 UTC 時間;因此,使用datetime.utctimetuple()
可能會產生誤導性的結果。如果你有一個表示 UTC 的樸素datetime
,使用datetime.replace(tzinfo=timezone.utc)
使其變為感知的,然後你就可以使用datetime.timetuple()
了。
- datetime.toordinal()¶
返回日期的預期公曆序數。與
self.date().toordinal()
相同。
- datetime.timestamp()¶
返回與
datetime
例項對應的 POSIX 時間戳。返回值是一個float
,類似於time.time()
返回的值。樸素的
datetime
例項被假定為表示本地時間,此方法依賴於平臺 C 的mktime()
函式來執行轉換。由於datetime
在許多平臺上支援的值範圍比mktime()
更廣,對於遙遠的過去或未來的時間,此方法可能會引發OverflowError
或OSError
。對於感知的
datetime
例項,返回值的計算方式為:(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()
在 3.3 版本加入。
在 3.6 版更改:
timestamp()
方法使用fold
屬性來消除重複時間區間內的歧義。備註
沒有方法可以直接從一個表示 UTC 時間的樸素
datetime
例項獲取 POSIX 時間戳。如果你的應用程式使用這種約定,並且你的系統時區未設定為 UTC,你可以透過提供tzinfo=timezone.utc
來獲取 POSIX 時間戳:timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
或者直接計算時間戳:
timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
- datetime.weekday()¶
返回星期幾的整數表示,其中星期一為 0,星期日為 6。與
self.date().weekday()
相同。另請參見isoweekday()
。
- datetime.isoweekday()¶
返回星期幾的整數表示,其中星期一為 1,星期日為 7。與
self.date().isoweekday()
相同。另請參見weekday()
、isocalendar()
。
- datetime.isoformat(sep='T', timespec='auto')¶
返回一個表示 ISO 8601 格式的日期和時間的字串:
YYYY-MM-DDTHH:MM:SS.ffffff
,如果microsecond
不為 0YYYY-MM-DDTHH:MM:SS
,如果microsecond
為 0
如果
utcoffset()
不返回None
,則會追加一個字串,給出 UTC 偏移量:YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]
,如果microsecond
不為 0YYYY-MM-DDTHH:MM:SS+HH:MM[:SS[.ffffff]]
,如果microsecond
為 0
示例:
>>> from datetime import datetime, timezone >>> datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat() '2019-05-18T15:17:08.132263' >>> datetime(2019, 5, 18, 15, 17, tzinfo=timezone.utc).isoformat() '2019-05-18T15:17:00+00:00'
可選引數 sep(預設為
'T'
)是一個單字元分隔符,放在結果的日期和時間部分之間。例如:>>> from datetime import tzinfo, timedelta, datetime >>> class TZ(tzinfo): ... """A time zone with an arbitrary, constant -06:39 offset.""" ... def utcoffset(self, dt): ... return timedelta(hours=-6, minutes=-39) ... >>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ') '2002-12-25 00:00:00-06:39' >>> datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat() '2009-11-27T00:00:00.000100-06:39'
可選引數 timespec 指定要包含的時間的附加元件數量(預設為
'auto'
)。它可以是以下之一:'auto'
:如果microsecond
為 0,則與'seconds'
相同,否則與'microseconds'
相同。'hours'
:以兩位數的HH
格式包含hour
。'milliseconds'
:包含完整時間,但將小數秒部分截斷到毫秒。HH:MM:SS.sss
格式。'microseconds'
:以HH:MM:SS.ffffff
格式包含完整時間。
備註
被排除的時間部分會被截斷,而不是四捨五入。
對於無效的 timespec 引數,將引發
ValueError
。>>> from datetime import datetime >>> datetime.now().isoformat(timespec='minutes') '2002-12-25T00:00' >>> dt = datetime(2015, 1, 1, 12, 30, 59, 0) >>> dt.isoformat(timespec='microseconds') '2015-01-01T12:30:59.000000'
在 3.6 版更改: 添加了 timespec 引數。
- datetime.ctime()¶
返回一個表示日期和時間的字串:
>>> from datetime import datetime >>> datetime(2002, 12, 4, 20, 30, 40).ctime() 'Wed Dec 4 20:30:40 2002'
輸出字串將*不*包含時區資訊,無論輸入是感知的還是樸素的。
d.ctime()
等價於:time.ctime(time.mktime(d.timetuple()))
在原生 C
ctime()
函式(time.ctime()
會呼叫,但datetime.ctime()
不會呼叫)符合 C 標準的平臺上。
- datetime.strftime(format)¶
返回一個由顯式格式字串控制的表示日期和時間的字串。另請參見 strftime() 和 strptime() 的行為 和
datetime.isoformat()
。
- datetime.__format__(format)¶
與
datetime.strftime()
相同。這使得在格式化字串字面值中以及使用str.format()
時可以為datetime
物件指定格式字串。另請參見 strftime() 和 strptime() 的行為 和datetime.isoformat()
。
使用示例:datetime
¶
使用 datetime
物件的示例:
>>> from datetime import datetime, date, time, timezone
>>> # Using datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)
>>> # Using datetime.now()
>>> datetime.now()
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043) # GMT +1
>>> datetime.now(timezone.utc)
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060, tzinfo=datetime.timezone.utc)
>>> # Using datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)
>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = dt.timetuple()
>>> for it in tt:
... print(it)
...
2006 # year
11 # month
21 # day
16 # hour
30 # minute
0 # second
1 # weekday (0 = Monday)
325 # number of days since 1st January
-1 # dst - method tzinfo.dst() returned None
>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> for it in ic:
... print(it)
...
2006 # ISO year
47 # ISO week
2 # ISO weekday
>>> # Formatting a datetime
>>> 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", "time")
'The day is 21, the month is November, the time is 04:30PM.'
下面的示例定義了一個 tzinfo
子類,用於捕獲阿富汗喀布林的時區資訊,該地區在 1945 年之前使用 UTC+4,之後使用 UTC+4:30:
from datetime import timedelta, datetime, tzinfo, timezone
class KabulTz(tzinfo):
# Kabul used +4 until 1945, when they moved to +4:30
UTC_MOVE_DATE = datetime(1944, 12, 31, 20, tzinfo=timezone.utc)
def utcoffset(self, dt):
if dt.year < 1945:
return timedelta(hours=4)
elif (1945, 1, 1, 0, 0) <= dt.timetuple()[:5] < (1945, 1, 1, 0, 30):
# An ambiguous ("imaginary") half-hour range representing
# a 'fold' in time due to the shift from +4 to +4:30.
# If dt falls in the imaginary range, use fold to decide how
# to resolve. See PEP495.
return timedelta(hours=4, minutes=(30 if dt.fold else 0))
else:
return timedelta(hours=4, minutes=30)
def fromutc(self, dt):
# Follow same validations as in datetime.tzinfo
if not isinstance(dt, datetime):
raise TypeError("fromutc() requires a datetime argument")
if dt.tzinfo is not self:
raise ValueError("dt.tzinfo is not self")
# A custom implementation is required for fromutc as
# the input to this function is a datetime with utc values
# but with a tzinfo set to self.
# See datetime.astimezone or fromtimestamp.
if dt.replace(tzinfo=timezone.utc) >= self.UTC_MOVE_DATE:
return dt + timedelta(hours=4, minutes=30)
else:
return dt + timedelta(hours=4)
def dst(self, dt):
# Kabul does not observe daylight saving time.
return timedelta(0)
def tzname(self, dt):
if dt >= self.UTC_MOVE_DATE:
return "+04:30"
return "+04"
使用上面的 KabulTz
:
>>> tz1 = KabulTz()
>>> # Datetime before the change
>>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1)
>>> print(dt1.utcoffset())
4:00:00
>>> # Datetime after the change
>>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1)
>>> print(dt2.utcoffset())
4:30:00
>>> # Convert datetime to another time zone
>>> dt3 = dt2.astimezone(timezone.utc)
>>> dt3
datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc)
>>> dt2
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=KabulTz())
>>> dt2 == dt3
True
time
物件¶
一個 time
物件表示一天中的(本地)時間,與任何特定日期無關,並可透過 tzinfo
物件進行調整。
- class datetime.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]
.
如果給出的引數超出這些範圍,則會引發
ValueError
。除了 tzinfo 預設為None
之外,所有引數都預設為 0。
類屬性:
例項屬性(只讀):
- time.hour¶
在
range(24)
範圍內。
- time.minute¶
在
range(60)
範圍內。
- time.second¶
在
range(60)
範圍內。
- time.microsecond¶
在
range(1000000)
範圍內。
- time.fold¶
在
[0, 1]
範圍內。用於在重複的時間區間內消除時鐘時間的歧義。(當夏令時結束時鐘回撥,或當前時區的 UTC 偏移因政治原因減少時,會出現重複的時間區間。)值 0 和 1 分別表示具有相同牆上時鐘時間表示的兩個時刻中較早和較晚的一個。在 3.6 版本加入。
time
物件支援相等性和順序比較,當 a
在時間上早於 b
時,認為 a
小於 b
。
簡單 time
物件和感知 time
物件永遠不相等。 簡單和感知 time
物件之間的大小比較會引發 TypeError
。
如果兩個比較物件都是感知的,並且具有相同的 tzinfo
屬性,則會忽略 tzinfo
和 fold
屬性,並比較基礎時間。如果兩個比較物件都是感知的,但具有不同的 tzinfo
屬性,則首先透過減去它們的 UTC 偏移量(從 self.utcoffset()
獲得)來調整比較物件。
在布林上下文中,time
物件總是被視為真值。
在 3.5 版更改: 在 Python 3.5 之前,如果一個 time
物件代表 UTC 的午夜,則它被認為是假值。此行為被認為是晦澀且容易出錯的,並在 Python 3.5 中被移除。有關完整詳細資訊,請參閱 bpo-13936。
其他構造器
- classmethod time.fromisoformat(time_string)¶
返回一個與 time_string 對應的
time
物件,該字串可以是任何有效的 ISO 8601 格式,但有以下例外:時區偏移量可以有小數秒。
前導的
T
(在日期和時間可能存在歧義的情況下通常是必需的)不是必需的。小數秒可以有任意數量的數字(超過 6 位的將被截斷)。
不支援小數小時和分鐘。
示例:
>>> from datetime import time >>> time.fromisoformat('04:23:01') datetime.time(4, 23, 1) >>> time.fromisoformat('T04:23:01') datetime.time(4, 23, 1) >>> time.fromisoformat('T042301') datetime.time(4, 23, 1) >>> time.fromisoformat('04:23:01.000384') datetime.time(4, 23, 1, 384) >>> 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.fromisoformat('04:23:01Z') datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc) >>> time.fromisoformat('04:23:01+00:00') datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)
在 3.7 版本加入。
在 3.11 版更改: 以前,此方法僅支援
time.isoformat()
可以發出的格式。
- classmethod time.strptime(date_string, format)¶
返回一個與 date_string 相對應的
time
物件,根據 format 進行解析。如果 format 不包含微秒或時區資訊,這等同於:
time(*(time.strptime(date_string, format)[3:6]))
如果 date_string 和 format 無法被
time.strptime()
解析,或者如果它返回的值不是時間元組,則會引發ValueError
。另請參閱 strftime() 和 strptime() 的行為 和time.fromisoformat()
。在 3.14 版本加入。
例項方法:
- time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)¶
返回一個具有相同值的新
time
物件,但指定的引數已更新。請注意,可以指定tzinfo=None
從一個感知time
建立一個簡單time
,而無需轉換時間資料。time
物件也受通用函式copy.replace()
的支援。在 3.6 版本發生變更: 添加了 fold 引數。
- time.isoformat(timespec='auto')¶
返回一個以 ISO 8601 格式表示時間的字串,以下格式之一:
HH:MM:SS.ffffff
,如果microsecond
不為 0HH:MM:SS
,如果microsecond
為 0HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]
,如果utcoffset()
不返回None
HH:MM:SS+HH:MM[:SS[.ffffff]]
,如果microsecond
為 0 並且utcoffset()
不返回None
可選引數 timespec 指定要包含的時間的附加元件數量(預設為
'auto'
)。它可以是以下之一:'auto'
: 如果microsecond
為 0,則與'seconds'
相同,否則與'microseconds'
相同。'hours'
: 以兩位數的HH
格式包含hour
。'milliseconds'
:包含完整時間,但將小數秒部分截斷到毫秒。HH:MM:SS.sss
格式。'microseconds'
:以HH:MM:SS.ffffff
格式包含完整時間。
備註
被排除的時間部分會被截斷,而不是四捨五入。
對於無效的 timespec 引數,將引發
ValueError
。示例
>>> from datetime import time >>> time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes') '12:34' >>> dt = time(hour=12, minute=34, second=56, microsecond=0) >>> dt.isoformat(timespec='microseconds') '12:34:56.000000' >>> dt.isoformat(timespec='auto') '12:34:56'
在 3.6 版更改: 添加了 timespec 引數。
- time.__str__()¶
對於一個時間
t
,str(t)
等同於t.isoformat()
。
- time.strftime(format)¶
返回一個表示時間的字串,由顯式格式字串控制。另請參閱 strftime() 和 strptime() 的行為 和
time.isoformat()
。
- time.__format__(format)¶
與
time.strftime()
相同。這使得在格式化字串字面值中以及使用str.format()
時可以為time
物件指定格式字串。另請參閱 strftime() 和 strptime() 的行為 和time.isoformat()
。
- time.utcoffset()¶
如果
tzinfo
為None
,則返回None
,否則返回self.tzinfo.utcoffset(None)
,如果後者不返回None
或一個大小小於一天的timedelta
物件,則引發異常。在 3.7 版更改: UTC 偏移量不再限制為整數分鐘。
- time.dst()¶
如果
tzinfo
為None
,則返回None
,否則返回self.tzinfo.dst(None)
,如果後者不返回None
或一個大小小於一天的timedelta
物件,則引發異常。在 3.7 版更改: DST 偏移量不再限制為整數分鐘。
用法示例:time
¶
使用 time
物件的示例
>>> from datetime import time, tzinfo, timedelta
>>> class 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.'
tzinfo
物件¶
- class datetime.tzinfo¶
這是一個抽象基類,意味著這個類不應該被直接例項化。定義
tzinfo
的子類來捕獲特定時區的資訊。tzinfo
(的一個具體子類)的例項可以傳遞給datetime
和time
物件的建構函式。後者物件將其屬性視為本地時間,而tzinfo
物件支援的方法可以揭示本地時間與 UTC 的偏移量、時區名稱和夏令時偏移量,所有這些都相對於傳遞給它們的日期或時間物件。你需要派生一個具體的子類,並且(至少)提供你所使用的
datetime
方法所需的標準tzinfo
方法的實現。datetime
模組提供了timezone
,這是一個tzinfo
的簡單具體子類,可以表示與 UTC 有固定偏移量的時區,例如 UTC 本身或北美的 EST 和 EDT。對 pickling 的特殊要求:
tzinfo
子類必須有一個可以無引數呼叫的__init__()
方法,否則它可以被 pickle,但可能無法再次 unpickle。這是一個技術要求,將來可能會放寬。tzinfo
的具體子類可能需要實現以下方法。具體需要哪些方法取決於對感知datetime
物件的使用。如果不確定,只需實現所有方法。
- tzinfo.utcoffset(dt)¶
返回本地時間與 UTC 的偏移量,作為一個
timedelta
物件,UTC 以東為正。如果本地時間在 UTC 以西,這應該是負數。這表示與 UTC 的*總*偏移量;例如,如果一個
tzinfo
物件同時表示時區和夏令時調整,utcoffset()
應該返回它們的總和。如果 UTC 偏移量未知,則返回None
。否則,返回的值必須是一個嚴格介於-timedelta(hours=24)
和timedelta(hours=24)
之間的timedelta
物件(偏移量的大小必須小於一天)。utcoffset()
的大多數實現可能看起來像以下兩種之一:return CONSTANT # fixed-offset class return CONSTANT + self.dst(dt) # daylight-aware class
如果
utcoffset()
不返回None
,那麼dst()
也不應返回None
。utcoffset()
的預設實現會引發NotImplementedError
。在 3.7 版更改: UTC 偏移量不再限制為整數分鐘。
- tzinfo.dst(dt)¶
返回夏令時 (DST) 調整,作為一個
timedelta
物件,如果 DST 資訊未知,則返回None
。如果夏令時未生效,則返回
timedelta(0)
。如果夏令時生效,則返回偏移量作為一個timedelta
物件(詳見utcoffset()
)。請注意,夏令時偏移量(如果適用)已經加到了utcoffset()
返回的 UTC 偏移量中,因此除非您有興趣單獨獲取夏令時資訊,否則無需查閱dst()
。例如,datetime.timetuple()
會呼叫其tzinfo
屬性的dst()
方法來確定tm_isdst
標誌應該如何設定,而tzinfo.fromutc()
會呼叫dst()
來考慮跨時區時的夏令時變化。一個同時模擬標準時間和夏令時的
tzinfo
子類的例項 tz 在此意義上必須保持一致:tz.utcoffset(dt) - tz.dst(dt)
對於每個
dt.tzinfo == tz
的datetime
物件 dt,必須返回相同的結果。對於正常的tzinfo
子類,此表示式產生時區的“標準偏移量”,該偏移量不應取決於日期或時間,而只取決於地理位置。datetime.astimezone()
的實現依賴於此,但無法檢測到違規;確保這一點是程式設計師的責任。如果一個tzinfo
子類無法保證這一點,它可能能夠覆蓋tzinfo.fromutc()
的預設實現,以便與astimezone()
正確工作。dst()
的大多數實現可能看起來像以下兩種之一:def dst(self, dt): # a fixed-offset class: doesn't account for DST return timedelta(0)
或
def dst(self, dt): # Code to set dston and dstoff to the time zone's DST # transition times based on the input dt.year, and expressed # in standard local time. if dston <= dt.replace(tzinfo=None) < dstoff: return timedelta(hours=1) else: return timedelta(0)
dst()
的預設實現會引發NotImplementedError
。在 3.7 版更改: DST 偏移量不再限制為整數分鐘。
- tzinfo.tzname(dt)¶
返回與
datetime
物件 dt 相對應的時區名稱,作為字串。datetime
模組沒有定義關於字串名稱的任何內容,也沒有要求它必須有任何特定的含義。例如,"GMT"
、"UTC"
、"-500"
、"-5:00"
、"EDT"
、"US/Eastern"
、"America/New York"
都是有效的回覆。如果字串名稱未知,則返回None
。請注意,這是一個方法而不是一個固定的字串,主要是因為一些tzinfo
子類希望根據傳遞的 dt 的具體值返回不同的名稱,特別是如果tzinfo
類考慮了夏令時。tzname()
的預設實現會引發NotImplementedError
。
這些方法由 datetime
或 time
物件呼叫,以響應它們同名的方法。一個 datetime
物件將自身作為引數傳遞,而一個 time
物件將 None
作為引數傳遞。因此,tzinfo
子類的方法應該準備好接受一個為 None
或 datetime
類的 dt 引數。
當傳遞 None
時,由類的設計者決定最佳響應。例如,如果類希望表示時間物件不參與 tzinfo
協議,則返回 None
是合適的。讓 utcoffset(None)
返回標準 UTC 偏移量可能更有用,因為沒有其他約定來發現標準偏移量。
當一個 datetime
物件作為對 datetime
方法的響應被傳入時,dt.tzinfo
與 self 是同一個物件。tzinfo
方法可以依賴於此,除非使用者程式碼直接呼叫 tzinfo
方法。其意圖是讓 tzinfo
方法將 dt 解釋為本地時間,而無需擔心其他時區的物件。
還有一個 tzinfo
方法,子類可能希望覆蓋:
- tzinfo.fromutc(dt)¶
這從預設的
datetime.astimezone()
實現中呼叫。當從那裡呼叫時,dt.tzinfo
是 self,並且 dt 的日期和時間資料被視為表示 UTC 時間。fromutc()
的目的是調整日期和時間資料,返回一個等效的在 self 的本地時間中的日期時間。大多數
tzinfo
子類應該能夠毫無問題地繼承預設的fromutc()
實現。它足夠強大,可以處理固定偏移時區,以及同時考慮標準時間和夏令時的時區,並且後者即使在不同年份的夏令時轉換時間不同時也能處理。預設fromutc()
實現可能無法在所有情況下正確處理的一個時區示例是,標準偏移量(與 UTC 相比)取決於傳遞的特定日期和時間,這可能由於政治原因而發生。如果結果是跨越標準偏移量變化時刻的小時之一,那麼astimezone()
和fromutc()
的預設實現可能不會產生您想要的結果。跳過錯誤情況的程式碼,預設的
fromutc()
實現的行為類似於:def fromutc(self, dt): # raise ValueError error if dt.tzinfo is not self dtoff = dt.utcoffset() dtdst = dt.dst() # raise ValueError if dtoff is None or dtdst is None delta = dtoff - dtdst # this is self's standard offset if delta: dt += delta # convert to standard local time dtdst = dt.dst() # raise ValueError if dtdst is None if dtdst: return dt + dtdst else: return dt
在以下 tzinfo_examples.py
檔案中,有一些 tzinfo
類的示例:
from datetime import tzinfo, timedelta, datetime
ZERO = timedelta(0)
HOUR = timedelta(hours=1)
SECOND = timedelta(seconds=1)
# A class capturing the platform's idea of local time.
# (May result in wrong values on historical times in
# timezones where UTC offset and/or the DST rules had
# changed in the past.)
import time as _time
STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds = -_time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
class LocalTimezone(tzinfo):
def fromutc(self, dt):
assert dt.tzinfo is self
stamp = (dt - datetime(1970, 1, 1, tzinfo=self)) // SECOND
args = _time.localtime(stamp)[:6]
dst_diff = DSTDIFF // SECOND
# Detect fold
fold = (args == _time.localtime(stamp - dst_diff))
return datetime(*args, microsecond=dt.microsecond,
tzinfo=self, fold=fold)
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
Local = LocalTimezone()
# A complete implementation of current DST rules for major US time zones.
def first_sunday_on_or_after(dt):
days_to_go = 6 - dt.weekday()
if days_to_go:
dt += timedelta(days_to_go)
return dt
# US DST Rules
#
# This is a simplified (i.e., wrong for a few cases) set of rules for US
# DST start and end times. For a complete and up-to-date set of DST rules
# and timezone definitions, visit the Olson Database (or try pytz):
# http://www.twinsun.com/tz/tz-link.htm
# https://sourceforge.net/projects/pytz/ (might not be up-to-date)
#
# In the US, since 2007, DST starts at 2am (standard time) on the second
# Sunday in March, which is the first Sunday on or after Mar 8.
DSTSTART_2007 = datetime(1, 3, 8, 2)
# and ends at 2am (DST time) on the first Sunday of Nov.
DSTEND_2007 = datetime(1, 11, 1, 2)
# From 1987 to 2006, DST used to start at 2am (standard time) on the first
# Sunday in April and to end at 2am (DST time) on the last
# Sunday of October, which is the first Sunday on or after Oct 25.
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
DSTEND_1987_2006 = datetime(1, 10, 25, 2)
# From 1967 to 1986, DST used to start at 2am (standard time) on the last
# Sunday in April (the one on or after April 24) and to end at 2am (DST time)
# on the last Sunday of October, which is the first Sunday
# on or after Oct 25.
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
DSTEND_1967_1986 = DSTEND_1987_2006
def us_dst_range(year):
# Find start and end times for US DST. For years before 1967, return
# start = end for no DST.
if 2006 < year:
dststart, dstend = DSTSTART_2007, DSTEND_2007
elif 1986 < year < 2007:
dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
elif 1966 < year < 1987:
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
else:
return (datetime(year, 1, 1), ) * 2
start = first_sunday_on_or_after(dststart.replace(year=year))
end = first_sunday_on_or_after(dstend.replace(year=year))
return start, end
class USTimeZone(tzinfo):
def __init__(self, hours, reprname, stdname, dstname):
self.stdoffset = timedelta(hours=hours)
self.reprname = reprname
self.stdname = stdname
self.dstname = dstname
def __repr__(self):
return self.reprname
def tzname(self, dt):
if self.dst(dt):
return self.dstname
else:
return self.stdname
def utcoffset(self, dt):
return self.stdoffset + self.dst(dt)
def dst(self, dt):
if dt is None or dt.tzinfo is None:
# An exception may be sensible here, in one or both cases.
# It depends on how you want to treat them. The default
# fromutc() implementation (called by the default astimezone()
# implementation) passes a datetime with dt.tzinfo is self.
return ZERO
assert dt.tzinfo is self
start, end = us_dst_range(dt.year)
# Can't compare naive to aware objects, so strip the timezone from
# dt first.
dt = dt.replace(tzinfo=None)
if start + HOUR <= dt < end - HOUR:
# DST is in effect.
return HOUR
if end - HOUR <= dt < end:
# Fold (an ambiguous hour): use dt.fold to disambiguate.
return ZERO if dt.fold else HOUR
if start <= dt < start + HOUR:
# Gap (a non-existent hour): reverse the fold rule.
return HOUR if dt.fold else ZERO
# DST is off.
return ZERO
def fromutc(self, dt):
assert dt.tzinfo is self
start, end = us_dst_range(dt.year)
start = start.replace(tzinfo=self)
end = end.replace(tzinfo=self)
std_time = dt + self.stdoffset
dst_time = std_time + HOUR
if end <= dst_time < end + HOUR:
# Repeated hour
return std_time.replace(fold=1)
if std_time < start or dst_time >= end:
# Standard time
return std_time
if start <= std_time < end - HOUR:
# Daylight saving time
return dst_time
Eastern = USTimeZone(-5, "Eastern", "EST", "EDT")
Central = USTimeZone(-6, "Central", "CST", "CDT")
Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
Pacific = USTimeZone(-8, "Pacific", "PST", "PDT")
請注意,在一個同時考慮標準時間和夏令時的 tzinfo
子類中,每年有兩次在夏令時轉換點存在不可避免的微妙之處。為具體起見,考慮美國東部時間(UTC -0500),其中 EDT 在三月的第二個星期日的 1:59 (EST) 後的下一分鐘開始,並在十一月的第一個星期日的 1:59 (EDT) 後的下一分鐘結束。
UTC 3:MM 4:MM 5:MM 6:MM 7:MM 8:MM
EST 22:MM 23:MM 0:MM 1:MM 2:MM 3:MM
EDT 23:MM 0:MM 1:MM 2:MM 3:MM 4:MM
start 22:MM 23:MM 0:MM 1:MM 3:MM 4:MM
end 23:MM 0:MM 1:MM 1:MM 2:MM 3:MM
當夏令時開始時(“start”行),本地掛鐘時間從 1:59 跳到 3:00。在那一天,形式為 2:MM 的掛鐘時間實際上沒有意義,因此在夏令時開始的那天,astimezone(Eastern)
不會提供 hour == 2
的結果。例如,在 2016 年的春季向前轉換時,我們得到:
>>> from datetime import datetime, timezone
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = datetime(2016, 3, 13, 5, tzinfo=timezone.utc)
>>> for i in range(4):
... u = u0 + i*HOUR
... t = u.astimezone(Eastern)
... print(u.time(), 'UTC =', t.time(), t.tzname())
...
05:00:00 UTC = 00:00:00 EST
06:00:00 UTC = 01:00:00 EST
07:00:00 UTC = 03:00:00 EDT
08:00:00 UTC = 04:00:00 EDT
當夏令時結束時(“end”行),有一個可能更糟的問題:有一個小時在本地掛鐘時間中無法明確表示:夏令時的最後一個小時。在東部時區,這是夏令時結束當天 UTC 時間 5:MM 形式的時間。本地掛鐘時間從 1:59(夏令時)再次跳回到 1:00(標準時間)。形式為 1:MM 的本地時間是模稜兩可的。astimezone()
透過將兩個相鄰的 UTC 小時對映到同一個本地小時來模仿本地時鐘的行為。在東部時區的例子中,當轉換為東部時間時,形式為 5:MM 和 6:MM 的 UTC 時間都對映到 1:MM,但較早的時間將 fold
屬性設定為 0,而較晚的時間將其設定為 1。例如,在 2016 年的秋季回撥轉換時,我們得到:
>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
>>> for i in range(4):
... u = u0 + i*HOUR
... t = u.astimezone(Eastern)
... print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
...
04:00:00 UTC = 00:00:00 EDT 0
05:00:00 UTC = 01:00:00 EDT 0
06:00:00 UTC = 01:00:00 EST 1
07:00:00 UTC = 02:00:00 EST 0
請注意,僅在 fold
屬性的值上有所不同的 datetime
例項在比較中被認為是相等的。
無法承受掛鐘時間歧義的應用程式應明確檢查 fold
屬性的值,或避免使用混合 tzinfo
子類;在使用 timezone
或任何其他固定偏移 tzinfo
子類(例如僅代表 EST(固定偏移 -5 小時)或僅代表 EDT(固定偏移 -4 小時)的類)時,沒有歧義。
參見
zoneinfo
datetime
模組有一個基本的timezone
類(用於處理與 UTC 的任意固定偏移)及其timezone.utc
屬性(一個 UTCtimezone
例項)。
zoneinfo
將 *IANA 時區資料庫*(也稱為奧爾森資料庫)引入 Python,並推薦使用它。
- IANA 時區資料庫
時區資料庫(通常稱為 tz、tzdata 或 zoneinfo)包含程式碼和資料,表示全球許多代表性地點的本地時間歷史。它會定期更新,以反映政治機構對時區邊界、UTC 偏移量和夏令時規則所做的更改。
timezone
物件¶
timezone
類是 tzinfo
的一個子類,它的每個例項都代表一個由與 UTC 的固定偏移量定義的時區。
此類的物件不能用於表示一年中不同日期使用不同偏移量的地區或民用時間有歷史變化地區的時區資訊。
- class datetime.timezone(offset, name=None)¶
offset 引數必須指定為一個
timedelta
物件,表示本地時間與 UTC 之間的差異。它必須嚴格介於-timedelta(hours=24)
和timedelta(hours=24)
之間,否則會引發ValueError
。name 引數是可選的。如果指定,它必須是一個字串,將用作
datetime.tzname()
方法返回的值。在 3.2 版本加入。
在 3.7 版更改: UTC 偏移量不再限制為整數分鐘。
- timezone.utcoffset(dt)¶
返回在構造
timezone
例項時指定的固定值。dt 引數被忽略。返回值是一個
timedelta
例項,等於本地時間與 UTC 之間的差異。在 3.7 版更改: UTC 偏移量不再限制為整數分鐘。
- timezone.tzname(dt)¶
返回在構造
timezone
例項時指定的固定值。如果在建構函式中未提供 name,
tzname(dt)
返回的名稱是根據offset
的值生成的,如下所示。如果 offset 為timedelta(0)
,則名稱為“UTC”,否則它是一個格式為UTC±HH:MM
的字串,其中 ± 是offset
的符號,HH 和 MM 分別是offset.hours
和offset.minutes
的兩位數字。在 3.6 版更改: 從
offset=timedelta(0)
生成的名稱現在是純粹的'UTC'
,而不是'UTC+00:00'
。
- timezone.dst(dt)¶
總是返回
None
。
類屬性:
- timezone.utc¶
UTC 時區,
timezone(timedelta(0))
。
strftime()
和 strptime()
的行為¶
date
、datetime
和 time
物件都支援一個 strftime(format)
方法,用於在顯式格式字串的控制下建立一個表示時間的字串。
相反,date.strptime()
、datetime.strptime()
和 time.strptime()
類方法從一個表示時間的字串和相應的格式字串建立一個物件。
下表提供了 strftime()
與 strptime()
的高階比較。
|
|
|
---|---|---|
用法 |
根據給定格式將物件轉換為字串 |
根據相應格式將字串解析為物件 |
方法型別 |
例項方法 |
類方法 |
簽名 |
|
|
strftime()
和 strptime()
格式程式碼¶
這些方法接受可用於解析和格式化日期的格式程式碼。
>>> datetime.strptime('31/01/22 23:59:59.999999',
... '%d/%m/%y %H:%M:%S.%f')
datetime.datetime(2022, 1, 31, 23, 59, 59, 999999)
>>> _.strftime('%a %d %b %Y, %I:%M%p')
'Mon 31 Jan 2022, 11:59PM'
以下是 1989 年 C 標準要求的所有格式程式碼的列表,這些程式碼在所有具有標準 C 實現的平臺上都有效。
指令 |
含義 |
示例 |
備註 |
---|---|---|---|
|
星期幾,區域設定的縮寫名稱。 |
Sun, Mon, …, Sat (en_US);
So, Mo, …, Sa (de_DE)
|
(1) |
|
星期幾,區域設定的完整名稱。 |
Sunday, Monday, …, Saturday (en_US);
Sonntag, Montag, …, Samstag (de_DE)
|
(1) |
|
星期幾,作為十進位制數,其中 0 是星期日,6 是星期六。 |
0, 1, …, 6 |
|
|
月份中的第幾天,作為零填充的十進位制數。 |
01, 02, …, 31 |
(9) |
|
月份,區域設定的縮寫名稱。 |
Jan, Feb, …, Dec (en_US);
Jan, Feb, …, Dez (de_DE)
|
(1) |
|
月份,區域設定的完整名稱。 |
January, February, …, December (en_US);
Januar, Februar, …, Dezember (de_DE)
|
(1) |
|
月份,作為零填充的十進位制數。 |
01, 02, …, 12 |
(9) |
|
不帶世紀的年份,作為零填充的十進位制數。 |
00, 01, …, 99 |
(9) |
|
帶世紀的年份,作為十進位制數。 |
0001, 0002, …, 2013, 2014, …, 9998, 9999 |
(2) |
|
小時(24小時制),作為零填充的十進位制數。 |
00, 01, …, 23 |
(9) |
|
小時(12小時制),作為零填充的十進位制數。 |
01, 02, …, 12 |
(9) |
|
區域設定中等同於 AM 或 PM 的表示。 |
AM, PM (en_US);
am, pm (de_DE)
|
(1), (3) |
|
分鐘,作為零填充的十進位制數。 |
00, 01, …, 59 |
(9) |
|
秒,作為零填充的十進位制數。 |
00, 01, …, 59 |
(4), (9) |
|
微秒,作為十進位制數,零填充到 6 位。 |
000000, 000001, …, 999999 |
(5) |
|
UTC 偏移量,格式為 |
(空), +0000, -0400, +1030, +063415, -030712.345216 |
(6) |
|
時區名稱(如果物件是簡單的,則為空字串)。 |
(空), UTC, GMT |
(6) |
|
一年中的第幾天,作為零填充的十進位制數。 |
001, 002, …, 366 |
(9) |
|
一年中的週數(星期日作為一週的第一天),作為零填充的十進位制數。新的一年中第一個星期日之前的所有天都算作第 0 周。 |
00, 01, …, 53 |
(7), (9) |
|
一年中的週數(星期一作為一週的第一天),作為零填充的十進位制數。新的一年中第一個星期一之前的所有天都算作第 0 周。 |
00, 01, …, 53 |
(7), (9) |
|
區域設定中合適的日期和時間表示。 |
Tue Aug 16 21:30:00 1988 (en_US);
Di 16 Aug 21:30:00 1988 (de_DE)
|
(1) |
|
區域設定中合適的日期表示。 |
08/16/88 (None);
08/16/1988 (en_US);
16.08.1988 (de_DE)
|
(1) |
|
區域設定中合適的時間表示。 |
21:30:00 (en_US);
21:30:00 (de_DE)
|
(1) |
|
一個字面上的 |
% |
為了方便,還包括了一些 C89 標準未要求的附加指令。這些引數都對應於 ISO 8601 日期值。
指令 |
含義 |
示例 |
備註 |
---|---|---|---|
|
ISO 8601 年份,帶世紀,表示包含 ISO 周( |
0001, 0002, …, 2013, 2014, …, 9998, 9999 |
(8) |
|
ISO 8601 星期幾,作為十進位制數,其中 1 是星期一。 |
1, 2, …, 7 |
|
|
ISO 8601 週數,作為十進位制數,星期一為一週的第一天。第 01 周是包含 1 月 4 日的那一週。 |
01, 02, …, 53 |
(8), (9) |
|
UTC 偏移量,格式為 |
(空), +00:00, -04:00, +10:30, +06:34:15, -03:07:12.345216 |
(6) |
當與 strftime()
方法一起使用時,這些指令可能並非在所有平臺上都可用。ISO 8601 年份和 ISO 8601 周指令不能與上面的年份和週數指令互換。使用不完整或模糊的 ISO 8601 指令呼叫 strptime()
將引發 ValueError
。
支援的完整格式程式碼集因平臺而異,因為 Python 呼叫平臺 C 庫的 strftime()
函式,而平臺差異很常見。要檢視您平臺上支援的完整格式程式碼集,請查閱 strftime(3) 文件。在處理不支援的格式說明符方面,平臺之間也存在差異。
在 3.6 版新增: 增加了 %G
, %u
和 %V
。
在 3.12 版新增: 增加了 %:z
。
技術細節¶
廣義上說,d.strftime(fmt)
的行為類似於 time
模組的 time.strftime(fmt, d.timetuple())
,儘管並非所有物件都支援 timetuple()
方法。
對於 datetime.strptime()
類方法,預設值為 1900-01-01T00:00:00.000
:格式字串中未指定的任何元件都將從預設值中獲取。[4]
使用 datetime.strptime(date_string, format)
等同於:
datetime(*(time.strptime(date_string, format)[0:6]))
除非格式包含亞秒級元件或時區偏移資訊,這些資訊在 datetime.strptime
中受支援,但在 time.strptime
中被丟棄。
對於 time
物件,不應使用年、月、日的格式程式碼,因為 time
物件沒有這些值。如果仍然使用,年份將替換為 1900,月份和日期替換為 1。
對於 date
物件,不應使用小時、分鐘、秒和微秒的格式程式碼,因為 date
物件沒有這些值。如果仍然使用,它們將被替換為 0。
出於同樣的原因,處理包含無法在當前區域設定的字元集中表示的 Unicode 碼點的格式字串也依賴於平臺。在某些平臺上,這些碼點在輸出中保持不變,而在其他平臺上,strftime
可能會引發 UnicodeError
或返回一個空字串。
備註
因為格式取決於當前的區域設定,所以在對輸出值做假設時應小心。欄位順序會變化(例如,“月/日/年”與“日/月/年”),並且輸出可能包含非 ASCII 字元。
strptime()
方法可以解析 [1, 9999] 範圍內的年份,但小於 1000 的年份必須用零填充到 4 位寬度。在 3.2 版更改: 在以前的版本中,
strftime()
方法僅限於年份 >= 1900。在 3.3 版更改: 在 3.2 版中,
strftime()
方法僅限於年份 >= 1000。當與
strptime()
方法一起使用時,%p
指令僅在%I
指令用於解析小時時才影響輸出的小時欄位。與
time
模組不同,datetime
模組不支援閏秒。當與
strptime()
方法一起使用時,%f
指令接受一到六位數字,並在右側補零。%f
是對 C 標準中格式字元集的擴充套件(但在 datetime 物件中單獨實現,因此始終可用)。對於簡單物件,
%z
、%:z
和%Z
格式程式碼被替換為空字串。對於感知物件:
%z
utcoffset()
被轉換為±HHMM[SS[.ffffff]]
形式的字串,其中HH
是一個兩位數的字串,表示 UTC 偏移的小時數,MM
是一個兩位數的字串,表示 UTC 偏移的分鐘數,SS
是一個兩位數的字串,表示 UTC 偏移的秒數,ffffff
是一個六位數的字串,表示 UTC 偏移的微秒數。當偏移量是整數秒時,省略ffffff
部分,當偏移量是整數分鐘時,同時省略ffffff
和SS
部分。例如,如果utcoffset()
返回timedelta(hours=-3, minutes=-30)
,則%z
被替換為字串'-0330'
。
在 3.7 版更改: UTC 偏移量不再限制為整數分鐘。
在 3.7 版更改: 當向
strptime()
方法提供%z
指令時,UTC 偏移量可以在小時、分鐘和秒之間使用冒號作為分隔符。例如,'+01:00:00'
將被解析為一小時的偏移量。此外,提供'Z'
等同於'+00:00'
。%:z
行為與
%z
完全相同,但在小時、分鐘和秒之間添加了冒號分隔符。%Z
在
strftime()
中,如果tzname()
返回None
,則%Z
被替換為空字串;否則,%Z
被替換為返回的值,該值必須是字串。strptime()
只接受%Z
的某些值:您機器區域設定的
time.tzname
中的任何值硬編碼值
UTC
和GMT
因此,生活在日本的人可能會有
JST
、UTC
和GMT
作為有效值,但可能沒有EST
。對於無效值,它將引發ValueError
。
在 3.2 版更改: 當向
strptime()
方法提供%z
指令時,將生成一個感知的datetime
物件。結果的tzinfo
將設定為一個timezone
例項。當與
strptime()
方法一起使用時,%U
和%W
僅在指定了星期和公曆年份 (%Y
) 時才用於計算。與
%U
和%W
類似,%V
僅在strptime()
格式字串中指定了星期和 ISO 年份 (%G
) 時才用於計算。另請注意,%G
和%Y
不可互換。當與
strptime()
方法一起使用時,對於%d
、%m
、%H
、%I
、%M
、%S
、%j
、%U
、%W
和%V
格式,前導零是可選的。格式%y
則需要前導零。使用
strptime()
解析月份和日期時,請務必在格式中包含年份。如果您需要解析的值缺少年份,請附加一個明確的虛擬閏年。否則,當遇到閏日時,您的程式碼將引發異常,因為解析器使用的預設年份不是閏年。使用者每四年就會遇到這個錯誤……>>> month_day = "02/29" >>> datetime.strptime(f"{month_day};1984", "%m/%d;%Y") # No leap year bug. datetime.datetime(1984, 2, 29, 0, 0)
自 3.13 版本起棄用,將在 3.15 版本中移除: 使用包含月中某天但沒有年份的格式字串呼叫
strptime()
現在會發出DeprecationWarning
。在 3.15 或更高版本中,我們可能會將其更改為錯誤,或將預設年份更改為閏年。請參閱 gh-70647。
腳註