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。
脚注