datetime
— 基本日期和时间类型¶
源代码: Lib/datetime.py
datetime
模块提供了用于处理日期和时间的类。
虽然支持日期和时间运算,但实现的重点是高效地提取属性以进行输出格式化和操作。
提示
跳至 格式代码。
另请参阅
感知型对象和简单型对象¶
日期和时间对象可以根据是否包含时区信息分为“感知型”或“简单型”。
如果充分了解适用的算法和政治时间调整,例如时区和夏令时信息,则感知型对象可以相对于其他感知型对象定位自身。感知型对象表示时间上的特定时刻,该时刻没有解释的余地。 [1]
简单型对象不包含足够的信息来明确地相对于其他日期/时间对象定位自身。简单型对象是否表示协调世界时 (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。参数可以是整数或浮点数,可以是正数或负数。
只有 *天*、*秒* 和 *微秒* 存储在内部。参数将转换为这些单位
一毫秒转换为 1000 微秒。
一分钟转换为 60 秒。
一小时转换为 3600 秒。
一周转换为 7 天。
然后对天、秒和微秒进行标准化,以使表示形式唯一,其中
0 <= 微秒 < 1000000
0 <= 秒 < 3600*24
(一天中的秒数)-999999999 <= 天 <= 999999999
以下示例说明了如何将 *天*、*秒* 和 *微秒* 以外的任何参数“合并”并标准化为这三个结果属性
>>> 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.max¶
最大的正
timedelta
对象,timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999)
。
请注意,由于标准化的原因,timedelta.max
大于 -timedelta.min
。-timedelta.max
不能表示为 timedelta
对象。
实例属性(只读)
属性 |
值 |
---|---|
|
介于 -999999999 和 999999999 之间(含) |
|
介于 0 和 86399 之间(含) |
|
介于 0 和 999999 之间(含) |
支持的操作
操作 |
结果 |
---|---|
|
|
|
|
|
时间差乘以一个整数。之后, |
通常, |
|
|
时间差乘以一个浮点数。结果使用四舍五入到偶数的规则舍入到最接近的 timedelta.resolution 倍数。 |
|
总持续时间 |
|
时间差除以一个浮点数或整数。结果使用四舍五入到偶数的规则舍入到最接近的 timedelta.resolution 倍数。 |
|
计算向下取整的结果,并丢弃余数(如果有)。在第二种情况下,返回一个整数。(3) |
|
计算余数,并作为 |
|
计算商和余数: |
|
返回一个具有相同值的 |
|
等效于 |
|
当 |
|
返回一个格式为 |
|
返回 |
备注
这是精确的,但可能会溢出。
这是精确的,并且不会溢出。
零不能做除数,否则会引发
ZeroDivisionError
。-timedelta.max
不能表示为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)
时,才认为它是 True。
实例方法
- 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)¶
返回与任何有效的 ISO 8601 格式给出的 date_string 对应的
date
,但以下情况除外当前不支持精度降低的日期(
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 版新增。
类属性
- 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
对象表示相同的日期,则它们相等。如果 date1 在时间上先于 date2,则认为 date1 小于 date2。换句话说,当且仅当
date1.toordinal() < date2.toordinal()
时,date1 < date2
。
在布尔上下文中,所有 date
对象都被视为真。
实例方法
- date.replace(year=self.year, month=self.month, day=self.day)¶
返回一个与原日期值相同的日期,但对于那些由任何指定的关键字参数赋予新值的日期参数除外。
示例
>>> from datetime import date >>> d = date(2002, 12, 31) >>> d.replace(day=26) datetime.date(2002, 12, 26)
- 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 年从星期四开始,因此 2004 年 ISO 年的第一周从 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()
时间戳获得的精度(例如,这在提供 Cgettimeofday()
函数的平台上可能是可能的)。如果 tz 不为
None
,则它必须是tzinfo
子类的实例,并且当前日期和时间将转换为 tz 的时区。
- classmethod datetime.utcnow()¶
返回当前 UTC 日期和时间,其中
tzinfo
为None
。这类似于
now()
,但返回当前 UTC 日期和时间,作为原始的datetime
对象。可以通过调用datetime.now(timezone.utc)
获取当前 UTC 日期时间的感知对象。另请参阅now()
。警告
因为许多
datetime
方法将原始的datetime
对象视为本地时间,所以最好使用感知日期时间来表示 UTC 时间。因此,建议使用datetime.now(timezone.utc)
来创建表示当前 UTC 时间的对象。自版本 3.12 起弃用: 请改用带有
UTC
的datetime.now()
。
- classmethod datetime.fromtimestamp(timestamp, tz=None)¶
返回与 POSIX 时间戳对应的本地日期和时间,例如
time.time()
返回的时间戳。如果可选参数 tz 为None
或未指定,则时间戳将转换为平台的本地日期和时间,并且返回的datetime
对象是原始的。如果 tz 不为
None
,则它必须是tzinfo
子类的实例,并且时间戳将转换为 tz 的时区。fromtimestamp()
可能会引发OverflowError
(如果时间戳超出平台 Clocaltime()
或gmtime()
函数支持的值范围),并在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
。(结果对象是 naive 的。)如果时间戳超出平台 C
gmtime()
函数支持的值范围,则可能会引发OverflowError
,并在gmtime()
失败时引发OSError
。通常,这被限制在 1970 年到 2038 年之间的年份。要获取 aware
datetime
对象,请调用fromtimestamp()
datetime.fromtimestamp(timestamp, timezone.utc)
在符合 POSIX 标准的平台上,它等效于以下表达式
datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=timestamp)
但后一个公式始终支持完整的年份范围:介于
MINYEAR
和MAXYEAR
之间(含)。警告
因为许多
datetime
方法将 naivedatetime
对象视为本地时间,所以最好使用 aware datetime 来表示 UTC 时间。因此,建议使用datetime.fromtimestamp(timestamp, tz=timezone.utc)
来创建表示 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.isocalendar()
的逆函数。3.8 版新增。
- classmethod datetime.strptime(date_string, format)¶
返回与 date_string 对应的
datetime
,根据 format 进行解析。如果 format 不包含微秒或时区信息,则这等效于
datetime(*(time.strptime(date_string, format)[0:6]))
如果
time.strptime()
无法解析 date_string 和 format,或者它返回的值不是时间元组,则会引发ValueError
。另请参阅 strftime() 和 strptime() 行为 以及datetime.fromisoformat()
。
类属性
实例属性(只读)
- 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
,则向后移动。结果具有与输入日期时间相同的tzinfo
属性,并且之后datetime2 - datetime1 == timedelta
。如果datetime2.year
小于MINYEAR
或大于MAXYEAR
,则会引发OverflowError
。请注意,即使输入是感知时区的对象,也不会进行时区调整。计算
datetime2
使得datetime2 + timedelta == datetime1
。对于加法,结果与输入日期时间具有相同的tzinfo
属性,即使输入是感知的,也不会进行时区调整。仅当两个操作数都是简单的,或者两者都是感知的时,才定义从
datetime
中减去datetime
。如果一个是感知的而另一个是简单的,则会引发TypeError
。如果两者都是简单的,或者两者都是感知的并且具有相同的
tzinfo
属性,则tzinfo
属性将被忽略,结果是一个timedelta
对象 *t*,使得datetime2 + t == datetime1
。在这种情况下,不会进行时区调整。如果两者都是感知的并且具有不同的
tzinfo
属性,则a-b
的行为就像先将 *a* 和 *b* 转换为简单的 UTC 日期时间一样。结果是(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())
,除了实现永远不会溢出。datetime
对象在表示相同的日期和时间(考虑到时区)时相等。简单的和感知的
datetime
对象永远不会相等。datetime
对象永远不会等于不是datetime
实例的date
对象,即使它们表示相同的日期。如果两个比较对象都是感知的,并且具有相同的
tzinfo
属性,则tzinfo
和fold
属性将被忽略,并比较基本日期时间。如果两个比较对象都是感知的并且具有不同的tzinfo
属性,则比较的行为就像先将比较对象转换为 UTC 日期时间一样,除了实现永远不会溢出。重复间隔中的datetime
实例永远不会等于其他时区中的datetime
实例。当 *datetime1* 在时间上早于 *datetime2*(考虑到时区)时,*datetime1* 被认为小于 *datetime2*。
简单的和感知的
datetime
对象之间的顺序比较,以及datetime
对象和不是datetime
实例的date
对象之间的顺序比较,会引发TypeError
。如果两个比较对象都是感知的,并且具有相同的
tzinfo
属性,则tzinfo
和fold
属性将被忽略,并比较基本日期时间。如果两个比较对象都是感知的并且具有不同的tzinfo
属性,则比较的行为就像先将比较对象转换为 UTC 日期时间一样,除了实现永远不会溢出。
实例方法
- datetime.time()¶
返回具有相同小时、分钟、秒、微秒和折叠的
time
对象。tzinfo
为None
。另请参阅方法timetz()
。在 3.6 版更改: 折叠值将复制到返回的
time
对象。
- datetime.timetz()¶
返回具有相同小时、分钟、秒、微秒、折叠和 tzinfo 属性的
time
对象。另请参阅方法time()
。在 3.6 版更改: 折叠值将复制到返回的
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)¶
返回一个日期时间,其属性与之前相同,但指定的任何关键字参数给出的属性除外。请注意,可以指定
tzinfo=None
以从感知日期时间创建简单日期时间,而无需转换日期和时间数据。版本 3.6 中的变化: 添加了 fold 参数。
- datetime.astimezone(tz=None)¶
返回一个具有新的
tzinfo
属性 *tz* 的datetime
对象,调整日期和时间数据,以便结果与 *self* 的 UTC 时间相同,但在 *tz* 的本地时间中。如果提供,则 tz 必须是
tzinfo
子类的实例,并且其utcoffset()
和dst()
方法不能返回None
。如果 self 是 naive 的,则假定它表示系统时区中的时间。如果在没有参数的情况下调用(或使用
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()
相同的日期和时间数据。如果您只想将时区对象 tz 附加到 datetime dt 而不调整日期和时间数据,请使用
dt.replace(tzinfo=tz)
。如果您只想从感知时区的 datetime dt 中删除时区对象而不转换日期和时间数据,请使用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 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。
在 3.6 版更改:
astimezone()
方法现在可以在假定表示系统本地时间的 naive 实例上调用。
- 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 是 naive 的,则这与d.timetuple()
相同,只是tm_isdst
被强制为 0,而不管d.dst()
返回什么。对于 UTC 时间,DST 从未生效。如果 d 是感知时区的,则通过减去
d.utcoffset()
将 d 标准化为 UTC 时间,并返回标准化时间的time.struct_time
。tm_isdst
被强制为 0。请注意,如果d.year
是MINYEAR
或MAXYEAR
并且 UTC 调整溢出一年的边界,则可能会引发OverflowError
。警告
因为 naive 的
datetime
对象被许多datetime
方法视为本地时间,所以最好使用感知时区的 datetime 来表示 UTC 时间;因此,使用datetime.utctimetuple()
可能会产生误导性的结果。如果您有一个表示 UTC 的 naivedatetime
,请使用datetime.replace(tzinfo=timezone.utc)
使其感知时区,此时您可以使用datetime.timetuple()
。
- datetime.toordinal()¶
返回日期的公历序数。与
self.date().toordinal()
相同。
- datetime.timestamp()¶
返回与
datetime
实例相对应的 POSIX 时间戳。返回值是一个float
,类似于time.time()
返回的值。朴素
datetime
实例假定表示本地时间,此方法依赖于平台 Cmktime()
函数来执行转换。由于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
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
或直接计算时间戳来获取 POSIX 时间戳
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 外,所有参数默认为 0,tzinfo 默认为None
。
类属性
实例属性(只读)
- 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
对象之间的顺序比较会引发 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)¶
返回与任何有效 ISO 8601 格式的 time_string 对应的
time
,但以下情况除外时区偏移量可能包含小数秒。
不需要前导
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()
可以发出的格式。
实例方法
- time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)¶
返回一个与之值相同的
time
,但指定的任何关键字参数都会为其属性赋予新值。请注意,可以指定tzinfo=None
以从感知型time
创建简单型time
,而无需转换时间数据。版本 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 的偏移量、时区名称和 DST 偏移量的方法,所有这些方法都与传递给它们的日期或时间对象相关。您需要派生一个具体的子类,并且(至少)提供您使用的
datetime
方法所需的标准tzinfo
方法的实现。datetime
模块提供了timezone
,它是tzinfo
的一个简单具体子类,可以表示与 UTC 具有固定偏移量的时区,例如 UTC 本身或北美东部标准时间和夏令时。对 Pickle 的特殊要求:
tzinfo
子类必须有一个__init__()
方法,该方法可以在不带参数的情况下调用,否则它可以被 Pickle 但可能无法再次 Unpickle。这是一个技术要求,将来可能会放宽。tzinfo
的具体子类可能需要实现以下方法。究竟需要哪些方法取决于对感知datetime
对象的使用。如有疑问,只需全部实现即可。
- tzinfo.utcoffset(dt)¶
以
timedelta
对象的形式返回本地时间与 UTC 的偏移量,该对象在 UTC 以东为正。如果本地时间在 UTC 以西,则应为负。这表示与 UTC 的*总*偏移量;例如,如果
tzinfo
对象同时表示时区和 DST 调整,则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)¶
以
timedelta
对象的形式返回夏令时 (DST) 调整,如果 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
时,由类设计者决定最佳响应。例如,如果类希望表示 time 对象不参与 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 的本地时间返回等效的 datetime。大多数
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 从 3 月第二个星期日凌晨 1:59(EST)之后的分钟开始,到 11 月第一个星期日凌晨 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
当夏令时开始时(“开始”行),本地挂钟时间从 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
当夏令时结束时(“结束”行),存在一个可能更糟糕的问题:有一个小时无法用本地挂钟时间明确表示:夏令时的最后一个小时。在东部时间,这是夏令时结束当天 UTC 时间为 5:MM 的时间。本地挂钟时间从 1:59(夏令时)跳回到 1:00(标准时间)。1:MM 形式的本地时间不明确。astimezone()
通过将两个相邻的 UTC 小时映射到同一个本地小时来模拟本地时钟的行为。在东部时间示例中,UTC 时间形式为 5:MM 和 6:MM 的时间在转换为东部时间时都映射到 1:MM,但较早的时间的 fold
属性设置为 0,而较晚的时间的 fold
属性设置为 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
属性(UTC 时区实例)。
zoneinfo
将 *IANA 时区数据库*(也称为 Olson 数据库)引入 Python,建议使用它。
- IANA 时区数据库
时区数据库(通常称为 tz、tzdata 或 zoneinfo)包含表示全球许多代表性地点的本地时间历史记录的代码和数据。它会定期更新,以反映政治机构对时区边界、UTC 偏移量和夏令时规则所做的更改。
timezone
对象¶
timezone
类是 tzinfo
的子类,它的每个实例都表示由与 UTC 的固定偏移量定义的时区。
此类的对象不能用于表示在一年中不同日期使用不同偏移量或对民用时间进行历史更改的位置中的时区信息。
- class datetime.timezone(offset, name=None)¶
必须将 *offset* 参数指定为表示本地时间和 UTC 之间差异的
timedelta
对象。它必须严格介于-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)
方法,以创建一个在显式格式字符串的控制下表示时间的字符串。
相反,datetime.strptime()
类方法从表示日期和时间的字符串以及相应的格式字符串创建一个 datetime
对象。
下表提供了 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) |
|
时区名称(如果对象是 naive,则为空字符串)。 |
(空)、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(无);
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 对象中单独实现,因此始终可用)。对于 naive 对象,
%z
、%:z
和%Z
格式代码将替换为空字符串。对于 aware 对象
%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 中的变化: 当
%z
指令提供给strptime()
方法时,将生成一个可感知的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
确实需要前导零。
脚注