8.1. datetime-基本日期和时间类型

2.3 版的新Function。

datetime模块提供了用于以简单和复杂方式操纵日期和时间的类。虽然支持日期和时间算术,但实现的重点是针对输出格式和操作的有效属性提取。有关相关Function,另请参见timecalendar模块。

有两种日期和时间对象:“天真”和“意识”。

一个有意识的对象对适用的算法和政治时间调整(例如时区和夏时制时间信息)具有足够的知识,可以相对于其他有意识的对象定位自己。有意识的对象用于表示特定时间,该特定时间对解释[1]不开放。

天真的对象没有足够的信息来明确地相对于其他日期/时间对象定位自己。天真对象是代表协调世界时(UTC),本地时间还是在其他时区中的时间,完全取决于程序,就像特定数字代表米,英里或质量取决于程序一样。天真的对象易于理解和使用,以忽略现实的某些方面为代价。

对于需要感知对象的应用程序,datetimetime对象具有可选的时区信息属性tzinfo,可以将其设置为抽象tzinfo类的子类的实例。这些tzinfo对象捕获有关 UTC 时间的偏移量,时区名称以及夏时制是否有效的信息。请注意,datetime模块未提供任何具体的tzinfo类。支持时区的详细程度取决于应用程序。Global 范围内的时间调整规则更具政治性,而不是理性性,并且没有适用于每种应用程序的标准。

datetime模块导出以下常量:

See also

  • Module calendar

  • 常规 calendar 相关Function。

  • Module time

  • 时间访问和转换。

8.1.1. 可用类型

  • datetime. date

    • 假设当前公历始终有效,并且是永远有效,那么这是一个理想的天真日期。属性:yearmonthday
  • datetime. time

    • 一个理想的时间,独立于任何特定的一天,假设每天正好有 24 * 60 * 60 秒(此处没有“ le 秒”的概念)。属性:hourminutesecondmicrosecondtzinfo
  • datetime. datetime

  • datetime. timedelta

    • 表示两个datetimedatetime实例之间的差异的持续时间,以微秒为单位。
  • datetime. tzinfo

    • 时区信息对象的抽象 Base Class。 datetimetime类使用它们来提供可自定义的时间调整概念(例如,考虑时区和/或夏时制)。

这些类型的对象是不可变的。

date类型的对象总是幼稚的。

类型timedatetime的对象可能是幼稚的或感知的。 datetime对象* d 知道d.tzinfo不是None并且d.tzinfo.utcoffset(d)不返回None。如果d.tzinfoNone,或者d.tzinfo不是None而是d.tzinfo.utcoffset(d)返回None,则 d 是幼稚的。 time对象 t 知道t.tzinfo不是None并且t.tzinfo.utcoffset(None)不返回None。否则, t *是幼稚的。

天真和有意识之间的区别不适用于timedelta个对象。

Subclass relationships:

object
    timedelta
    tzinfo
    time
    date
        datetime

8.1.2. timedelta 对象

timedelta对象代表持续时间,即两个日期或时间之间的差。

    • class * datetime. timedelta([ [, [,微秒 [,毫秒 [,分钟 [,小时 [,]]]]]]]]]))
    • 所有参数都是可选的,默认为0。参数可以是整数,多头或浮点数,并且可以是正数或负数。

内部仅存储* day seconds microseconds *。参数将转换为以下单位:

  • 毫秒转换为 1000 微秒。

  • 一分钟转换为 60 秒。

  • 一个小时转换为 3600 秒。

  • 一周转换为 7 天。

然后将天,秒和微秒标准化,以使表示形式唯一

  • 0 <= microseconds < 1000000

  • 0 <= seconds < 3600*24(一天中的秒数)

  • -999999999 <= days <= 999999999

如果任何自变量是浮点型并且有分数微秒,则将从所有自变量剩余的分数微秒进行合并,并且它们的和将四舍五入到最接近的微秒。如果没有参数是浮点数,则转换和规范化过程是精确的(不会丢失任何信息)。

如果天的归一化值超出指定的范围,则将引发OverflowError

请注意,负值的标准化一开始可能令人惊讶。例如,

>>> from datetime import timedelta
>>> d = timedelta(microseconds=-1)
>>> (d.days, d.seconds, d.microseconds)
(-1, 86399, 999999)

类属性是:

  • timedelta. min

    • 最否定的timedelta对象timedelta(-999999999)
  • timedelta. max

    • 最积极的timedelta对象timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999)
  • timedelta. resolution

    • 不相等的timedelta个对象timedelta(microseconds=1)之间的最小可能差异。

请注意,由于标准化,timedelta.max> -timedelta.min-timedelta.max不能表示为timedelta对象。

实例属性(只读):

AttributeValue
days-999999999 至 999999999(含)之间
seconds0 至 86399(含)之间
microseconds0 至 999999(含)之间

Supported operations:

OperationResult
t1 = t2 + t3* t2 t3 的总和。之后 t1 - t2 * == * t3 t1 - t3 * == * t2 *为真。 (1)
t1 = t2 - t3* t2 t3 的差。之后 t1 * == * t2 - t3 t2 * == * t1 * * t3 *为真。 (1)
t1 = t2 * i or t1 = i * t2Delta 乘以整数或 long。之后,* t1 * // i == * t2 *为 true,前提是i != 0
通常,* t1 * * i == * t1 * (i-1) t1 *为 true。 (1)
t1 = t2 // i计算底数,其余部分(如果有)被丢弃。 (3)
+t1返回具有相同值的timedelta对象。 (2)
-t1等效于timedelta(-* t1.days ,- t1.seconds ,- t1.microseconds )和 t1 * * -1. (1)(4)
abs(t)等效于t.days >= 0时的* t ,以及t.days < 0时的- t *。 (2)
str(t)返回格式为[D day[s], ][H]H:MM:SS[.UUUUUU]的字符串,其中 D 表示负数t的负数。 (5)
repr(t)返回格式为datetime.timedelta(D[, S[, U]])的字符串,其中 D 表示负数t的负数。 (5)

Notes:

  • 这是正确的,但可能会溢出。

  • 这是正确的,并且不会溢出。

  • 除以 0 会引发ZeroDivisionError

  • -* timedelta.max *无法表示为timedelta对象。

  • timedelta对象的字符串表示形式类似于其内部表示形式被规范化。对于负时间增量,这会导致一些不寻常的结果。例如:

>>> timedelta(hours=-5)
datetime.timedelta(-1, 68400)
>>> print(_)
-1 day, 19:00:00

除了上面列出的操作外,timedelta对象还支持对datedatetime对象进行某些加法和减法(请参见下文)。

支持timedelta对象的比较,而timedelta对象则代表较小的持续时间,该较小的持续时间被认为是较小的时间增量。为了阻止混合类型比较回退到按对象地址进行的默认比较,将timedelta对象与不同类型的对象进行比较时,除非比较是==!=,否则将引发TypeError。后一种情况分别返回FalseTrue

timedelta对象是hashable(可用作字典键),支持有效的 Pickling,并且在布尔上下文中,当且仅当timedelta不等于timedelta(0)时,才认为timedelta对象为 true。

Instance methods:

  • timedelta. total_seconds ( )
    • 返回持续时间中包含的总秒数。等效于启用了真除法计算的(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6

请注意,对于非常长的时间间隔(在大多数平台上大于 270 年),此方法将失去微秒的精度。

2.7 版的新Function。

Example usage:

>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
...                          minutes=50, seconds=600)  # adds up to 365 days
>>> year.total_seconds()
31536000.0
>>> year == another_year
True
>>> ten_years = 10 * year
>>> ten_years, ten_years.days // 365
(datetime.timedelta(3650), 10)
>>> nine_years = ten_years - year
>>> nine_years, nine_years.days // 365
(datetime.timedelta(3285), 9)
>>> three_years = nine_years // 3;
>>> three_years, three_years.days // 365
(datetime.timedelta(1095), 3)
>>> abs(three_years - ten_years) == 2 * three_years + year
True

8.1.3. 日期对象

date对象代表理想 calendar 中的日期(年,月和日),当前公历 calendar 在两个方向上无限期扩展。第 1 年的 1 月 1 日称为第 1 天,第 1 年的 1 月 2 日称为第 2 天,依此类推。这与 Dershowitz 和 Reingold 的《calendar 计算》一书中“多用格里高利历”calendar 的定义相匹配,它是所有计算的基础 calendar。请参阅本书,以了解在公历和其他 calendar 系统之间进行转换的算法。

  • 类别 datetime. date()

    • 所有参数都是必需的。参数可以是整数或多头,范围在以下范围内:
  • MINYEAR <= year <= MAXYEAR

  • 1 <= month <= 12

  • 1 <= day <= number of days in the given month and year

如果给出了超出这些范围的参数,则引发ValueError

其他构造函数,所有类方法:

  • 分类方法 date. today()

    • 返回当前的本地日期。这等效于date.fromtimestamp(time.time())
  • 类方法 date. fromtimestamp(时间戳)

    • 返回与 POSIX 时间戳相对应的本地日期,例如time.time()返回的日期。如果时间戳不在平台 C localtime()函数支持的值范围内,则可能会引发ValueError。通常将其限制为从 1970 年到 2038 年的几年。请注意,在非 POSIX 系统上,在时间戳概念中包含 leap 秒的情况下,fromtimestamp()会忽略 leap 秒。
  • 类方法 date. fromordinal(常规)

    • 返回对应于多格勒公历序号的日期,其中第一年的 1 月 1 日具有序数 1.除非1 <= ordinal <= date.max.toordinal(),否则将引发ValueError。对于任何日期* d *,date.fromordinal(d.toordinal()) == d

Class attributes:

  • date. min

    • 最早的可表示日期date(MINYEAR, 1, 1)
  • date. max

    • 最近的可表示日期date(MAXYEAR, 12, 31)
  • date. resolution

    • 非相等日期对象timedelta(days=1)之间的最小可能差异。

实例属性(只读):

  • date. year

  • date. month

    • 在 1 到 12 之间(含 1 和 12)。
  • date. day

    • 在 1 和给定年份的给定月份中的天数之间。

Supported operations:

OperationResult
date2 = date1 + timedelta* date2 已从 date1 *中删除timedelta.days天。 (1)
date2 = date1 - timedelta计算* date2 *这样的date2 + timedelta == date1。 (2)
timedelta = date1 - date2(3)
date1 < date2如果* date1 在时间上早于 date2 ,则 date1 被认为小于 date2 *。 (4)

Notes:

  • 如果timedelta.days > 0,则* date2 *将在时间上向前移动,如果timedelta.days < 0,则将在时间上向后移动。之后date2 - date1 == timedelta.daystimedelta.secondstimedelta.microseconds被忽略。如果date2.year小于MINYEAR或大于MAXYEAR,则引发OverflowError

  • 这不太等同于 date1(-timedelta),因为在 date1-timedelta 不存在的情况下,-timedelta 孤立地会溢出。 timedelta.secondstimedelta.microseconds被忽略。

  • 这是正确的,并且不会溢出。 timedelta.seconds 和 timedelta.microseconds 为 0,date2 timedelta == date1 之后。

  • 换句话说,当且仅当date1.toordinal() < date2.toordinal()时为date1 < date2。为了阻止比较返回到比较对象地址的默认方案,如果另一个比较符也不是date对象,则日期比较通常会提高TypeError。但是,如果另一个比较符具有timetuple()属性,则返回NotImplemented。该钩子为其他日期对象提供了实现混合类型比较的机会。如果不是,则将date对象与不同类型的对象进行比较时,除非比较是==!=,否则将引发TypeError。后一种情况分别返回FalseTrue

日期可以用作字典键。在布尔上下文中,所有date对象都被视为正确。

Instance methods:

  • date. replace()

    • 返回具有相同值的日期,但那些pass指定关键字参数给定新值的参数除外。例如,如果d == date(2002, 12, 31),则d.replace(day=26) == 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 ( )

    • 返回一个三 Tuples(ISO 年,ISO 周号,ISO 工作日)。

ISOcalendar 是公历的一种广泛使用的变体。有关详细说明,请参见https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm

ISO 年度包括 52 或 53 个整周,其中一个星期从星期一开始,在星期日结束。 ISO 年的第一周是包含星期四的一年中的第一个(格里高利历)calendar 周。这称为第 1 周,该周四的 ISO 年与其公历年相同。

例如,2004 年在星期四开始,因此 ISO 2004 年的第一周从 2003 年 12 月 29 日星期一开始,到 2004 年 1 月 4 日星期日结束,因此date(2003, 12, 29).isocalendar() == (2004, 1, 1)date(2004, 1, 4).isocalendar() == (2004, 1, 7)

  • date. isoformat ( )

    • 以 ISO 8601 格式返回表示日期的字符串'YYYY-MM-DD'。例如date(2002, 12, 4).isoformat() == '2002-12-04'
  • date. __str__ ( )

    • 对于日期* d *,str(d)等效于d.isoformat()
  • date. ctime ( )

    • 返回表示日期的字符串,例如date(2002, 12, 4).ctime() == 'Wed Dec 4 00:00:00 2002'。在本机 C ctime()函数(time.ctime()调用但date.ctime()不调用)符合 C 标准的平台上,d.ctime()等效于time.ctime(time.mktime(d.timetuple()))
  • date. strftime(* format *)

    • 返回表示日期的字符串,由明确的格式字符串控制。表示小时,分钟或秒的格式代码将显示 0 个值。有关格式设置指令的完整列表,请参见strftime()和 strptime()行为部分。
  • date. __format__(* format *)

计算事件天数的示例:

>>> import time
>>> from datetime import date
>>> today = date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == date.fromtimestamp(time.time())
True
>>> my_birthday = date(today.year, 6, 24)
>>> if my_birthday < today:
...     my_birthday = my_birthday.replace(year=today.year + 1)
>>> my_birthday
datetime.date(2008, 6, 24)
>>> time_to_birthday = abs(my_birthday - today)
>>> time_to_birthday.days
202

使用date的示例:

>>> from datetime import date
>>> d = date.fromordinal(730920) # 730920th day after 1. 1. 0001
>>> d
datetime.date(2002, 3, 11)
>>> t = d.timetuple()
>>> for i in t:     
...     print i
2002                # year
3                   # month
11                  # day
0
0
0
0                   # weekday (0 = Monday)
70                  # 70th day in the year
-1
>>> ic = d.isocalendar()
>>> for i in ic:    
...     print i
2002                # ISO year
11                  # ISO week number
1                   # ISO day number ( 1 = Monday )
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
'The day is 11, the month is March.'

8.1.4. 日期时间对象

datetime对象是包含来自date对象和time对象的所有信息的单个对象。像date对象一样,datetime假定当前的公历沿两个方向延伸。像时间对象一样,datetime假设每天恰好有 3600 * 24 秒。

Constructor:

    • class * datetime. datetime(* year month day * [,* hour * [,* minute * [,* second * [,* microsecond * [,* tzinfo *]]]]]]))
    • 必须 Importing 年,月和日。 * tzinfo *可以是None,或者是tzinfo子类的实例。其余参数可以是整数或长整数,范围如下:
  • MINYEAR <= year <= MAXYEAR

  • 1 <= month <= 12

  • 1 <= day <= number of days in the given month and year

  • 0 <= hour < 24

  • 0 <= minute < 60

  • 0 <= second < 60

  • 0 <= microsecond < 1000000

如果给出了超出这些范围的参数,则引发ValueError

其他构造函数,所有类方法:

  • 分类方法 datetime. today()

    • 返回当前的本地日期时间,为tzinfo None。这等效于datetime.fromtimestamp(time.time())。另请参见now()fromtimestamp()
  • 分类方法 datetime. now([* tz *])

    • 返回当前的本地日期和时间。如果可选参数* tz *为None或未指定,则类似于today(),但是,如果可能的话,它提供的精度比passtime.time()时间戳获得的精度更高(例如,在提供 C gettimeofday()函数的平台上可以实现这种精度) )。

如果* tz 不是None,则它必须是tzinfo子类的实例,并且当前日期和时间将转换为 tz *的时区。在这种情况下,结果等于tz.fromutc(datetime.utcnow().replace(tzinfo=tz))。另请参见today()utcnow()

  • 分类方法 datetime. utcnow()

    • 返回当前的 UTC 日期和时间,使用tzinfo None。类似于now(),但返回当前的 UTC 日期和时间(作为天真datetime对象)。另请参见now()
    • classmethod * datetime. fromtimestamp(* timestamp * [,* tz *])
    • 返回与 POSIX 时间戳相对应的本地日期和时间,例如time.time()返回的日期和时间。如果可选参数* tz *为None或未指定,则时间戳将转换为平台的本地日期和时间,并且返回的datetime对象是天真的。

如果* tz 不是None,则它必须是tzinfo子类的实例,并且时间戳将转换为 tz *的时区。在这种情况下,结果等于tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))

如果时间戳不在平台 C localtime()gmtime()函数支持的值范围内,则fromtimestamp()可能会引发ValueError。通常将其限制在 1970 年到 2038 年之间。请注意,在非 POSIX 系统中,在时间戳概念中包含 leap 秒的情况下,fromtimestamp()会忽略 leap 秒,然后可能会有两个时间戳之间的差异第二个产生相同的datetime对象。另请参见utcfromtimestamp()

  • 类方法 datetime. utcfromtimestamp(时间戳)

    • tzinfo None返回与 POSIX 时间戳相对应的 UTC datetime。如果时间戳超出平台 C gmtime()函数支持的值范围,则可能会提高ValueError。通常将其限制在 1970 年到 2038 年之间。另请参见fromtimestamp()
  • 类方法 datetime. fromordinal(常规)

    • 返回对应于多头格列高利序数的datetime,其中第一年的 1 月 1 日具有序数 1.除非1 <= ordinal <= datetime.max.toordinal(),否则将引发ValueError。结果的小时,分钟,秒和微秒均为 0,tzinfoNone
  • 类方法 datetime. combine(日期时间)

    • 返回一个新的datetime对象,该对象的日期分量等于给定的date对象,并且其时间分量和tzinfo属性等于给定的time对象。对于任何datetime对象* d *,d == datetime.combine(d.date(), d.timetz())。如果 date 是datetime对象,则将忽略其时间成分和tzinfo属性。
    • classmethod * datetime. strptime(* date_string format *)
    • 返回与* date_string 对应的datetime,并根据 format *进行解析。这等效于datetime(*(time.strptime(date_string, format)[0:6]))。如果time.strptime()无法解析 date_string 和格式,或者返回的值不是时间 Tuples,则引发ValueError。有关格式设置指令的完整列表,请参见strftime()和 strptime()行为部分。

2.5 版的新Function。

Class attributes:

  • datetime. min

    • 最早可表示的datetimedatetime(MINYEAR, 1, 1, tzinfo=None)
  • datetime. max

    • 最新的可表示的datetimedatetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None)
  • datetime. resolution

    • 不相等的datetime个对象timedelta(microseconds=1)之间的最小可能差异。

实例属性(只读):

  • datetime. year

  • datetime. month

    • 在 1 到 12 之间(含 1 和 12)。
  • datetime. day

    • 在 1 和给定年份的给定月份中的天数之间。
  • datetime. hour

    • range(24)中。
  • datetime. minute

    • range(60)中。
  • datetime. second

    • range(60)中。
  • datetime. microsecond

    • range(1000000)中。
  • datetime. tzinfo

    • 该对象作为* tzinfo *参数传递给datetime构造函数,或者None(如果没有传递)。

Supported operations:

OperationResult
datetime2 = datetime1 + timedelta(1)
datetime2 = datetime1 - timedelta(2)
timedelta = datetime1 - datetime2(3)
datetime1 < datetime2比较datetimedatetime。 (4)
  • datetime2 是从 datetime1 删除的 timedelta 的持续时间;如果timedelta.days> 0,则时间向前移动;如果timedelta.days <0,则时间向后移动。结果具有与 Importingdatetime 相同的tzinfo属性,datetime2-datetime1 ==之后的 timedelta。如果 datetime2.year 小于MINYEAR或大于MAXYEAR,则引发OverflowError。请注意,即使 Importing 是感知对象,也不会进行时区调整。

  • 计算 datetime2,以使 datetime2 timedelta == datetime1.至于加法,结果具有与 Importing 日期时间相同的tzinfo属性,即使 Importing 知道,也不会进行时区调整。这并不完全等同于 datetime1(-timedelta),因为孤立的-timedelta 在 datetime1-timedelta 不存在的情况下可能会溢出。

  • 仅当两个操作数都是天真或两个都知道时,才定义从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()),除了实现永不溢出。

  • 当* datetime1 在时间上早于 datetime2 时, datetime1 被认为小于 datetime2 *。

如果一个比较项是幼稚的而另一个比较项知道的,则将引发TypeError。如果两个比较符都知道并且具有相同的tzinfo属性,则将忽略公共tzinfo属性,并比较基本日期时间。如果两个比较器都知道并且具有不同的tzinfo属性,则首先pass减去其 UTC 偏移量(从self.utcoffset()获得)来调整比较器。

Note

为了防止比较结果退回到默认的比较对象地址的方案,如果另一个比较符也不是datetime对象,则日期时间比较通常会提高TypeError。但是,如果另一个比较符具有timetuple()属性,则返回NotImplemented。该钩子为其他日期对象提供了实现混合类型比较的机会。如果不是,则将datetime对象与不同类型的对象进行比较时,除非比较是==!=,否则将引发TypeError。后一种情况分别返回FalseTrue

datetime对象可用作字典键。在布尔上下文中,所有datetime对象都被认为是正确的。

Instance methods:

  • datetime. date ( )

    • 返回具有相同年份,月份和日期的date对象。
  • datetime. time ( )

    • 返回具有相同时,分,秒和微秒的time对象。 tzinfoNone。另请参见方法timetz()
  • datetime. timetz ( )

    • 返回具有相同时,分,秒,微秒和 tzinfo 属性的time对象。另请参见方法time()
  • datetime. replace([[* year * [,* month * [,* day * [,* hour * [,分钟 [,* second * [,* microsecond * [,* tzinfo *]]]]]]] []] )

    • 返回具有相同属性的日期时间,除了那些pass指定关键字参数给定新值的属性。请注意,可以指定tzinfo=None来从已知日期时间创建原始日期时间,而不进行日期和时间数据的转换。
  • datetime. astimezone(* tz *)

    • 返回一个具有新tzinfo属性* tz datetime对象,调整日期和时间数据,使结果与 self 相同,并且以 tz *的本地时间为 UTC 时间。
  • tz *必须是tzinfo子类的实例,并且其utcoffset()dst()方法不得返回None。 * self *必须知道(self.tzinfo不能为None,并且self.utcoffset()不能返回None)。

如果self.tzinfo是* tz ,则self.astimezone(tz)等于 self :不执行日期或时间数据的调整。其他结果是时区 tz 中的本地时间,表示与 self 相同的 UTC 时间:在astz = dt.astimezone(tz)之后,astz - astz.utcoffset()通常具有与dt - dt.utcoffset()相同的日期和时间数据。 tzinfo类的讨论解释了夏令时过渡边界上无法实现的情况(仅当 tz *同时模拟标准时间和夏令时时才出现此问题)。

如果只想将时区对象* tz 附加到日期时间 dt 而不调整日期和时间数据,请使用dt.replace(tzinfo=tz)。如果您只想从已知的日期时间 dt *中删除时区对象而不转换日期和时间数据,请使用dt.replace(tzinfo=None)

请注意,可以在tzinfo子类中覆盖默认的tzinfo.fromutc()方法,以影响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)
  • datetime. utcoffset ( )

    • 如果tzinfoNone,则返回None,否则返回self.tzinfo.utcoffset(self),如果后者不返回None或表示整个分钟数小于一天的timedelta对象,则引发异常。
  • datetime. dst ( )

    • 如果tzinfoNone,则返回None,否则返回self.tzinfo.dst(self),如果后者不返回None或表示整个分钟数小于一天的timedelta对象,则引发异常。
  • datetime. tzname ( )

    • 如果tzinfoNone,则返回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开始。根据dst()方法设置结果的tm_isdst标志:tzinfoNonedst()返回Nonetm_isdst设置为-1;否则,如果dst()返回非零值,则将tm_isdst设置为1;否则tm_isdst设置为0
  • datetime. utctimetuple ( )

    • 如果datetime实例* d *天真,则与d.timetuple()相同,除了d.dst()返回什么而将tm_isdst强制为 0. DST 永远不会在 UTC 时间生效。

如果* d 知道,则pass减去d.utcoffset() d 标准化为 UTC 时间,并返回标准化时间的time.struct_timetm_isdst强制为 0.请注意,如果 d * .year 是MINYEARMAXYEAR并且 UTC 调整超出年份边界,则结果的tm_year成员可能是MINYEAR -1 或MAXYEAR1.

  • datetime. toordinal ( )

    • 返回日期的公历序数。与self.date().toordinal()相同。
  • datetime. weekday ( )

    • 以整数形式返回星期几,其中 Monday 为 0,Sunday 为 6.与self.date().weekday()相同。另请参见isoweekday()
  • datetime. isoweekday ( )

    • 以整数形式返回星期几,其中 Monday 是 1,Sunday 是 7.与self.date().isoweekday()相同。另请参见weekday()isocalendar()
  • datetime. isocalendar ( )

    • 返回一个三 Tuples(ISO 年,ISO 周号,ISO 工作日)。与self.date().isocalendar()相同。
  • datetime. isoformat([* sep *])

    • 以 ISO 8601 格式返回表示日期和时间的字符串,即 YYYY-MM-DDTHH:MM:SS.mmmmmm;如果microsecond为 0,则返回 YYYY-MM-DDTHH:MM:SS

如果utcoffset()不返回None,则会附加一个 6 个字符的字符串,并以(带符号的)小时和分钟表示 UTC 偏移量:YYYY-MM-DDTHH:MM:SS.mmmmmm HH:MM;或者,如果microsecond为 0 YYYY-MM -DDTHH:MM:SS HH:MM

可选参数* sep *(默认为'T')是一个单字符分隔符,位于结果的日期和时间部分之间。例如,

>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
...     def utcoffset(self, dt): return timedelta(minutes=-399)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
  • datetime. __str__ ( )

    • 对于datetime实例* d *,str(d)等效于d.isoformat(' ')
  • datetime. ctime ( )

    • 返回表示日期和时间的字符串,例如datetime(2002, 12, 4, 20, 30, 40).ctime() == 'Wed Dec 4 20:30:40 2002'。在本机 C ctime()函数(time.ctime()调用但datetime.ctime()不调用)符合 C 标准的平台上,d.ctime()等效于time.ctime(time.mktime(d.timetuple()))
  • datetime. strftime(* format *)

    • 返回表示日期和时间的字符串,由明确的格式字符串控制。有关格式设置指令的完整列表,请参见strftime()和 strptime()行为部分。
  • datetime. __format__(* format *)

使用日期时间对象的示例:

>>> from datetime import datetime, date, time
>>> # Using datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)
>>> # Using datetime.now() or datetime.utcnow()
>>> datetime.now()   
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043)   # GMT +1
>>> datetime.utcnow()   
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060)
>>> # Using datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)
>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = dt.timetuple()
>>> for it in tt:   
...     print it
...
2006    # year
11      # month
21      # day
16      # hour
30      # minute
0       # second
1       # weekday (0 = Monday)
325     # number of days since 1st January
-1      # dst - method tzinfo.dst() returned None
>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> for it in ic:   
...     print it
...
2006    # ISO year
47      # ISO week
2       # ISO weekday
>>> # Formatting datetime
>>> dt.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(dt, "day", "month", "time")
'The day is 21, the month is November, the time is 04:30PM.'

在 tzinfo 中使用 datetime:

>>> from datetime import timedelta, datetime, tzinfo
>>> class GMT1(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=1) + self.dst(dt)
...     def dst(self, dt):
...         # DST starts last Sunday in March
...         d = datetime(dt.year, 4, 1)   # ends last Sunday in October
...         self.dston = d - timedelta(days=d.weekday() + 1)
...         d = datetime(dt.year, 11, 1)
...         self.dstoff = d - timedelta(days=d.weekday() + 1)
...         if self.dston <=  dt.replace(tzinfo=None) < self.dstoff:
...             return timedelta(hours=1)
...         else:
...             return timedelta(0)
...     def tzname(self,dt):
...          return "GMT +1"
...
>>> class GMT2(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=2) + self.dst(dt)
...     def dst(self, dt):
...         d = datetime(dt.year, 4, 1)
...         self.dston = d - timedelta(days=d.weekday() + 1)
...         d = datetime(dt.year, 11, 1)
...         self.dstoff = d - timedelta(days=d.weekday() + 1)
...         if self.dston <=  dt.replace(tzinfo=None) < self.dstoff:
...             return timedelta(hours=1)
...         else:
...             return timedelta(0)
...     def tzname(self,dt):
...         return "GMT +2"
...
>>> gmt1 = GMT1()
>>> # Daylight Saving Time
>>> dt1 = datetime(2006, 11, 21, 16, 30, tzinfo=gmt1)
>>> dt1.dst()
datetime.timedelta(0)
>>> dt1.utcoffset()
datetime.timedelta(0, 3600)
>>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=gmt1)
>>> dt2.dst()
datetime.timedelta(0, 3600)
>>> dt2.utcoffset()
datetime.timedelta(0, 7200)
>>> # Convert datetime to another time zone
>>> dt3 = dt2.astimezone(GMT2())
>>> dt3     
datetime.datetime(2006, 6, 14, 14, 0, tzinfo=<GMT2 object at 0x...>)
>>> dt2     
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=<GMT1 object at 0x...>)
>>> dt2.utctimetuple() == dt3.utctimetuple()
True

8.1.5. 时间对象

时间对象表示一天中的(本地)时间,与任何特定的日期无关,并且可以passtzinfo对象进行调整。

    • class * datetime. time([小时 [,分钟 [, [,微秒 [,* tzinfo *]]]]])
    • 所有参数都是可选的。 * tzinfo *可以是None,或者是tzinfo子类的实例。其余参数可以是整数或长整数,范围如下:
  • 0 <= hour < 24

  • 0 <= minute < 60

  • 0 <= second < 60

  • 0 <= microsecond < 1000000 .

如果给出了超出这些范围的参数,则引发ValueError。除* tzinfo *(默认为None)外,其他所有默认值为0

Class attributes:

  • time. min

    • 最早可表示的timetime(0, 0, 0, 0)
  • time. max

    • 最新的可表示的timetime(23, 59, 59, 999999)
  • time. resolution

    • 不相等的time对象timedelta(microseconds=1)之间的最小可能差异,但请注意,不支持对time对象进行算术运算。

实例属性(只读):

  • time. hour

    • range(24)中。
  • time. minute

    • range(60)中。
  • time. second

    • range(60)中。
  • time. microsecond

    • range(1000000)中。
  • time. tzinfo

    • 作为 tzinfo 参数传递给time构造函数的对象,如果未传递则返回None

Supported operations:

  • timetime的比较,其中* a 在时间上优先于 b 时, a 被认为小于 b *。如果一个比较项是幼稚的,而另一个比较项是知道的,则将引发TypeError。如果两个比较符都知道并且具有相同的tzinfo属性,则将忽略公共tzinfo属性,并比较基准时间。如果两个比较器都知道并且具有不同的tzinfo属性,则首先pass减去其 UTC 偏移量(从self.utcoffset()获得)来调整比较器。为了阻止混合类型比较回退到按对象地址进行的默认比较,将time对象与其他类型的对象进行比较时,除非比较是==!=,否则将引发TypeError。后一种情况分别返回FalseTrue

  • 哈希,用作字典键

  • efficient pickling

  • 在布尔上下文中,当且仅当将其转换为分钟并减去utcoffset()(或0,如果是None)后结果为非零时,才将time对象视为真。

Instance methods:

  • time. replace([小时 [,分钟 [, [,微秒 [,* tzinfo *]]]]])

    • 返回一个具有相同值的time,除了那些由指定的关键字参数赋予新值的属性。请注意,可以指定tzinfo=None以从有意识的time创建天真的time,而无需转换时间数据。
  • time. isoformat ( )

    • 以 ISO 8601 格式返回表示时间的字符串,即 HH:MM:SS.mmmmmm;如果 self.microsecond 为 0,则返回 HH:MM:SS 如果utcoffset()不返回None,则会附加一个 6 个字符的字符串,并指定 UTC 以(带符号)小时和分钟为单位的偏移量:HH:MM:SS.mmmmmm HH:MM;如果 self.microsecond 为 0,则为 HH:MM:SS HH:MM
  • time. __str__ ( )

    • 在时间* t *中,str(t)等于t.isoformat()
  • time. strftime(* format *)

    • 返回表示时间的字符串,由明确的格式字符串控制。有关格式设置指令的完整列表,请参见strftime()和 strptime()行为部分。
  • time. __format__(* format *)

  • time. utcoffset ( )

    • 如果tzinfoNone,则返回None,否则返回self.tzinfo.utcoffset(None),如果后者不返回None或表示小于一整天的整数分钟的timedelta对象,则引发异常。
  • time. dst ( )

    • 如果tzinfoNone,则返回None,否则返回self.tzinfo.dst(None),如果后者不返回None或表示整个分钟数小于一天的timedelta对象,则引发异常。
  • time. tzname ( )

    • 如果tzinfoNone,则返回None,否则返回self.tzinfo.tzname(None),如果后者不返回None或字符串对象,则引发异常。

Example:

>>> from datetime import time, tzinfo, timedelta
>>> class GMT1(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=1)
...     def dst(self, dt):
...         return timedelta(0)
...     def tzname(self,dt):
...         return "Europe/Prague"
...
>>> t = time(12, 10, 30, tzinfo=GMT1())
>>> t                               
datetime.time(12, 10, 30, tzinfo=<GMT1 object at 0x...>)
>>> gmt = GMT1()
>>> t.isoformat()
'12:10:30+01:00'
>>> t.dst()
datetime.timedelta(0)
>>> t.tzname()
'Europe/Prague'
>>> t.strftime("%H:%M:%S %Z")
'12:10:30 Europe/Prague'
>>> 'The {} is {:%H:%M}.'.format("time", t)
'The time is 12:10.'

8.1.6. tzinfo 对象

  • 类别 datetime. tzinfo
    • 这是一个抽象 Base Class,意味着该类不应直接实例化。您需要派生一个具体的子类,并且(至少)提供所使用的datetime方法所需的标准tzinfo方法的实现。 datetime模块不提供tzinfo的任何具体子类。

tzinfo的实例(具体子类)可以传递给datetimetime对象的构造函数。后者的对象将其属性视为本地时间,而tzinfo对象则支持显示相对于传递给它们的日期或时间对象而言,相对于 UTC 的本地时间偏移,时区名称和 DST 偏移的方法。

腌制的特殊要求:tzinfo子类必须具有init()方法,可以不带任何参数调用该方法,否则可以对其进行腌制,但可能无法再次对其进行腌制。这是一项技术要求,将来可能会放宽。

tzinfo的具体子类可能需要实现以下方法。究竟需要哪种方法取决于对已知的datetime对象的使用。如有疑问,只需实施所有这些。

  • tzinfo. utcoffset(* self dt *)
    • 从 UTC 返回本地时间的偏移量,以 UTC 以东的分钟数为单位。如果当地时间在 UTC 西部,则应该为负。注意,这是与 UTC 的总偏移量;例如,如果tzinfo对象代表时区和夏令时调整,则utcoffset()应返回其总和。如果不知道 UTC 偏移量,则返回None。否则,返回的值必须是一个timedelta对象,该整数指定-1439 至 1439 之间的整数分钟数(包括 1440 = 24 * 60;偏移量的大小必须小于一天)。 utcoffset()的大多数实现可能看起来像这两个之一:
return CONSTANT                 # fixed-offset class
return CONSTANT + self.dst(dt)  # daylight-aware class

如果utcoffset()不返回None,则dst()也不应返回None

默认实现utcoffset()引发NotImplementedError

  • tzinfo. dst(* self dt *)
    • 返回夏令时(DST)调整,以 UTC 以东的分钟数表示,如果未知 DST 信息,则返回None。如果 DST 无效,则返回timedelta(0)。如果 DST 有效,则将偏移量作为timedelta对象返回(有关详细信息,请参见utcoffset())。请注意,DST 偏移(如果适用)已经添加到utcoffset()返回的 UTC 偏移中,因此除非您有兴趣单独获取 DST 信息,否则无需咨询dst()。例如,datetime.timetuple()调用其tzinfo属性的dst()方法来确定应如何设置tm_isdst标志,并且tzinfo.fromutc()调用dst()以解决跨时区的 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)

or

def dst(self, dt):
    # Code to set dston and dstoff to the time zone's DST
    # transition times based on the input dt.year, and expressed
    # in standard local time.  Then

    if dston <= dt.replace(tzinfo=None) < dstoff:
        return timedelta(hours=1)
    else:
        return timedelta(0)

默认实现dst()引发NotImplementedError

  • tzinfo. tzname(* self dt *)
    • 以字符串形式返回与datetime对象* dt 对应的时区名称。 datetime模块未定义任何有关字符串名称的内容,也没有要求其特别含义。例如,“ GMT”,“ UTC”,“-500”,“-5:00”,“ EDT”,“ US/Eastern”,“ America/New York”都是有效的回复。如果字符串名称未知,则返回None。请注意,这是一个方法,而不是固定的字符串,主要是因为某些tzinfo子类希望根据传递的 dt *的特定值返回不同的名称,尤其是在tzinfo类考虑了日光时间的情况下。

默认实现tzname()引发NotImplementedError

响应它们的相同名称的方法,这些方法由datetimetime对象调用。 datetime对象将自身作为参数传递,而time对象将None作为参数传递。因此,应准备tzinfo子类的方法以接受None或类datetime的* dt *参数。

传递None时,由类设计者决定最佳响应。例如,如果类希望说时间对象不参与tzinfo协议,则返回None是适当的。 utcoffset(None)返回标准 UTC 偏移量可能更有用,因为没有其他约定可以发现标准偏移量。

当响应datetime对象而传递datetime对象时,dt.tzinfo与* self 是同Pair象。 tzinfo方法可以依赖于此,除非用户代码直接调用tzinfo方法。目的是tzinfo方法将 dt *解释为本地时间,而不必担心其他时区的对象。

子类可能希望重写另一个tzinfo方法:

  • tzinfo. fromutc(* self dt *)
    • 这是从默认的datetime.astimezone()实现中调用的。从中调用dt.tzinfo是* self ,并且 dt 的日期和时间数据将被视为表示 UTC 时间。 fromutc()的目的是调整日期和时间数据,并以 self *的本地时间返回等效的 datetime。

大多数tzinfo子类应该能够继承默认的fromutc()实现,而不会出现问题。它具有足够的能力来处理固定偏移的时区,并且时区同时考虑了标准时间和夏令时,即使 DST 转换时间在不同年份有所不同,后者也是如此。默认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类:

from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)
HOUR = timedelta(hours=1)

# A UTC class.

class UTC(tzinfo):
    """UTC"""

    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

# A class building tzinfo objects for fixed-offset time zones.
# Note that FixedOffset(0, "UTC") is a different way to build a
# UTC tzinfo object.

class FixedOffset(tzinfo):
    """Fixed offset in minutes east from UTC."""

    def __init__(self, offset, name):
        self.__offset = timedelta(minutes = offset)
        self.__name = name

    def utcoffset(self, dt):
        return self.__offset

    def tzname(self, dt):
        return self.__name

    def dst(self, dt):
        return ZERO

# A class capturing the platform's idea of local time.

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 utcoffset(self, dt):
        if self._isdst(dt):
            return DSTOFFSET
        else:
            return STDOFFSET

    def dst(self, dt):
        if self._isdst(dt):
            return DSTDIFF
        else:
            return ZERO

    def tzname(self, dt):
        return _time.tzname[self._isdst(dt)]

    def _isdst(self, dt):
        tt = (dt.year, dt.month, dt.day,
              dt.hour, dt.minute, dt.second,
              dt.weekday(), 0, 0)
        stamp = _time.mktime(tt)
        tt = _time.localtime(stamp)
        return tt.tm_isdst > 0

Local = LocalTimezone()

# A complete implementation of current DST rules for major US time zones.

def first_sunday_on_or_after(dt):
    days_to_go = 6 - dt.weekday()
    if days_to_go:
        dt += timedelta(days_to_go)
    return dt

# US DST Rules
#
# This is a simplified (i.e., wrong for a few cases) set of rules for US
# DST start and end times. For a complete and up-to-date set of DST rules
# and timezone definitions, visit the Olson Database (or try pytz):
# http://www.twinsun.com/tz/tz-link.htm
# http://sourceforge.net/projects/pytz/ (might not be up-to-date)
#
# In the US, since 2007, DST starts at 2am (standard time) on the second
# Sunday in March, which is the first Sunday on or after Mar 8.
DSTSTART_2007 = datetime(1, 3, 8, 2)
# and ends at 2am (DST time; 1am standard time) on the first Sunday of Nov.
DSTEND_2007 = datetime(1, 11, 1, 1)
# 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; 1am standard 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, 1)
# 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;
# 1am standard 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

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

        # Find start and end times for US DST. For years before 1967, return
        # ZERO for no DST.
        if 2006 < dt.year:
            dststart, dstend = DSTSTART_2007, DSTEND_2007
        elif 1986 < dt.year < 2007:
            dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
        elif 1966 < dt.year < 1987:
            dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
        else:
            return ZERO

        start = first_sunday_on_or_after(dststart.replace(year=dt.year))
        end = first_sunday_on_or_after(dstend.replace(year=dt.year))

        # Can't compare naive to aware objects, so strip the timezone from
        # dt first.
        if start <= dt.replace(tzinfo=None) < end:
            return HOUR
        else:
            return ZERO

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子类中,每年 DST 过渡点的标准时间和夏时制都有不可避免的细微之处。具体而言,请考虑美国东部(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

DST 开始时(“开始”行),本地壁钟从 1:59 跳到 3:00.格式为 2:MM 的有效时间在该天实际上没有意义,因此astimezone(Eastern)不会在 DST 开始的那一天与hour == 2传递结果。为了使astimezone()做出此保证,rzinfo.dst()方法必须考虑“缺少时间”(东部时间为 2:MM)中的时间为夏令时。

当 DST 结束(“结束”行)时,可能会出现一个更严重的问题:在当地的墙上时间,不能明确地拼写一个小时:夏令时的最后一个小时。在东部,白天的时间是 5:MM UTC。当地壁钟再次从 1:59(夏令时)跳回到 1:00(标准时间)。 1:MM 形式的当地时间是模棱两可的。 astimezone()pass将两个相邻的 UTC 小时 Map 到同一本地时间来模仿本地时钟的行为。在东部示例中,格式为 5:MM 和 6:MM 的 UTC 时间在转换为东部时都 Map 为 1:MM。为了使astimezone()做出此保证,tzinfo.dst()方法必须将“重复小时”中的时间视为标准时间。如示例中所示,可以pass在时区的标准本地时间中表示 DST 切换时间来轻松地进行安排。

不能承受此类歧义的应用程序应避免使用混合tzinfo子类。使用 UTC 或任何其他固定偏移tzinfo子类(例如仅表示 EST(固定偏移-5 小时)或仅 EDT(固定偏移-4 小时)的类)时,没有任何歧义。

See also

  • pytz

  • 标准库没有tzinfo实例,但是存在一个第三方库,它将* IANA 时区数据库*(也称为 Olson 数据库)带到 Python:* pytz *。

  • pytz *包含最新信息,建议使用。
  • IANA 时区数据库

  • 时区数据库(通常称为 tz 或 zoneinfo)包含代表 Global 许多代表性位置的本地时间历史的代码和数据。它会定期更新,以反映政治机构对时区边界,UTC 偏移量和夏令时规则所做的更改。

8.1.7. strftime()和 strptime()行为

datedatetimetime对象都支持strftime(format)方法,以在显式格式字符串的控制下创建表示时间的字符串。从广义上讲,d.strftime(fmt)的行为类似于time模块的time.strftime(fmt, d.timetuple()),尽管并非所有对象都支持timetuple()方法。

相反,datetime.strptime()类方法从表示日期和时间的字符串以及相应的格式字符串中创建datetime对象。 datetime.strptime(date_string, format)等效于datetime(*(time.strptime(date_string, format)[0:6])),但格式中包含datetime.strptime支持但被time.strptime丢弃的亚秒分量或时区偏移信息。

对于time个对象,不应使用年,月和日的格式代码,因为时间对象没有这样的值。如果仍然使用它们,则用1900代替年份,用1代替月份和日期。

对于date个对象,不应使用小时,分钟,秒和微秒的格式代码,因为date个对象没有这样的值。如果仍然使用它们,则用0代替它们。

在不同平台上,支持的全部格式代码集会有所不同,因为 Python 会调用平台 C 库的strftime()函数,并且平台版本也很常见。要查看平台所支持的全套格式代码,请查阅* strftime(3)*文档。

出于同样的原因,对包含无法在当前语言环境的字符集中表示的 Unicode 代码点的格式字符串的处理也取决于平台。在某些平台上,此类代码点会保留在输出中,而在其他平台上,strftime可能会引发UnicodeError或返回空字符串。

以下是 C 标准(1989 版)要求的所有格式代码的列表,这些格式代码在所有使用标准 C 实现的平台上都可以使用。请注意,C 标准的 1999 版本增加了其他格式代码。

strftime()工作的确切年份范围也因平台而异。无论平台如何,都无法使用 1900 年之前的年份。

DirectiveMeaningExampleNotes
%a工作日为语言环境的缩写名称。周日,周一,…,周六(en_US);

因此,Mo,...,Sa(de_DE)
(1)
%A工作日为语言环境的全名。星期日,星期一,…,星期六(zh_CN);
桑塔格,蒙塔格,…,萨姆斯塔格(de_DE)
(1)
%w工作日作为十进制数字,其中 0 是星期日,6 是星期六。0,1,…,6
%d每月的一天,以零填充的十进制数。01、02,…,31
%b月份为语言环境的缩写名称。1 月,2 月,…,12 月(zh_CN);
一月,二月,…,迪斯(de_DE)
(1)
%B月份为语言环境的全名。1 月,2 月,…,12 月(en_US);
Januar,Februar,...,Dezember(de_DE)
(1)
%m月份为零填充的十进制数字。01、02,…,12
%y无世纪的年份作为补零的十进制数字。00,01,…,99
%Y以世纪作为十进制数字的年份。1970、1988、2001、2013
%H小时(24 小时制),为零填充的十进制数字。00、01,…,23
%I小时(12 小时制),为零填充的十进制数字。01、02,…,12
%p相当于 AM 或 PM 的语言环境。AM,PM(en_US);
上午,下午(de_DE)
(1),(2)
%M分钟,为零填充的十进制数字。00,01,…,59
%S第二个为零填充的十进制数字。00,01,…,59(3)
%f微秒为十进制数字,左侧为零。000000,000001,…,999999(4)
%zUTC 偏移量,格式为 HHMM 或-HHMM(如果对象是天真对象,则为空字符串)。(空),0000,-0400、1030(5)
%Z时区名称(如果对象是天真对象,则为空字符串)。(空),UTC,EST,CST
%j一年中的一天,用零填充的十进制数字。001、002,…,366
%U一年中的周号(星期日为一周的第一天),为零填充的十进制数。第一个星期日之前的新的一年中的所有天都被认为是第 0 周。00,01,…,53(6)
%W一年中的星期几(星期一为星期几),以十进制数表示。第一个星期一之前的新的一年中的所有天都视为在第 0 周。00,01,…,53(6)
%c语言环境的适当日期和时间表示形式。1988 年 8 月 16 日,星期二,21:30:00(en_US);
Di 16 Aug 21:30:00 1988(de_DE)
(1)
%x区域设置的适当日期表示形式。08/16/88(无);
08/16/1988 (en_US);
16.08.1988 (de_DE)
(1)
%X语言环境的适当时间表示形式。21:30:00(en_US);
21:30:00 (de_DE)
(1)
%%Literals'%'字符。

Notes:

  • 由于格式取决于当前的语言环境,因此在对输出值进行假设时应格外小心。字段 Sequences 将有所不同(例如,“月/日/年”与“日/月/年”),并且输出中可能包含使用语言环境默认编码编码的 Unicode 字符(例如,如果当前语言环境为ja_JP,则默认编码可以是eucJPSJISutf-8中的任何一种;请使用locale.getlocale()确定当前语言环境的编码)。

  • strptime()方法一起使用时,%p指令仅在使用%I指令解析小时时才影响输出小时字段。

  • time模块不同,datetime模块不支持 leap 秒。

  • %f是 C 标准中格式字符集的扩展(但在日期时间对象中单独实现,因此始终可用)。与strptime()方法一起使用时,%f伪指令接受 1 到 6 位数字和右侧的零填充。

2.6 版的新Function。

  • 对于幼稚的对象,格式为%z%Z的代码将替换为空字符串。

对于有意识的对象:

  • %z

    • utcoffset()转换为 HHMM 或-HHMM 形式的 5 个字符的字符串,其中 HH 是 2 个数字的字符串,给出了 UTC 偏移小时数,而 MM 是 2 个数字的字符串,给出了 UTC 偏移分钟数。例如,如果utcoffset()返回timedelta(hours=-3, minutes=-30),则%z将替换为字符串'-0330'
  • %Z

    • 如果tzname()返回None,则%Z替换为空字符串。否则,%Z将被返回值替换,该值必须是字符串。
  • 当与strptime()方法一起使用时,%U%W仅在指定星期几和年份的情况下用于计算。

Footnotes

  • [1]
    • 如果,也就是说,我们忽略相对论的影响