datetime --- 基本的日期和時(shí)間類型?
源代碼: Lib/datetime.py
datetime 模塊提供了可以通過多種方式操作日期和時(shí)間的類。在支持日期時(shí)間數(shù)學(xué)運(yùn)算的同時(shí),實(shí)現(xiàn)的關(guān)注點(diǎn)更著重于如何能夠更有效地解析其屬性用于格式化輸出和數(shù)據(jù)操作。相關(guān)功能可以參閱 time 和 calendar 模塊。
有兩種日期和時(shí)間的對(duì)象:“簡(jiǎn)單型“和”感知型“。
感知型對(duì)象有著用足以支持一些應(yīng)用層面算法和國(guó)家層面時(shí)間調(diào)整的信息,例如時(shí)區(qū)和夏令時(shí),來讓自己和其他的感知型對(duì)象區(qū)別開來。感知型對(duì)象是用來表達(dá)不對(duì)解釋器開放的特定時(shí)間信息 1。
簡(jiǎn)單型對(duì)象沒包含足夠多的信息來明確定位與之相關(guān)的 date/time 對(duì)象。 簡(jiǎn)單型對(duì)象所代表的是世界標(biāo)準(zhǔn)時(shí)間(UTC)、當(dāng)?shù)貢r(shí)間或者是其它時(shí)區(qū)的時(shí)間完全取決于程序,就像一個(gè)數(shù)字是代表的是米、英里或者質(zhì)量完全取決于程序一樣。 簡(jiǎn)單型對(duì)象以忽略了一些現(xiàn)實(shí)情況的為代價(jià)使得它容易理解和使用。
對(duì)于需要感知型對(duì)象的應(yīng)用, datetime 對(duì)象和 time 對(duì)象有一個(gè)可選的時(shí)區(qū)信息屬性 tzinfo ,這個(gè)屬性可以設(shè)置給 tzinfo 類的子類實(shí)例。這些 tzinfo 對(duì)象捕獲關(guān)于相對(duì)于世界標(biāo)準(zhǔn)時(shí)間(UTC)偏移、時(shí)區(qū)名字和夏令時(shí)是否有效等信息。需要注意的是,只有一個(gè)具體的 tzinfo 類,即由 datetime 模塊提供的 timezone 類。 timezone 類可以代表相對(duì)于世界標(biāo)準(zhǔn)時(shí)間(UTC)固定偏移的簡(jiǎn)單時(shí)區(qū),比如世界標(biāo)準(zhǔn)時(shí)間(UTC)自己或者北美東部時(shí)間或者東部夏令時(shí)。支持時(shí)區(qū)的詳細(xì)程度取決于應(yīng)用。世界各地的時(shí)間調(diào)整規(guī)則相比理性更加政治性,經(jīng)常會(huì)變更。也沒有一個(gè)基于世界標(biāo)準(zhǔn)時(shí)間(UTC)的標(biāo)準(zhǔn)套件適合用于所有應(yīng)用。
The datetime module exports the following constants:
有效的類型?
-
class
datetime.date 一個(gè)理想化的簡(jiǎn)單型日期,它假設(shè)當(dāng)今的公歷在過去和未來永遠(yuǎn)有效。 屬性:
year,month, andday。
-
class
datetime.time 一個(gè)理想化的時(shí)間,它獨(dú)立于任何特定的日期,假設(shè)每天一共有 24*60*60 秒(這里沒有"閏秒"的概念)。 屬性:
hour,minute,second,microsecond, 和tzinfo。
-
class
datetime.datetime 日期和時(shí)間的結(jié)合。屬性:
year,month,day,hour,minute,second,microsecond, andtzinfo.
-
class
datetime.timedelta 表示兩個(gè)
date對(duì)象或者time對(duì)象,或者datetime對(duì)象之間的時(shí)間間隔,精確到微秒。
-
class
datetime.tzinfo 一個(gè)描述時(shí)區(qū)信息的抽象基類。用于給
datetime類和time類提供自定義的時(shí)間調(diào)整概念(例如,負(fù)責(zé)時(shí)區(qū)或者夏令時(shí))。
-
class
datetime.timezone 一個(gè)實(shí)現(xiàn)了
tzinfo抽象基類的子類,用于表示相對(duì)于 世界標(biāo)準(zhǔn)時(shí)間(UTC)的偏移量。3.2 新版功能.
這些類型的對(duì)象都是不可變的。
date 類型的對(duì)象都是簡(jiǎn)單型的。
An object of type time or datetime may be naive or aware.
A datetime object d is aware if d.tzinfo is not None and
d.tzinfo.utcoffset(d) does not return None. If d.tzinfo is
None, or if d.tzinfo is not None but d.tzinfo.utcoffset(d)
returns None, d is naive. A time object t is aware
if t.tzinfo is not None and t.tzinfo.utcoffset(None) does not return
None. Otherwise, t is naive.
簡(jiǎn)單型和感知型之間的差別不適用于 timedelta 對(duì)象。
子類關(guān)系
object
timedelta
tzinfo
timezone
time
date
datetime
timedelta 類對(duì)象?
timedelta 對(duì)象表示兩個(gè) date 或者 time 的時(shí)間間隔。
-
class
datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)? 所有的參數(shù)都是可選的并且默認(rèn)為
0。這些參數(shù)可以是整數(shù)或者浮點(diǎn)數(shù),也可以是正數(shù)或者負(fù)數(shù)。只有 days,*seconds* 和 microseconds 會(huì)存儲(chǔ)在內(nèi)部,即python內(nèi)部以 days,*seconds* 和 microseconds 三個(gè)單位作為存儲(chǔ)的基本單位。參數(shù)單位轉(zhuǎn)換規(guī)則如下:
1毫秒會(huì)轉(zhuǎn)換成1000微秒。
1分鐘會(huì)轉(zhuǎn)換成60秒。
1小時(shí)會(huì)轉(zhuǎn)換成3600秒。
1星期會(huì)轉(zhuǎn)換成7天。
days, seconds, microseconds 本身也是標(biāo)準(zhǔn)化的,以保證表達(dá)方式的唯一性,例:
0 <= microseconds < 10000000 <= seconds < 3600*24(一天的秒數(shù))-999999999 <= days <= 999999999
在有任何浮點(diǎn)型參數(shù)或者微秒為小數(shù)的情況下,所有小數(shù)均會(huì)按照前面的換算規(guī)則疊加到下一級(jí),并使用round-half-to-even的方法對(duì)微秒進(jìn)行取舍。沒有浮點(diǎn)型參數(shù)情況下,轉(zhuǎn)換的過程就是精確的(沒有信息丟失)。
如果標(biāo)準(zhǔn)化后的 days 數(shù)值超過了指定范圍,將會(huì)拋出
OverflowError異常。需要注意的是,負(fù)數(shù)被標(biāo)準(zhǔn)化后的結(jié)果會(huì)讓你大吃一驚。例如,
>>> from datetime import timedelta >>> d = timedelta(microseconds=-1) >>> (d.days, d.seconds, d.microseconds) (-1, 86399, 999999)
類屬性:
-
timedelta.max? The most positive
timedeltaobject,timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999).
需要注意的是,因?yàn)闃?biāo)準(zhǔn)化的緣故,timedelta.max > -timedelta.min,-timedelta.max?不可以表示一個(gè) timedelta 類對(duì)象。
實(shí)例屬性(只讀):
屬性 |
值 |
|---|---|
|
-999999999 至 999999999 ,含999999999 |
|
0 至 86399,包含86399 |
|
0 至 999999,包含999999 |
支持的運(yùn)算:
運(yùn)算 |
結(jié)果: |
|---|---|
|
t2 和 t3 的和。 運(yùn)算后 t1-t2 == t3 and t1-t3 == t2 必為真值。(1) |
|
t2 減 t3 的差。 運(yùn)算后 t1 == t2 - t3 and t2 == t1 + t3 必為真值。 (1)(6) |
|
乘以一個(gè)整數(shù)。運(yùn)算后假如 |
In general, t1 * i == t1 * (i-1) + t1 is true. (1) |
|
|
乘以一個(gè)浮點(diǎn)數(shù),結(jié)果會(huì)被舍入到 timedelta 最接近的整數(shù)倍。 精度使用四舍五偶入奇不入規(guī)則。 |
|
總時(shí)間 t2 除以間隔單位 t3 (3)。 返回一個(gè) |
|
除以一個(gè)浮點(diǎn)數(shù)或整數(shù)。 結(jié)果會(huì)被舍入到 timedelta 最接近的整數(shù)倍。 精度使用四舍五偶入奇不入規(guī)則。 |
|
取整除,余數(shù)部分(如果有的話)將被丟棄。在第二種情況下,返回一個(gè)整數(shù)。(3) |
|
余數(shù)為一個(gè) |
|
通過 : |
|
返回一個(gè)相同數(shù)值的 |
|
等價(jià)于 |
|
當(dāng) |
|
返回一個(gè)形如 |
|
返回一個(gè) |
注釋:
精確但可能會(huì)溢出。
精確且不會(huì)溢出。
除以0將會(huì)拋出異常
ZeroDivisionError。-timedelta.max 不是一個(gè)
timedelta類對(duì)象。String representations of
timedeltaobjects are normalized similarly to their internal representation. This leads to somewhat unusual results for negative timedeltas. For example:>>> timedelta(hours=-5) datetime.timedelta(days=-1, seconds=68400) >>> print(_) -1 day, 19:00:00
表達(dá)式
t2 - t3通常與t2 + (-t3)是等價(jià)的,除非 t3 等于timedelta.max; 在這種情況下前者會(huì)返回結(jié)果,而后者則會(huì)溢出。
除了上面列舉的操作以外 timedelta 對(duì)象還支持與 date 和 datetime 對(duì)象進(jìn)行特定的相加和相減運(yùn)算(見下文)。
在 3.2 版更改: 現(xiàn)在已支持 timedelta 對(duì)象與另一個(gè) timedelta 對(duì)象相整除或相除,包括求余運(yùn)算和 divmod() 函數(shù)。 現(xiàn)在也支持 timedelta 對(duì)象被 float 對(duì)象除或乘。
timedelta 對(duì)象與 timedelta 對(duì)象比較的支持是通過將表示較小時(shí)間差的 timedelta 對(duì)象視為較小值。 為了防止將混合類型比較回退為基于對(duì)象地址的默認(rèn)比較,當(dāng) timedelta 對(duì)象與不同類型的對(duì)象比較時(shí),將會(huì)引發(fā) TypeError,除非比較運(yùn)算符是 == 或 !=。 在后一種情況下將分別返回 False 或 True。
timedelta 對(duì)象是 hashable 類型的(可以作為字典關(guān)鍵字), 支持高效獲取, 在布爾上下文中, timedelta 對(duì)象大多數(shù)情況下都被視為真,僅在不等于 timedelta(0) 時(shí)。
實(shí)例方法:
-
timedelta.total_seconds()? 返回時(shí)間間隔包含了多少秒。造價(jià)于
td / timedelta(seconds=1)。對(duì)于其它單位可以直接使用除法的形式 (例如td / timedelta(microseconds=1))。需要注意的是,時(shí)間間隔較大時(shí),這個(gè)方法的結(jié)果中的微秒將會(huì)失真(大多數(shù)平臺(tái)上大于270年視為一個(gè)較大的時(shí)間間隔)。
3.2 新版功能.
用法示例:
>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
... minutes=50, seconds=600) # adds up to 365 days
>>> year.total_seconds()
31536000.0
>>> year == another_year
True
>>> ten_years = 10 * year
>>> ten_years, ten_years.days // 365
(datetime.timedelta(days=3650), 10)
>>> nine_years = ten_years - year
>>> nine_years, nine_years.days // 365
(datetime.timedelta(days=3285), 9)
>>> three_years = nine_years // 3
>>> three_years, three_years.days // 365
(datetime.timedelta(days=1095), 3)
>>> abs(three_years - ten_years) == 2 * three_years + year
True
date 對(duì)象?
date 對(duì)象代表一個(gè)理想化歷法中的日期(年、月和日),即當(dāng)今的格列高利歷向前后兩個(gè)方向無限延伸。公元 1 年 1 月 1 日是第 1 日,公元 1 年 1 月 2 日是第 2 日, 依此類推。 這與 Dershowitz 與 Reingold 所著 Calendrical Calculations 中“預(yù)期格列高利”歷法的定義一致,它是適用于該書中所有運(yùn)算的基礎(chǔ)歷法。 請(qǐng)參閱該書了解在預(yù)期格列高利歷序列與許多其他歷法系統(tǒng)之間進(jìn)行轉(zhuǎn)換的算法。
-
class
datetime.date(year, month, day)? 所有參數(shù)都是必要的。 參數(shù)必須是在下面范圍內(nèi)的整數(shù):
MINYEAR <= year <= MAXYEAR1 <= month <= 121 <= 日期 <= 給定年月對(duì)應(yīng)的天數(shù)
如果參數(shù)不在這些范圍內(nèi),則拋出
ValueError異常。
其它構(gòu)造器,所有的類方法:
-
classmethod
date.today()? 返回當(dāng)?shù)氐漠?dāng)前日期。與``date.fromtimestamp(time.time())``等價(jià)。
-
classmethod
date.fromtimestamp(timestamp)? 返回對(duì)應(yīng)于 POSIX 時(shí)間戳例如
time.time()返回值的本地日期。 這可能引發(fā)OverflowError,如果時(shí)間戳數(shù)值超出所在平臺(tái) Clocaltime()函數(shù)的支持范圍的話,并會(huì)在localtime()出錯(cuò)時(shí)引發(fā)OSError。 通常該數(shù)值會(huì)被限制在 1970 年至 2038 年之間。 請(qǐng)注意在時(shí)間戳概念包含閏秒的非 POSIX 系統(tǒng)上,閏秒會(huì)被fromtimestamp()所忽略。在 3.3 版更改: 引發(fā)
OverflowError而不是ValueError,如果時(shí)間戳數(shù)值超出所在平臺(tái) Clocaltime()函數(shù)的支持范圍的話,并會(huì)在localtime()出錯(cuò)時(shí)引發(fā)OSError而不是ValueError。
-
classmethod
date.fromordinal(ordinal)? 返回對(duì)應(yīng)于預(yù)期格列高利歷序號(hào)的日期,其中公元 1 年 1 月 1 日的序號(hào)為 1。 除非
1 <= 序號(hào) <= date.max.toordinal()否則會(huì)引發(fā)ValueError。 對(duì)于任意日期 d,date.fromordinal(d.toordinal()) == d。
-
classmethod
date.fromisoformat(date_string)? 返回對(duì)應(yīng)于
date.isoformat()所提供的 date_string 格式的date。 特別地,此函數(shù)支持YYYY-MM-DD格式的字符串。警告
此函數(shù)不支持解析任意 ISO 8601 字符串 —— 它的目的只是作為
date.isoformat()的逆操作。3.7 新版功能.
類屬性:
-
date.min? 最小的日期
date(MINYEAR, 1, 1)。
-
date.max? 最大的日期 ,
date(MAXYEAR, 12, 31)。
-
date.resolution? 兩個(gè)日期對(duì)象的最小間隔,
timedelta(days=1)。
實(shí)例屬性(只讀):
-
date.month? 1 至 12(含)
-
date.day? 返回1到指定年月的天數(shù)間的數(shù)字。
支持的運(yùn)算:
運(yùn)算 |
結(jié)果: |
|---|---|
|
date2 等于從 date1 減去 |
|
計(jì)算 date2 的值使得 |
|
(3) |
|
如果 date1 的時(shí)間在 date2 之前則認(rèn)為 date1 小于 date2 。 (4) |
注釋:
如果
timedelta.days > 0則 date2 在時(shí)間線上前進(jìn),如果timedelta.days < 0則后退。 操作完成后date2 - date1 == timedelta.days。timedelta.seconds和timedelta.microseconds會(huì)被忽略。如果date2.year將小于MINYEAR或大于MAXYEAR則會(huì)引發(fā)OverflowError。.timedelta.seconds和timedelta.microseconds會(huì)被忽略。精確且不會(huì)溢出。 操作完成后 timedelta.seconds 和 timedelta.microseconds 均為0, 并且 date2 + timedelta == date1。
換句話說,當(dāng)且僅當(dāng)
date1.toordinal() < date2.toordinal()時(shí)date1 < date2。 日期比較會(huì)引發(fā)TypeError,如果比較目標(biāo)不為date對(duì)象的話。 不過也可能會(huì)返回NotImplemented,如果比較目標(biāo)具有timetuple()屬性的話。 這個(gè)鉤子給予其他日期對(duì)象類型實(shí)現(xiàn)混合類型比較的機(jī)會(huì)。 否則,當(dāng)date對(duì)象與不同類型的對(duì)象比較時(shí)將會(huì)引發(fā)TypeError,除非==或!=比較。 后兩種情況將分別返回False或True。
日期可以作為字典的關(guān)鍵字。在布爾上下文中,所有的 date 對(duì)象都視為真。
實(shí)例方法:
-
date.replace(year=self.year, month=self.month, day=self.day)? 返回一個(gè)具有同樣值的日期,除非通過任何關(guān)鍵字參數(shù)給出了某些形參的新值。 例如,如果
d == date(2002, 12, 31),則d.replace(day=26) == date(2002, 12, 26)。
-
date.timetuple()? 返回一個(gè)
time.struct_time,即與time.localtime()的返回類型相同。 hours, minutes 和 seconds 值為 0, 且 DST 標(biāo)志值為 -1。d.timetuple()等價(jià)于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是日期在當(dāng)前年份中的序號(hào),起始序號(hào)1表示 1 月 1 日。
-
date.toordinal()? 返回日期的預(yù)期格列高利歷序號(hào),其中公元 1 年 1 月 1 日的序號(hào)為 1。 對(duì)于任意
date對(duì)象 d,date.fromordinal(d.toordinal()) == d。
-
date.weekday()? 返回一個(gè)整數(shù)代表星期幾,星期一為0,星期天為6。例如,
date(2002, 12, 4).weekday() == 2,表示的是星期三。參閱isoweekday()。
-
date.isoweekday()? 返回一個(gè)整數(shù)代表星期幾,星期一為1,星期天為7。例如:
date(2002, 12, 4).isoweekday() == 3,表示星期三。參見weekday(),isocalendar()。
-
date.isocalendar()? 返回一個(gè)三元元組,(ISO year, ISO week number, ISO weekday) 。
ISO日歷是一個(gè)被廣泛使用的公歷??梢詮?https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm 上查看更完整的說明。
ISO 年由 52 或 53 個(gè)完整星期構(gòu)成,每個(gè)星期開始于星期一結(jié)束于星期日。 一個(gè) ISO 年的第一個(gè)星期就是(格列高利)歷法的的一年中第一個(gè)包含星期四的星期。 這被稱為 1 號(hào)星期,其中星期四所在的 ISO 年與其所在的格列高利年相同。
例如,2004 年的第一天是一個(gè)星期四,因此 ISO 2004 年的第一個(gè)星期開始于 2003 年 12 月 29 日星期一,結(jié)束于 2004 年 1 月 4 日星期日,因此
date(2003, 12, 29).isocalendar() == (2004, 1, 1)anddate(2004, 1, 4).isocalendar() == (2004, 1, 7)。
-
date.isoformat()? 返回一個(gè) ISO 8601 格式的字符串, 'YYYY-MM-DD'。例如
date(2002, 12, 4).isoformat() == '2002-12-04'。
-
date.__str__()? 對(duì)于日期對(duì)象 d,
str(d)等價(jià)于d.isoformat()。
-
date.ctime()? 返回一個(gè)代表日期的字符串,例如
date(2002, 12, 4).ctime() == 'Wed Dec 4 00:00:00 2002'。 在原生 Cctime()函數(shù) (time.ctime()會(huì)發(fā)起調(diào)用該函數(shù),但date.ctime()則不會(huì)) 遵循 C 標(biāo)準(zhǔn)的平臺(tái)上,d.ctime()等價(jià)于time.ctime(time.mktime(d.timetuple()))。
-
date.strftime(format)? 返回一個(gè)由顯式格式字符串所指明的代表日期的字符串。 表示時(shí)、分或秒的格式代碼值將為 0。 要獲取格式指令的完整列表請(qǐng)參閱 strftime() 和 strptime() 的行為。
-
date.__format__(format)? 與
date.strftime()相同。 此方法使得為date對(duì)象指定以 格式化字符串字面值 表示的格式化字符串以及使用str.format()進(jìn)行格式化成為可能。 要獲取格式指令的完整列表,請(qǐng)參閱 strftime() 和 strptime() 的行為。
計(jì)算距離特定事件天數(shù)的例子:
>>> 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)
>>> 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 )
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
'The day is 11, the month is March.'
datetime 對(duì)象?
datetime 對(duì)象是一個(gè)包含了來自 date 對(duì)象和 time 對(duì)象所有信息的單一對(duì)象。 與 date 對(duì)象一樣,datetime 假定當(dāng)今的格列高利歷向前后兩個(gè)方向無限延伸;與 time 對(duì)象一樣,datetime 假定每一天恰好有 3600*24 秒。
構(gòu)造器 :
-
class
datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)? year, month 和 day 參數(shù)是必要的。 tzinfo 可以是
None或者一個(gè)tzinfo子類的實(shí)例。 其余的參數(shù)必須是在下面范圍內(nèi)的整數(shù):MINYEAR <= year <= MAXYEAR,1 <= month <= 12,1 <= day <= 指定年月的天數(shù),0 <= hour < 24,0 <= minute < 60,0 <= second < 60,0 <= microsecond < 1000000,fold in [0, 1].
如果參數(shù)不在這些范圍內(nèi),則拋出
ValueError異常。3.6 新版功能: 增加了
fold參數(shù)。
其它構(gòu)造器,所有的類方法:
-
classmethod
datetime.today()? 返回當(dāng)前的本地 datetime,
tzinfo值為None。 這等價(jià)于datetime.fromtimestamp(time.time())。 另請(qǐng)參閱now(),fromtimestamp()。
-
classmethod
datetime.now(tz=None)? 返回當(dāng)前的本地 date 和 time。 如果可選參數(shù) tz 為
None或未指定,這就類似于today(),但該方法會(huì)在可能的情況下提供比通過time.time()時(shí)間戳所獲時(shí)間值更高的精度(例如,在提供了 Cgettimeofday()函數(shù)的平臺(tái)上就可能做到)。如果 tz 不為
None,它必須是tzinfo的子類的一個(gè)實(shí)例,并且當(dāng)前日期和時(shí)間將轉(zhuǎn)換為 tz 時(shí)區(qū)的日期和時(shí)間。 在這種情況下結(jié)果等價(jià)于tz.fromutc(datetime.utcnow().replace(tzinfo=tz))。 另請(qǐng)參閱today(),utcnow()。
-
classmethod
datetime.utcnow()? 返回當(dāng)前 UTC 日期和時(shí)間,其中
tzinfo為None。 這類似于now(),但返回的當(dāng)前 UTC 日期和時(shí)間是一個(gè)本機(jī)datetime對(duì)象。 自動(dòng)感知的當(dāng)前 UTC 日期時(shí)間可通過調(diào)用datetime.now(timezone.utc)來獲得。 另請(qǐng)參閱now()。
-
classmethod
datetime.fromtimestamp(timestamp, tz=None)? 返回對(duì)應(yīng)于 POSIX 時(shí)間戳例如
time.time()的返回值的本地日期和時(shí)間。 如果可選參數(shù) tz 為None或未指定,時(shí)間戳?xí)晦D(zhuǎn)換為所在平臺(tái)的本地日期和時(shí)間,返回的datetime對(duì)象將為天真型。如果 tz 不為
None,它必須是tzinfo子類的一個(gè)實(shí)例,并且時(shí)間戳將被轉(zhuǎn)換到 tz 指定的時(shí)區(qū)。 在這種情況下結(jié)果等價(jià)于tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))。fromtimestamp()可能引發(fā)OverflowError,如果時(shí)間戳數(shù)值超出所在平臺(tái) Clocaltime()或gmtime()函數(shù)的支持范圍的話,并會(huì)在localtime()或gmtime()出錯(cuò)時(shí)引發(fā)OSError。 通常該數(shù)值會(huì)被限制在 1970 年至 2038 年之間。 請(qǐng)注意在時(shí)間戳概念包含閏秒的非 POSIX 系統(tǒng)上,閏秒會(huì)被fromtimestamp()所忽略,結(jié)果可能導(dǎo)致兩個(gè)相差一秒的時(shí)間戳產(chǎn)生相同的datetime對(duì)象。 另請(qǐng)參閱utcfromtimestamp()。在 3.3 版更改: 引發(fā)
OverflowError而不是ValueError,如果時(shí)間戳數(shù)值超出所在平臺(tái) Clocaltime()或gmtime()函數(shù)的支持范圍的話。 并會(huì)在localtime()或gmtime()出錯(cuò)時(shí)引發(fā)OSError而不是ValueError。在 3.6 版更改:
fromtimestamp()可能返回fold值設(shè)為 1 的實(shí)例。
-
classmethod
datetime.utcfromtimestamp(timestamp)? 返回對(duì)應(yīng)于 POSIX 時(shí)間戳的 UTC
datetime,其中tzinfo為None。 這可能引發(fā)OverflowError,如果時(shí)間戳數(shù)值超出所在平臺(tái) Cgmtime()函數(shù)的支持范圍的話,并會(huì)在gmtime()出錯(cuò)時(shí)引發(fā)OSError。 通常該數(shù)值并會(huì)限制在 1970 年至 2038 年之間。要得到一個(gè)感知型
datetime對(duì)象,應(yīng)調(diào)用fromtimestamp():datetime.fromtimestamp(timestamp, timezone.utc)
在 POSIX 兼容的平臺(tái)上,它等價(jià)于以下表達(dá)式:
datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=timestamp)
不同之處在于后一種形式總是支持完整年份范圍:從
MINYEAR到MAXYEAR的開區(qū)間。在 3.3 版更改: 引發(fā)
OverflowError而不是ValueError,如果時(shí)間戳數(shù)值超出所在平臺(tái) Cgmtime()函數(shù)的支持范圍的話。 并會(huì)在gmtime()出錯(cuò)時(shí)引發(fā)OSError而不是ValueError。
-
classmethod
datetime.fromordinal(ordinal)? 返回對(duì)應(yīng)于預(yù)期格列高利歷序號(hào)的
datetime,其中公元 1 年 1 月 1 日的序號(hào)為 1。 除非1 <= ordinal <= datetime.max.toordinal()否則會(huì)引發(fā)ValueError。 結(jié)果的hour, minute, second 和 microsecond 值均為 0,并且tzinfo值為None。
-
classmethod
datetime.combine(date, time, tzinfo=self.tzinfo)? 返回一個(gè)新的
datetime對(duì)象,對(duì)象的日期數(shù)值等于給定的date對(duì)象的數(shù)值,時(shí)間數(shù)值等于給定的time對(duì)象的數(shù)值。 如果提供 tzinfo 參數(shù),其值會(huì)被用來設(shè)置結(jié)果的tzinfo屬性,否則將會(huì)使用 time 參數(shù)的tzinfo屬性。對(duì)于任意
datetime對(duì)象 d,d == datetime.combine(d.date(), d.time(), d.tzinfo)。 如果 date 是一個(gè)datetime對(duì)象,它的時(shí)間數(shù)值和tzinfo屬性會(huì)被忽略。在 3.6 版更改: 增加了 tzinfo 參數(shù)。
-
classmethod
datetime.fromisoformat(date_string)? 返回對(duì)應(yīng)于
date.isoformat()和datetime.isoformat()所提供的格式字符串中 date_string 的datetime。 特別地,此函數(shù)支持YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]格式的字符串,其中*可匹配任意單個(gè)字符。警告
此函數(shù)并不支持解析任意 ISO 8601 字符串 —— 它的目的只是作為
datetime.isoformat()的逆操作。 在第三方包 dateutil 中提供了一個(gè)更完善的 ISO 8601 解析器dateutil.parser.isoparse。3.7 新版功能.
-
classmethod
datetime.strptime(date_string, format)? 返回根據(jù) format 解析與 date_string 相對(duì)應(yīng)的
datetime,這等價(jià)于datetime(*(time.strptime(date_string, format)[0:6])),如果 date_string 和 format 無法被time.strptime()解析或它返回一個(gè)不是時(shí)間元組的值,則將引發(fā)ValueError。 要獲取格式化指令的完整列表請(qǐng)參閱 strftime() 和 strptime() 的行為。
類屬性:
實(shí)例屬性(只讀):
-
datetime.month? 1 至 12(含)
-
datetime.day? 返回1到指定年月的天數(shù)間的數(shù)字。
-
datetime.hour? 取值范圍是
range(24)。
-
datetime.minute? 取值范圍是
range(60)。
-
datetime.second? 取值范圍是
range(60)。
-
datetime.microsecond? 取值范圍是
range(1000000)。
-
datetime.fold? 取值范圍是
[0, 1]。 用于在重復(fù)的時(shí)間段中消除邊界時(shí)間歧義。 (當(dāng)夏令時(shí)結(jié)束時(shí)回調(diào)時(shí)鐘或由于政治原因?qū)е庐?dāng)前時(shí)區(qū)的 UTC 時(shí)差減少就會(huì)出現(xiàn)重復(fù)的時(shí)間段。) 取值 0 (1) 表示兩個(gè)時(shí)刻早于(晚于)所代表的同一邊界時(shí)間。3.6 新版功能.
支持的運(yùn)算:
運(yùn)算 |
結(jié)果: |
|---|---|
|
(1) |
|
(2) |
|
(3) |
|
datetime2 是從中去掉的一段 timedelta 的結(jié)果,如果
timedelta.days> 0 則是在時(shí)間線上前進(jìn),如果timedelta.days< 0 則后退。 結(jié)果具有與輸入的 datetime 相同的tzinfo屬性,并且操作完成后 datetime2 - datetime1 == timedelta。 如果 datetime2.year 將小于MINYEAR或大于MAXYEAR則會(huì)引發(fā)OverflowError。 請(qǐng)注意即使輸入的是一個(gè)感知型對(duì)象,該方法也不會(huì)進(jìn)行時(shí)區(qū)調(diào)整。計(jì)算 datetime2 使得 datetime2 + timedelta == datetime1。 與相加操作一樣,結(jié)果具有與輸入的 datetime 相同的
tzinfo屬性,即使輸入的是一個(gè)感知型對(duì)象,該方法也不會(huì)進(jìn)行時(shí)區(qū)調(diào)整。從一個(gè)
datetime減去一個(gè)datetime僅對(duì)兩個(gè)操作數(shù)均為簡(jiǎn)單型或均為感知型時(shí)有定義。 如果一個(gè)是感知型而另一個(gè)是簡(jiǎn)單型,則會(huì)引發(fā)TypeError。如果兩個(gè)操作數(shù)都是簡(jiǎn)單型,或都是感知型且具有相同的
tzinfo屬性,tzinfo屬性會(huì)被忽略,結(jié)果是一個(gè)使得datetime2 + t == datetime1的timedelta對(duì)象 t。 在此情況下不會(huì)進(jìn)行時(shí)區(qū)調(diào)整。如果兩個(gè)操作數(shù)都是感知型且具有不同的
tzinfo屬性,a-b操作的行為就如同 a 和 b 被首先轉(zhuǎn)換為簡(jiǎn)單型 UTC 日期時(shí)間。 結(jié)果將是(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())除非具體實(shí)現(xiàn)絕對(duì)不溢出。當(dāng) datetime1 的時(shí)間在 datetime2 之前則認(rèn)為 datetime1 小于 datetime2。
如果比較的一方是簡(jiǎn)單型而另一方是感知型,則如果嘗試進(jìn)行順序比較將引發(fā)
TypeError。 對(duì)于相等比較,簡(jiǎn)單型實(shí)例將永遠(yuǎn)不等于感知型實(shí)例。如果兩個(gè)比較方都是感知型,且具有相同的
tzinfo屬性,相同的tzinfo屬性會(huì)被忽略并對(duì)基本日期時(shí)間值進(jìn)行比較。 如果兩個(gè)比較方都是感知型且具有不同的tzinfo屬性,兩個(gè)比較方將首先通過減去它們的 UTC 差值(使用self.utcoffset()獲?。﹣磉M(jìn)行調(diào)整。注解
為了防止比較操作回退為默認(rèn)的對(duì)象地址比較方案,datetime 比較通常會(huì)引發(fā)
TypeError,如果比較目標(biāo)不同樣為datetime對(duì)象的話。 不過也可能會(huì)返回NotImplemented如果比較目標(biāo)具有timetuple()屬性的話。 這個(gè)鉤子給予其他日期對(duì)象類型實(shí)現(xiàn)混合類型比較的機(jī)會(huì)。 否則,當(dāng)datetime對(duì)象與不同類型的對(duì)象比較時(shí)將會(huì)引發(fā)TypeError,除非==或!=比較。 后兩種情況將分別返回False或True。
datetime 對(duì)象可以用作字典的鍵。 在布爾運(yùn)算時(shí),所有 datetime 對(duì)象都被視為真值。
實(shí)例方法:
-
datetime.time()? 返回具有同樣 hour, minute, second, microsecond 和 fold 值的
time對(duì)象。tzinfo為None。 另請(qǐng)參見方法timetz()。在 3.6 版更改: fold 值會(huì)被復(fù)制給返回的
time對(duì)象。
-
datetime.timetz()? 返回具有同樣 hour, minute, second, microsecond, fold 和 tzinfo 屬性值的
time對(duì)象。 另請(qǐng)參見方法time()。在 3.6 版更改: fold 值會(huì)被復(fù)制給返回的
time對(duì)象。
-
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)? 返回一個(gè)具有同樣屬性值的 datetime,除非通過任何關(guān)鍵字參數(shù)指定了某些屬性值。 請(qǐng)注意可以通過指定
tzinfo=None從一個(gè)感知型 datetime 創(chuàng)建一個(gè)簡(jiǎn)單型 datetime 而不必轉(zhuǎn)換日期和時(shí)間值。3.6 新版功能: 增加了
fold參數(shù)。
-
datetime.astimezone(tz=None)? 返回一個(gè)具有新的
tzinfo屬性 tz 的datetime對(duì)象,并會(huì)調(diào)整日期和時(shí)間數(shù)據(jù)使得結(jié)果對(duì)應(yīng)的 UTC 時(shí)間與 self 相同,但為 tz 時(shí)區(qū)的本地時(shí)間。tz 如果給出則必須是一個(gè)
tzinfo子類的實(shí)例,并且其utcoffset()和dst()方法不可返回None。 如果 self 為簡(jiǎn)單型,它會(huì)被假定為基于系統(tǒng)時(shí)區(qū)表示的時(shí)間。如果調(diào)用時(shí)不傳入?yún)?shù)(或傳入
tz=None) 則將假定目標(biāo)時(shí)區(qū)為系統(tǒng)的本地時(shí)區(qū)。 轉(zhuǎn)換后 datetime 實(shí)例的.tzinfo屬性將被設(shè)為一個(gè)timezone實(shí)例,時(shí)區(qū)名稱和時(shí)差值將從系統(tǒng)獲取。如果
self.tzinfo為 tz,self.astimezone(tz)等于 self: 不會(huì)對(duì)日期或時(shí)間數(shù)據(jù)進(jìn)行調(diào)整。 否則結(jié)果為 tz 時(shí)區(qū)的本地時(shí)間,代表的 UTC 時(shí)間與 self 相同:在astz = dt.astimezone(tz)之后,astz - astz.utcoffset()將具有與dt - dt.utcoffset()相同的日期和時(shí)間數(shù)據(jù)。如果你只想附加一個(gè)時(shí)區(qū)對(duì)象 tz 給一個(gè) datetime 對(duì)象 dt 而不調(diào)整日期和時(shí)間數(shù)據(jù),請(qǐng)使用
dt.replace(tzinfo=tz)。 如果你只想從一個(gè)感知型 datetime 對(duì)象 dt 移除時(shí)區(qū)對(duì)象則不轉(zhuǎn)換日期和時(shí)間數(shù)據(jù),請(qǐng)使用dt.replace(tzinfo=None)。請(qǐng)注意默認(rèn)的
tzinfo.fromutc()方法在tzinfo的子類中可以被重載,從而影響astimezone()的返回結(jié)果。 如果忽略出錯(cuò)的情況,astimezone()的行為就類似于:def astimezone(self, tz): if self.tzinfo is tz: return self # Convert self to UTC, and attach the new time zone object. utc = (self - self.utcoffset()).replace(tzinfo=tz) # Convert from UTC to tz's local time. return tz.fromutc(utc)
在 3.3 版更改: tz 現(xiàn)在可以被省略。
在 3.6 版更改:
astimezone()方法可以由簡(jiǎn)單型實(shí)例調(diào)用,這將假定其表示本地時(shí)間。
-
datetime.utcoffset()? 如果
tzinfo為None,則返回None,否則返回self.tzinfo.utcoffset(self),并且在后者不返回None或者一個(gè)幅度小于一天的timedelta對(duì)象時(shí)將引發(fā)異常。在 3.7 版更改: UTC 時(shí)差不再限制為一個(gè)整數(shù)分鐘值。
-
datetime.dst()? 如果
tzinfo為None,則返回None,否則返回self.tzinfo.dst(self),并且在后者不返回None或者一個(gè)幅度小于一天的timedelta對(duì)象時(shí)將引發(fā)異常。在 3.7 版更改: DST 差值不再限制為一個(gè)整數(shù)分鐘值。
-
datetime.tzname()? 如果
tzinfo為None,則返回None,否則返回self.tzinfo.tzname(self),如果后者不返回None或者一個(gè)字符串對(duì)象則將引發(fā)異常。
-
datetime.timetuple()? 返回一個(gè)
time.struct_time,即與time.localtime()的返回類型相同。d.timetuple()等價(jià)于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是日期在當(dāng)前年份中的序號(hào),起始序號(hào)1表示 1 月 1 日。 結(jié)果的tm_isdst旗標(biāo)的設(shè)定會(huì)依據(jù)dst()方法:如果tzinfo為None或dst()返回None,則tm_isdst將設(shè)為-1;否則如果dst()返回一個(gè)非零值,則tm_isdst將設(shè)為1;否則tm_isdst將設(shè)為0。
-
datetime.utctimetuple()? 如果
datetime實(shí)例 d 為簡(jiǎn)單型,這類似于d.timetuple(),不同之處為tm_isdst會(huì)強(qiáng)設(shè)為 0,無論d.dst()返回什么結(jié)果。 DST 對(duì)于 UTC 時(shí)間永遠(yuǎn)無效。如果 d 為感知型,d 會(huì)通過減去
d.utcoffset()被標(biāo)準(zhǔn)化為 UTC 時(shí)間,并返回標(biāo)準(zhǔn)化時(shí)間對(duì)應(yīng)的time.struct_time。tm_isdst會(huì)強(qiáng)設(shè)為 0。 請(qǐng)注意如果 d.year 為MINYEAR或MAXYEAR并且 UTC 調(diào)整超出一年的邊界則可能引發(fā)OverflowError。
-
datetime.toordinal()? 返回日期的預(yù)期格列高利歷序號(hào)。 與
self.date().toordinal()相同。
-
datetime.timestamp()? 返回對(duì)應(yīng)于
datetime實(shí)例的 POSIX 時(shí)間戳。 返回值是與time.time()類似的float。簡(jiǎn)單型
datetime實(shí)例會(huì)假定為代表本地時(shí)間,并且此方法依賴于平臺(tái)的 Cmktime()函數(shù)來執(zhí)行轉(zhuǎn)換。 由于在許多平臺(tái)上datetime支持的值范圍比mktime()更廣,對(duì)于極其遙遠(yuǎn)的過去或末來時(shí)間此方法可能引發(fā)OverflowError。對(duì)于感知型
datetime實(shí)例,返回值的計(jì)算方式為:(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()
3.3 新版功能.
在 3.6 版更改:
timestamp()方法使用fold屬性來消除重復(fù)間隔中的時(shí)間歧義。注解
沒有一個(gè)方法能直接從簡(jiǎn)單型
datetime實(shí)例獲取 POSIX 時(shí)間戳來代表 UTC 時(shí)間。 如果你的應(yīng)用使用此慣例方式并且你的系統(tǒng)時(shí)區(qū)不是設(shè)為 UTC,你可以通過提供tzinfo=timezone.utc來獲取 POSIX 時(shí)間戳:timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
或者通過直接計(jì)算時(shí)間戳:
timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
-
datetime.weekday()? 返回一個(gè)整數(shù)代表星期幾,星期一為 0,星期天為 6。 相當(dāng)于
self.date().weekday()。 另請(qǐng)參閱isoweekday()。
-
datetime.isoweekday()? 返回一個(gè)整數(shù)代表星期幾,星期一為 1,星期天為 7。 相當(dāng)于
self.date().isoweekday()。 另請(qǐng)參閱weekday(),isocalendar()。
-
datetime.isocalendar()? 返回一個(gè) 3 元組 (ISO 年份, ISO 周序號(hào), ISO 周日期)。 相當(dāng)于
self.date().isocalendar()。
-
datetime.isoformat(sep='T', timespec='auto')? 返回一個(gè)以 ISO 8601 格式表示日期和時(shí)間的字符串 YYYY-MM-DDTHH:MM:SS.ffffff,如果
microsecond為 0 則改用格式 YYYY-MM-DDTHH:MM:SS如果
utcoffset()不返回None,則會(huì)添加一個(gè)字符串來給出 UTC 時(shí)差: YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]],如果microsecond為 0 則改用格式 YYYY-MM-DDTHH:MM:SS+HH:MM[:SS[.ffffff]]。可選參數(shù) sep (默認(rèn)為
'T') 為單個(gè)分隔字符,會(huì)被放在結(jié)果的日期和時(shí)間兩部分之間。例如>>> from datetime import tzinfo, timedelta, datetime >>> class TZ(tzinfo): ... def utcoffset(self, dt): return timedelta(minutes=-399) ... >>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ') '2002-12-25 00:00:00-06:39'
可選參數(shù) timespec 要包含的額外時(shí)間組件值 (默認(rèn)為
'auto')。它可以是以下值之一:'auto': 如果microsecond為 0 則與'seconds'相同,否則與'microseconds'相同。'hours': 以兩個(gè)數(shù)碼的 HH 格式包含hour。'milliseconds': 包含完整時(shí)間,但將秒值的小數(shù)部分截?cái)嘀廖⒚搿?格式為 HH:MM:SS.sss。'microseconds': 以HH:MM:SS.ffffff 格式包含完整時(shí)間。
注解
排除掉的時(shí)間部分將被截?cái)啵皇潜簧崛搿?/p>
對(duì)于無效的 timespec 參數(shù)將引發(fā)
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 參數(shù)。
-
datetime.ctime()? 返回一個(gè)代表日期和時(shí)間的字符串,例如
datetime(2002, 12, 4, 20, 30, 40).ctime() == 'Wed Dec 4 20:30:40 2002'。 在原生 Cctime()函數(shù) (time.ctime()會(huì)發(fā)起調(diào)用該函數(shù),但datetime.ctime()則不會(huì)) 遵循 C 標(biāo)準(zhǔn)的平臺(tái)上,d.ctime()等價(jià)于time.ctime(time.mktime(d.timetuple()))。
-
datetime.strftime(format)? 返回一個(gè)由顯式格式字符串所指明的代表日期和時(shí)間的字符串, 要獲取格式指令的完整列表請(qǐng)參閱 strftime() 和 strptime() 的行為。
-
datetime.__format__(format)? 與
datetime.strftime()相同。 此方法使得為datetime對(duì)象指定以 格式化字符串字面值 表示的格式化字符串以及使用str.format()進(jìn)行格式化成為可能。 要獲取格式指令的完整列表,請(qǐng)參閱 strftime() 和 strptime() 的行為。
使用 datetime 對(duì)象的例子:
>>> from datetime import datetime, date, time
>>> # 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() or datetime.utcnow()
>>> datetime.now()
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043) # GMT +1
>>> datetime.utcnow()
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060)
>>> # 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 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.'
使用 datetime 并附帶 tzinfo:
>>> 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):
... # 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):
... # 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
...
... # 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")
...
... 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):
... return timedelta(0)
...
... def tzname(self, dt):
... if dt >= self.UTC_MOVE_DATE:
... return "+04:30"
... else:
... return "+04"
...
... def __repr__(self):
... return f"{self.__class__.__name__}()"
...
>>> 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.utctimetuple() == dt3.utctimetuple()
True
time 對(duì)象?
一個(gè) time 對(duì)象代表某個(gè)日期內(nèi)的(本地)時(shí)間,它獨(dú)立于任何特定日期,并可通過 tzinfo 對(duì)象來調(diào)整。
-
class
datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)? 所有參數(shù)都是可選的。 tzinfo 可以是
None,或者是一個(gè)tzinfo子類的實(shí)例。 其余的參數(shù)必須是在下面范圍內(nèi)的整數(shù):0 <= hour < 24,0 <= minute < 60,0 <= second < 60,0 <= microsecond < 1000000,fold in [0, 1].
如果給出一個(gè)此范圍以外的參數(shù),則會(huì)引發(fā)
ValueError。 所有參數(shù)值默認(rèn)為0,除了 tzinfo 默認(rèn)為None。
類屬性:
-
time.resolution? 兩個(gè)不相等的
time對(duì)象之間可能的最小間隔,timedelta(microseconds=1),但是請(qǐng)注意time對(duì)象并不支持算術(shù)運(yùn)算。
實(shí)例屬性(只讀):
-
time.hour? 取值范圍是
range(24)。
-
time.minute? 取值范圍是
range(60)。
-
time.second? 取值范圍是
range(60)。
-
time.microsecond? 取值范圍是
range(1000000)。
-
time.fold? 取值范圍是
[0, 1]。 用于在重復(fù)的時(shí)間段中消除邊界時(shí)間歧義。 (當(dāng)夏令時(shí)結(jié)束時(shí)回調(diào)時(shí)鐘或由于政治原因?qū)е庐?dāng)前時(shí)區(qū)的 UTC 時(shí)差減少就會(huì)出現(xiàn)重復(fù)的時(shí)間段。) 取值 0 (1) 表示兩個(gè)時(shí)刻早于(晚于)所代表的同一邊界時(shí)間。3.6 新版功能.
支持的運(yùn)算:
比較
time和另一個(gè)time,當(dāng) a 的時(shí)間在 b 之前時(shí),則認(rèn)為 a 小于 b。 如果比較的一方是簡(jiǎn)單型而另一方是感知型,則如果嘗試進(jìn)行順序比較將引發(fā)TypeError。 對(duì)于相等比較,簡(jiǎn)單型實(shí)例將永遠(yuǎn)不等于感知型實(shí)例。如果兩個(gè)比較方都是感知型,且具有相同的
tzinfo屬性,相同的tzinfo屬性會(huì)被忽略并對(duì)基本時(shí)間值進(jìn)行比較。 如果兩個(gè)比較方都是感知型且具有不同的tzinfo屬性,兩個(gè)比較方將首先通過減去它們的 UTC 差值(使用self.utcoffset()獲取)來進(jìn)行調(diào)整。 為了防止將混合類型比較回退為基于對(duì)象地址的默認(rèn)比較,當(dāng)time對(duì)象與不同類型的對(duì)象比較時(shí),將會(huì)引發(fā)TypeError,除非比較運(yùn)算符是==或!=。 在后一種情況下將分別返回False或True。哈希,以便用作字典的鍵
高效的封存
在布爾運(yùn)算時(shí),time 對(duì)象總是被視為真值。
在 3.5 版更改: 在 Python 3.5 之前,如果一個(gè) time 對(duì)象代表 UTC 午夜零時(shí)則會(huì)被視為假值。 此行為被認(rèn)為容易引發(fā)困惑和錯(cuò)誤,因此從 Python 3.5 起已被去除。 詳情參見 bpo-13936。
其他構(gòu)造方法:
-
classmethod
time.fromisoformat(time_string)? 返回對(duì)應(yīng)于
time.isoformat()所提供的 time_string 格式的time。 特別地此函數(shù)支持HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]格式的字符串。警告
此方法不支持解析任意 ISO 8601 字符串 —— 它的目的只是作為
time.isoformat()的逆操作。3.7 新版功能.
實(shí)例方法:
-
time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)? 返回一個(gè)具有同樣屬性值的
time,除非通過任何關(guān)鍵字參數(shù)指定了某些屬性值。 請(qǐng)注意可以通過指定tzinfo=None從一個(gè)感知型time創(chuàng)建一個(gè)簡(jiǎn)單型time而不必轉(zhuǎn)換時(shí)間值。3.6 新版功能: 增加了
fold參數(shù)。
-
time.isoformat(timespec='auto')? 返回一個(gè)表示時(shí)間的字符串,使用 ISO 8601 格式 HH:MM:SS.ffffff,或者如果
microsecond為 0 則改用格式 HH:MM:SS, 如果utcoffset()不返回None,則會(huì)添加一個(gè)字符串來給出 UTC 時(shí)差: HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]],或者如果 self.microsecond 為 0 則改用格式 HH:MM:SS+HH:MM[:SS[.ffffff]]。可選參數(shù) timespec 要包含的額外時(shí)間組件值 (默認(rèn)為
'auto')。它可以是以下值之一:'auto': 如果microsecond為 0 則與'seconds'相同,否則與'microseconds'相同。'hours': 以兩個(gè)數(shù)碼的 HH 格式包含hour。'milliseconds': 包含完整時(shí)間,但將秒值的小數(shù)部分截?cái)嘀廖⒚搿?格式為 HH:MM:SS.sss。'microseconds': 以HH:MM:SS.ffffff 格式包含完整時(shí)間。
注解
排除掉的時(shí)間部分將被截?cái)?,而不是被舍入?/p>
對(duì)于無效的 timespec 參數(shù)將引發(fā)
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 參數(shù)。
-
time.__str__()? 對(duì)于時(shí)間對(duì)象 t,
str(t)等價(jià)于t.isoformat()。
-
time.strftime(format)? 返回一個(gè)由顯式格式字符串所指明的代表時(shí)間的字符串。 要獲取格式指令的完整列表請(qǐng)參閱 strftime() 和 strptime() 的行為。
-
time.__format__(format)? 與
time.strftime()相同。 此方法使得為time對(duì)象指定以 格式化字符串字面值 表示的格式化字符串以及使用str.format()進(jìn)行格式化成為可能。 要獲取格式指令的完整列表,請(qǐng)參閱 strftime() 和 strptime() 的行為。
-
time.utcoffset()? 如果
tzinfo為None,則返回None,否則返回self.tzinfo.utcoffset(None),并且在后者不返回None或一個(gè)幅度小于一天的 atimedelta對(duì)象時(shí)將引發(fā)異常。在 3.7 版更改: UTC 時(shí)差不再限制為一個(gè)整數(shù)分鐘值。
-
time.dst()? 如果
tzinfo為None,則返回None,否則返回self.tzinfo.dst(None),并且在后者不返回None或者一個(gè)幅度小于一天的timedelta對(duì)象時(shí)將引發(fā)異常。在 3.7 版更改: DST 差值不再限制為一個(gè)整數(shù)分鐘值。
-
time.tzname()? 如果
tzinfo為None,則返回None,否則返回self.tzinfo.tzname(None),如果后者不返回None或者一個(gè)字符串對(duì)象則將引發(fā)異常。
示例:
>>> 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 對(duì)象?
-
class
datetime.tzinfo? 這是一個(gè)抽象基類,即這個(gè)類不可直接被實(shí)例化。 你必須從該類派生一個(gè)實(shí)體子類,并且(至少)提供你使用
datetime需要的標(biāo)準(zhǔn)tzinfo方法的實(shí)現(xiàn)。datetime模塊提供了tzinfo的一個(gè)簡(jiǎn)單實(shí)體子類,timezone,它能以與 UTC 的固定差值來表示不同的時(shí)區(qū),例如 UTC 本身或北美的 EST 和 EDT。tzinfo的(某個(gè)實(shí)體子類)的實(shí)例可以被傳給datetime和time對(duì)象的構(gòu)造器。 這些對(duì)象會(huì)將它們的屬性視為對(duì)應(yīng)于本地時(shí)間,并且tzinfo對(duì)象支持展示本地時(shí)間與 UTC 的差值、時(shí)區(qū)名稱以及 DST 差值的方法,都是與傳給它們的日期或時(shí)間對(duì)象的相對(duì)值。對(duì)于封存操作的特殊要求:一個(gè)
tzinfo子類必須具有可不帶參數(shù)調(diào)用的__init__()方法,否則它雖然可以被封存,但可能無法再次解封。 這是個(gè)技術(shù)性要求,在未來可能會(huì)被取消。一個(gè)
tzinfo的實(shí)體子類可能需要實(shí)現(xiàn)以下方法。 具體需要實(shí)現(xiàn)的方法取決于感知型datetime對(duì)象如何使用它。 如果有疑問,可以簡(jiǎn)單地全都實(shí)現(xiàn)。
-
tzinfo.utcoffset(dt)? 返回本地時(shí)間與 UTC 的差值為一個(gè)
timedelta對(duì)象,在 UTC 以東為正值。 如果本地時(shí)間在 UTC 以西則為負(fù)值。 請(qǐng)注意這應(yīng)當(dāng)是與 UTC 的總計(jì)差值;即如果tzinfo對(duì)象同時(shí)代表時(shí)區(qū)和 DST 調(diào)整,utcoffset()應(yīng)當(dāng)返回兩者的和。 如果 UTC 差值不確定則返回None。 其他情況下返回值必須為一個(gè)timedelta對(duì)象,值的范圍嚴(yán)格限制于-timedelta(hours=24)和timedelta(hours=24)之間(差值的幅度必須小于一天)。 大多數(shù)utcoffset()的實(shí)現(xiàn)看起來可能像是以下兩者之一:return CONSTANT # fixed-offset class return CONSTANT + self.dst(dt) # daylight-aware class
如果
utcoffset()返回值不為None,則dst()也不應(yīng)返回None。默認(rèn)的
utcoffset()實(shí)現(xiàn)會(huì)引發(fā)NotImplementedError。在 3.7 版更改: UTC 時(shí)差不再限制為一個(gè)整數(shù)分鐘值。
-
tzinfo.dst(dt)? 返回夏令時(shí)(DST)調(diào)整值為一個(gè)
timedelta對(duì)象或當(dāng) DST 信息未知時(shí)返回None。 如果 DST 未啟用則返回timedelta(0)。 如果 DST 已啟用則返回調(diào)整值為一個(gè)timedelta對(duì)象(參見utcoffset()了解詳情)。 請(qǐng)注意 DST 差值如果可用,就會(huì)直接被加入utcoffset()所返回的 UTC 差值,因此無需額外查詢dst()除非你希望單獨(dú)獲取 DST 信息。 例如,datetime.timetuple()會(huì)調(diào)用其tzinfo屬性的dst()方法來確定應(yīng)當(dāng)如何設(shè)置tm_isdst旗標(biāo),而tzinfo.fromutc()會(huì)調(diào)用dst()來在跨越時(shí)區(qū)時(shí)處理 DST 的改變。一個(gè)可以同時(shí)處理標(biāo)準(zhǔn)時(shí)和夏令時(shí)的
tzinfo子類的實(shí)例 tz 必須在此情形中保持一致:tz.utcoffset(dt) - tz.dst(dt)必須為具有同樣的
tzinfo子類實(shí)例dt.tzinfo == tz的每個(gè)datetime對(duì)象 dt 返回同樣的結(jié)果,此表達(dá)式會(huì)產(chǎn)生時(shí)區(qū)的“標(biāo)準(zhǔn)時(shí)差”,它不應(yīng)取決于具體日期或時(shí)間,只取決于地理位置。datetime.astimezone()的實(shí)現(xiàn)依賴此方法,但無法檢測(cè)違反規(guī)則的情況;確保符合規(guī)則是程序員的責(zé)任。 如果一個(gè)tzinfo子類不能保證這一點(diǎn),也許應(yīng)該重載tzinfo.fromutc()的默認(rèn)實(shí)現(xiàn)以便在任何情況下與astimezone()配合正常。大多數(shù)
dst()的實(shí)現(xiàn)可能會(huì)如以下兩者之一: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. Then if dston <= dt.replace(tzinfo=None) < dstoff: return timedelta(hours=1) else: return timedelta(0)
默認(rèn)的
dst()實(shí)現(xiàn)會(huì)引發(fā)NotImplementedError。在 3.7 版更改: DST 差值不再限制為一個(gè)整數(shù)分鐘值。
-
tzinfo.tzname(dt)? 將對(duì)應(yīng)于
datetime對(duì)象 dt 的時(shí)區(qū)名稱作為字符串返回。datetime模塊沒有定義任何字符串名稱相關(guān)內(nèi)容,也不要求名稱有任何特定含義。 例如,"GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" 都是有效的返回值。 如果字符串名稱未知?jiǎng)t返回None。 請(qǐng)注意這是一個(gè)方法而不是一個(gè)固定的字符串,這主要是因?yàn)槟承?tzinfo子類可能需要根據(jù)所傳入的特定 dt 值返回不同的名稱,特別是當(dāng)tzinfo類要負(fù)責(zé)處理夏令時(shí)的時(shí)候。默認(rèn)的
tzname()實(shí)現(xiàn)會(huì)引發(fā)NotImplementedError。
這些方法會(huì)被 datetime 或 time 對(duì)象調(diào)用,用來對(duì)應(yīng)它們的同名方法。 datetime 對(duì)象會(huì)將自身作為傳入?yún)?shù),而 time 對(duì)象會(huì)將 None 作為傳入?yún)?shù)。 這樣 tzinfo 子類的方法應(yīng)當(dāng)準(zhǔn)備好接受 dt 參數(shù)值為 None 或是 datetime 類的實(shí)例。
當(dāng)傳入 None 時(shí),應(yīng)當(dāng)由類的設(shè)計(jì)者來決定最佳回應(yīng)方式。 例如,返回 None 適用于希望該類提示時(shí)間對(duì)象不參與 tzinfo 協(xié)議處理。 讓 utcoffset(None) 返回標(biāo)準(zhǔn) UTC 時(shí)差也許會(huì)更有用處,如果沒有其他用于發(fā)現(xiàn)標(biāo)準(zhǔn)時(shí)差的約定。
當(dāng)傳入一個(gè) datetime 對(duì)象來回應(yīng) datetime 方法時(shí),dt.tzinfo 與 self 是同一對(duì)象。 tzinfo 方法可以依賴這一點(diǎn),除非用戶代碼直接調(diào)用了 tzinfo 方法。 此行為的目的是使得 tzinfo 方法將 dt 解讀為本地時(shí)間,而不需要擔(dān)心其他時(shí)區(qū)的相關(guān)對(duì)象。
還有一個(gè)額外的 tzinfo 方法,某個(gè)子類可能會(huì)希望重載它:
-
tzinfo.fromutc(dt)? 此方法會(huì)由默認(rèn)的
datetime.astimezone()實(shí)現(xiàn)來調(diào)用。 當(dāng)被調(diào)用時(shí),dt.tzinfo為 self,并且 dt 的日期和時(shí)間數(shù)據(jù)會(huì)被視為代表 UTC 時(shí)間。fromutc()的目標(biāo)是調(diào)整日期和時(shí)間數(shù)據(jù),返回一個(gè)等價(jià)的 datetime 來表示 self 的本地時(shí)間。大多數(shù)
tzinfo子類應(yīng)該能夠毫無問題地繼承默認(rèn)的fromutc()實(shí)現(xiàn)。 它的健壯性足以處理固定差值的時(shí)區(qū)以及同時(shí)負(fù)責(zé)標(biāo)準(zhǔn)時(shí)和夏令時(shí)的時(shí)區(qū),對(duì)于后者甚至還能處理 DST 轉(zhuǎn)換時(shí)間在各個(gè)年份有變化的情況。 一個(gè)默認(rèn)fromutc()實(shí)現(xiàn)可能無法在所有情況下正確處理的例子是(與 UTC 的)標(biāo)準(zhǔn)差值取決于所經(jīng)過的特定日期和時(shí)間,這種情況可能由于政治原因而出現(xiàn)。 默認(rèn)的astimezone()和fromutc()實(shí)現(xiàn)可能無法生成你希望的結(jié)果,如果這個(gè)結(jié)果恰好是跨越了標(biāo)準(zhǔn)差值發(fā)生改變的時(shí)刻當(dāng)中的某個(gè)小時(shí)值的話。忽略針對(duì)錯(cuò)誤情況的代碼,默認(rèn)
fromutc()實(shí)現(xiàn)的行為方式如下: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
# http://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")
請(qǐng)注意同時(shí)負(fù)責(zé)標(biāo)準(zhǔn)時(shí)和夏令時(shí)的 tzinfo 子類在每年兩次的 DST 轉(zhuǎn)換點(diǎn)上會(huì)出現(xiàn)不可避免的微妙問題。 具體而言,考慮美國(guó)東部時(shí)區(qū) (UTC -0500),它的 EDT 從三月的第二個(gè)星期天 1:59 (EST) 之后一分鐘開始,并在十一月的第一個(gè)星期天 1:59 (EDT) 之后一分鐘結(jié)束:
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
當(dāng) DST 開始時(shí)(見 "start" 行),本地時(shí)鐘從 1:59 跳到 3:00。 形式為 2:MM 的時(shí)間值在那一天是沒有意義的,因此在 DST 開始的那一天 astimezone(Eastern) 不會(huì)輸出包含 hour == 2 的結(jié)果。 例如,在 2016 年春季時(shí)鐘向前調(diào)整時(shí),我們得到
>>> 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
當(dāng) DST 結(jié)束時(shí)(見 "end" 行),會(huì)有更糟糕的潛在問題:本地時(shí)間值中有一個(gè)小時(shí)是不可能沒有歧義的:夏令時(shí)的最后一小時(shí)。 即以美國(guó)東部時(shí)間表示當(dāng)天夏令時(shí)結(jié)束時(shí)的形式為 5:MM UTC 的時(shí)間。 本地時(shí)間從 1:59 (夏令時(shí)) 再次跳回到 1:00 (標(biāo)準(zhǔn)時(shí))。 形式為 1:MM 的本地時(shí)間就是有歧義的。 此時(shí) astimezone() 是通過將兩個(gè)相鄰的 UTC 小時(shí)映射到兩個(gè)相同的本地小時(shí)來模仿本地時(shí)鐘的行為。 在這個(gè)美國(guó)東部時(shí)間的示例中,形式為 5:MM 和 6:MM 的 UTC 時(shí)間在轉(zhuǎn)換為美國(guó)東部時(shí)間時(shí)都將被映射到 1:MM,但前一個(gè)時(shí)間會(huì)將 fold 屬性設(shè)為 0 而后一個(gè)時(shí)間會(huì)將其設(shè)為 1。 例如,在 2016 年秋季時(shí)鐘往回調(diào)整時(shí),我們得到
>>> 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
請(qǐng)注意不同的 datetime 實(shí)例僅通過 fold 屬性值來加以區(qū)分,它們?cè)诒容^時(shí)會(huì)被視為相等。
不允許時(shí)間顯示存在歧義的應(yīng)用需要顯式地檢查 fold 屬性的值,或者避免使用混合式的 tzinfo 子類;當(dāng)使用 timezone 或者任何其他固定差值的 tzinfo 子類例如僅表示 EST(固定差值 -5 小時(shí))或僅表示 EDT(固定差值 -4 小時(shí))的類時(shí)是不會(huì)有歧義的。
參見
- dateutil.tz
該標(biāo)準(zhǔn)庫具有
timezone類用來將相對(duì)于 UTC 和timezone.utc的任意固定差值處理為 UTC 時(shí)區(qū)實(shí)例。dateutil.tz 庫將 IANA 時(shí)區(qū)數(shù)據(jù)庫 (又名 Olson 數(shù)據(jù)庫) 引入 Python 并推薦使用。
- IANA 時(shí)區(qū)數(shù)據(jù)庫
該時(shí)區(qū)數(shù)據(jù)庫 (通常稱為 tz, tzdata 或 zoneinfo) 包含大量代碼和數(shù)據(jù)用來表示全球許多有代表性的地點(diǎn)的本地時(shí)間的歷史信息。 它會(huì)定期進(jìn)行更新以反映各政治實(shí)體對(duì)時(shí)區(qū)邊界、UTC 差值和夏令時(shí)規(guī)則的更改。
timezone 對(duì)象?
timezone 類是 tzinfo 的一個(gè)子類,它的每個(gè)實(shí)例代表一個(gè)由與 UTC 的固定差值所定義的時(shí)區(qū)。 請(qǐng)注意該類的對(duì)象不可被用于代表某些特殊地點(diǎn)的時(shí)區(qū)信息,例如在一年的不同日期使用不同差值,或是在歷史上對(duì)民用時(shí)間進(jìn)行過調(diào)整的地點(diǎn)。
-
class
datetime.timezone(offset, name=None)? offset 參數(shù)必須指定為一個(gè)
timedelta對(duì)象,表示本地時(shí)間與 UTC 的差值。 它必須嚴(yán)格限制于-timedelta(hours=24)和timedelta(hours=24)之間,否則會(huì)引發(fā)ValueError。name 參數(shù)是可選的。 如果指定則必須為一個(gè)字符串,它將被用作
datetime.tzname()方法的返回值。3.2 新版功能.
在 3.7 版更改: UTC 時(shí)差不再限制為一個(gè)整數(shù)分鐘值。
-
timezone.utcoffset(dt)? 返回在構(gòu)造
timezone實(shí)例時(shí)指定的固定值。 dt 參數(shù)會(huì)被忽略。 返回值是一個(gè)timedelta實(shí)例,其值等于本地時(shí)間與 UTC 之間的差值。在 3.7 版更改: UTC 時(shí)差不再限制為一個(gè)整數(shù)分鐘值。
-
timezone.tzname(dt)? 返回在構(gòu)造
timezone實(shí)例時(shí)指定的固定值。 如果沒有為構(gòu)造器提供 name,則tzname(dt)所返回的名稱將根據(jù)offset值按以下規(guī)則生成。 如果 offset 為timedelta(0),則名稱為 "UTC",否則為字符串 'UTC±HH:MM',其中 ± 為offset值的正負(fù),HH 和 MM 分別為表示offset.hours和offset.minutes的兩個(gè)數(shù)碼。在 3.6 版更改: 由
offset=timedelta(0)生成的名稱現(xiàn)在改為簡(jiǎn)單的 'UTC' 而不再是 'UTC+00:00'。
-
timezone.dst(dt)? 總是返回
None。
-
timezone.fromutc(dt)? 返回
dt + offset。 dt 參數(shù)必須為一個(gè)感知型datetime實(shí)例,其中tzinfo值設(shè)為self。
類屬性:
-
timezone.utc? UTC 時(shí)區(qū),
timezone(timedelta(0))。
strftime() 和 strptime() 的行為?
date, datetime 和 time 對(duì)象都支持 strftime(format) 方法,可用來創(chuàng)建一個(gè)由指定格式字符串所控制的表示時(shí)間的字符串。 總體而言,d.strftime(fmt) 類似于 time 模塊的 time.strftime(fmt, d.timetuple()) 但是并非所有對(duì)象都支持 timetuple() 方法。
相反地,datetime.strptime() 類方法可根據(jù)一個(gè)表示時(shí)間的字符串和對(duì)應(yīng)的格式字符串創(chuàng)建來一個(gè) datetime 對(duì)象。 datetime.strptime(date_string, format) 等價(jià)于 datetime(*(time.strptime(date_string, format)[0:6])),差別在于當(dāng) format 包含小于秒的部分或者時(shí)區(qū)差值信息的時(shí)候,這些信息被 datetime.strptime 所支持但會(huì)被 time.strptime 所丟棄。
對(duì)于 time 對(duì)象,年、月、日的格式代碼不應(yīng)被使用,因?yàn)?time 對(duì)象沒有這些值。 如果它們被使用,年份將被替換為 1900 而月和日將被替換為 1。
對(duì)于 date 對(duì)象,時(shí)、分、秒和微秒的格式代碼不應(yīng)被使用,因?yàn)?date 對(duì)象沒有這些值。 如果它們被使用,它們都將被替換為 0。
對(duì)于 datetime.strptime() 類方法,默認(rèn)值為 1900-01-01T00:00:00.000: 任何未在格式字符串中指定的部分都將從默認(rèn)值中提取。 2
對(duì)完整格式代碼集的支持在不同平臺(tái)上有所差異,因?yàn)?Python 要調(diào)用所在平臺(tái) C 庫的 strftime() 函數(shù),而不同平臺(tái)的差異是很常見的。 要查看你所用平臺(tái)所支持的完整格式代碼集,請(qǐng)參閱 strftime(3) 文檔。
出于相同的原因,對(duì)于包含當(dāng)前區(qū)域設(shè)置字符集所無法表示的 Unicode 碼位的格式字符串的處理方式也取決于具體平臺(tái)。 在某些平臺(tái)上這樣的碼位會(huì)不加修改地原樣輸出,而在其他平臺(tái)上 strftime 則可能引發(fā) UnicodeError 或只返回一個(gè)空字符串。
以下列表顯示了 C 標(biāo)準(zhǔn)(1989 版)所要求的全部格式代碼,它們?cè)趲в袠?biāo)準(zhǔn) C 實(shí)現(xiàn)的所有平臺(tái)上均可用。 請(qǐng)注意 1999 版 C 標(biāo)準(zhǔn)又添加了額外的格式代碼。
指令 |
含義 |
示例 |
注釋 |
|---|---|---|---|
|
當(dāng)?shù)毓ぷ魅盏目s寫。 |
Sun, Mon, ..., Sat (美國(guó));
So, Mo, ..., Sa (德國(guó))
|
(1) |
|
當(dāng)?shù)毓ぷ魅盏娜?/p> |
Sunday, Monday, ..., Saturday (美國(guó));
Sonntag, Montag, ..., Samstag (德國(guó))
|
(1) |
|
以十進(jìn)制數(shù)顯示的工作日,其中0表示星期日,6表示星期六。 |
0, 1, ..., 6 |
|
|
補(bǔ)零后,以十進(jìn)制數(shù)顯示的月份中的一天。 |
01, 02, ..., 31 |
(9) |
|
當(dāng)?shù)卦路莸目s寫。 |
Jan, Feb, ..., Dec (美國(guó));
Jan, Feb, ..., Dez (德國(guó))
|
(1) |
|
當(dāng)?shù)卦路莸娜?/p> |
January, February, ..., December (美國(guó));
Januar, Februar, ..., Dezember (德國(guó))
|
(1) |
|
補(bǔ)零后,以十進(jìn)制數(shù)顯示的月份。 |
01, 02, ..., 12 |
(9) |
|
補(bǔ)零后,以十進(jìn)制數(shù)表示的,不帶世紀(jì)的年份。 |
00, 01, ..., 99 |
(9) |
|
十進(jìn)制數(shù)表示的帶世紀(jì)的年份。 |
0001, 0002, ..., 2013, 2014, ..., 9998, 9999 |
(2) |
|
以補(bǔ)零后的十進(jìn)制數(shù)表示的小時(shí)(24 小時(shí)制)。 |
00, 01, ..., 23 |
(9) |
|
以補(bǔ)零后的十進(jìn)制數(shù)表示的小時(shí)(12 小時(shí)制)。 |
01, 02, ..., 12 |
(9) |
|
本地化的 AM 或 PM 。 |
AM, PM (美國(guó));
am, pm (德國(guó))
|
(1), (3) |
|
補(bǔ)零后,以十進(jìn)制數(shù)顯示的分鐘。 |
00, 01, ..., 59 |
(9) |
|
補(bǔ)零后,以十進(jìn)制數(shù)顯示的秒。 |
00, 01, ..., 59 |
(4), (9) |
|
以十進(jìn)制數(shù)表示的微秒,在左側(cè)補(bǔ)零。 |
000000, 000001, ..., 999999 |
(5) |
|
±HHMM[SS[.ffffff]] 形式的 UTC 差值(如果對(duì)象為簡(jiǎn)單型則為空字符串)。 |
(空), +0000, -0400, +1030, +063415, -030712.345216 |
(6) |
|
時(shí)區(qū)名稱(如果對(duì)象為簡(jiǎn)單型則為空字符串)。 |
(空), UTC, EST, CST |
|
|
以補(bǔ)零后的十進(jìn)制數(shù)表示的一年中的日序號(hào)。 |
001, 002, ..., 366 |
(9) |
|
以補(bǔ)零后的十進(jìn)制數(shù)表示的一年中的周序號(hào)(星期日作為每周的第一天)。 在新的一年中第一個(gè)星期日之前的所有日子都被視為是在第 0 周。 |
00, 01, ..., 53 |
(7), (9) |
|
以十進(jìn)制數(shù)表示的一年中的周序號(hào)(星期一作為每周的第一天)。 在新的一年中第一個(gè)第期一之前的所有日子都被視為是在第 0 周。 |
00, 01, ..., 53 |
(7), (9) |
|
本地化的適當(dāng)日期和時(shí)間表示。 |
Tue Aug 16 21:30:00 1988 (美國(guó));
Di 16 Aug 21:30:00 1988 (德國(guó))
|
(1) |
|
本地化的適當(dāng)日期表示。 |
08/16/88 (None);
08/16/1988 (en_US);
16.08.1988 (de_DE)
|
(1) |
|
本地化的適當(dāng)時(shí)間表示。 |
21:30:00 (en_US);
21:30:00 (de_DE)
|
(1) |
|
字面的 |
% |
有一些并非 C89 標(biāo)準(zhǔn)所要求的額外指令是為使用方便而加入的。 這些形參都與 ISO 8601 日期值相對(duì)應(yīng)。 它們可能不是在所有平臺(tái)上都可通過 strftime() 方法使用。 ISO 8601 年份和 ISO 8601 星期指令并不能與上面的年份和星期序號(hào)指令相互替代。 調(diào)用 strptime() 時(shí)傳入不完整或有歧義的 ISO 8601 指令將引發(fā) ValueError。
指令 |
含義 |
示例 |
注釋 |
|---|---|---|---|
|
帶有世紀(jì)的 ISO 8601 年份,表示包含大部分 ISO 星期 ( |
0001, 0002, ..., 2013, 2014, ..., 9998, 9999 |
(8) |
|
以十進(jìn)制數(shù)顯示的 ISO 8601 星期中的日序號(hào),其中 1 表示星期一。 |
1, 2, ..., 7 |
|
|
以十進(jìn)制數(shù)顯示的 ISO 8601 星期,以星期一作為每周的第一天。 第 01 周為包含 1 月 4 日的星期。 |
01, 02, ..., 53 |
(8), (9) |
3.6 新版功能: 增加了 %G, %u 和 %V。
注釋:
由于此格式依賴于當(dāng)前區(qū)域設(shè)置,因此對(duì)具體輸出值應(yīng)當(dāng)保持謹(jǐn)慎預(yù)期。 字段順序會(huì)發(fā)生改變(例如 "month/day/year" 與 "day/month/year"),并且輸出可能包含使用區(qū)域設(shè)置所指定的默認(rèn)編碼格式的 Unicode 字符(例如如果當(dāng)前區(qū)域?yàn)?
ja_JP,則默認(rèn)編碼格式可能為eucJP,SJIS或utf-8中的一個(gè);使用locale.getlocale()可確定當(dāng)前區(qū)域設(shè)置的編碼格式)。strptime()方法能夠解析整個(gè) [1, 9999] 范圍內(nèi)的年份,但 < 1000 的年份必須加零填充為 4 位數(shù)字寬度。在 3.2 版更改: 在之前的版本中,
strftime()方法只限于 >= 1900 的年份。在 3.3 版更改: 在版本3.2中,
strftime()方法只限于 years >= 1000。當(dāng)與
strptime()方法一起使用時(shí),如果使用%I指令來解析小時(shí),%p指令只影響輸出小時(shí)字段。當(dāng)與
strptime()方法一起使用時(shí),%f指令可接受一至六個(gè)數(shù)碼及左邊的零填充。%f是對(duì) C 標(biāo)準(zhǔn)中格式字符集的擴(kuò)展(但單獨(dú)在 datetime 對(duì)象中實(shí)現(xiàn),因此它總是可用)。對(duì)于簡(jiǎn)單型對(duì)象,
%zand%Z格式代碼會(huì)被替換為空字符串。對(duì)于一個(gè)覺悟型對(duì)象而言:
%zutcoffset()會(huì)被轉(zhuǎn)換為 ±HHMM[SS[.ffffff]] 形式的字符串,其中 HH 為給出 UTC 差值小時(shí)部分的 2 位數(shù)碼字符串,MM 為給出 UTC 差值分鐘部分的 2 位數(shù)碼字符串,SS 為給出 UTC 差值秒部分的2 位數(shù)碼字符串,而 ffffff 為給出 UTC 差值微秒部分的 6 位數(shù)碼字符串。 當(dāng)差值為整數(shù)秒時(shí) ffffff 部分將被省略,而當(dāng)差值為整數(shù)分鐘時(shí) ffffff 和 SS 部分都將被省略。 例如,如果utcoffset()返回timedelta(hours=-3, minutes=-30),%z會(huì)被替換為字符串'-0330'。
在 3.7 版更改: UTC 時(shí)差不再限制為一個(gè)整數(shù)分鐘值。
在 3.7 版更改: 當(dāng)提供
%z指令給strptime()方法時(shí),UTC 差值可以在時(shí)、分和秒之間使用冒號(hào)分隔符。 例如,'+01:00:00'將被解讀為一小時(shí)的差值。 此外,提供'Z'就相當(dāng)于'+00:00'。%Z如果
tzname()返回None,%Z會(huì)被替換為一個(gè)空字符串。 在其他情況下%Z會(huì)被替換為返回值,這必須為一個(gè)字符串。
當(dāng)與
strptime()方法一起使用時(shí),%U和%W僅用于指定星期幾和日歷年份 (%Y) 的計(jì)算。類似于
%U和%W,%V僅用于在strptime()格式字符串中指定星期幾和 ISO 年份 (%G) 的計(jì)算。 還要注意%G和%Y是不可交換的。當(dāng)于
strptime()方法一起使用時(shí),前導(dǎo)的零在格式%d,%m,%H,%I,%M,%S,%J,%U,%W和%V中是可選的。 格式%y不要求有前導(dǎo)的零。
備注
