日期和时间的格式化符号

如下表:

date, datetimetime 对象都支持 strftime(format) 方法,可用来创建由一个显式格式字符串所控制的表示时间的字符串。

相反地,datetime.strptime() 类会根据表示日期和时间的字符串和相应的格式字符串来创建一个 datetime 对象。

strftime()与 strptime() 的高层级比较:

下表提供了 strftime()strptime() 的高层级比较:

strftime strptime
用法 根据给定的格式将对象转换为字符串 将字符串解析为给定相应格式的 datetime 对象
方法类型 实例方法 类方法
方法 date; datetime; time datetime
签名 strftime(format) strptime(date_string, format)

datetime.timedelta对象

timedelta 对象表示一段持续的时间,即两个 datetimedate 实例之间的差值。

基本实现

mydelta=datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

所有参数都是可选的并且默认为 0。 这些参数可以是整数或者浮点数,并可以为正值或者负值。

只有 days, secondsmicroseconds 会存储在内部。 参数单位的换算规则如下

  • 1毫秒会转换成1000微秒。

  • 1分钟会转换成60秒。

  • 1小时会转换成3600秒。

  • 1星期会转换成7天。

1
2
3
4
5
6
7
8
9
10
11
12
13
import datetime

delta = datetime.timedelta(
days=50,
seconds=27,
microseconds=10,
milliseconds=29000,
minutes=5,
hours=8,
weeks=2
)
print('持续时间为:',delta)
# 输出64 days, 8:05:56.000010

在有任何参数为浮点型并且 microseconds 值为小数的情况下,从所有参数中余下的微秒数将被合并,并使用四舍五入偶不入奇的规则将总计值舍入到最接近的整数微秒值。 如果没有任何参数为浮点型的情况下,则转换和标准化过程将是完全精确的(不会丢失信息)。

如果标准化后的 days 数值超过了指定范围,将会抛出 OverflowError 异常。

类属性

  • datetime.timedelta.min

    最小的时间间隔, -999999999 days, 0:0

  • datetime.timedelta.max

    最大的时间间隔, 999999999 days, 23:59:59.999999

  • datetime.timedelta.resolution

    两个不相等的 timedelta 类对象最小的间隔为 timedelta(microseconds=1)

1
2
3
4
5
6
7
mindelta=datetime.timedelta.min
maxdelta=datetime.timedelta.max
resolution=datetime.timedelta.resolution

print('mindelta is:',mindelta) # -999999999 days, 0:00:00
print('maxdelta is:',maxdelta) # 999999999 days, 23:59:59.999999
print('resolution is:',resolution) # 0:00:00.000001

支持数学算术运算

运算 结果:
t1 = t2 + t3 t2t3 之和。 运算后 t1 - t2 == t3t1 - t3 == t2 为真值。 (1)
t1 = t2 - t3 t2t3 之差。 运算后 t1 == t2 - t3t2 == t1 + t3 为真值。 (1)(6)
t1 = t2 * i or t1 = i * t2 时差乘以一个整数。 运算后如果 i != 0t1 // i == t2 为真值。
通常情况下,t1 * i == t1 * (i-1) + t1 为真值。 (1)
t1 = t2 * f or t1 = f * t2 乘以一个浮点数,结果会被舍入到 timedelta 最接近的整数倍。 精度使用四舍五偶入奇不入规则。
f = t2 / t3 总时长 t2 除以间隔单位 t3 (3)。 返回一个 float 对象。
t1 = t2 / f or t1 = t2 / i 除以一个浮点数或整数。 结果会被舍入到 timedelta 最接近的整数倍。 精度使用四舍五偶入奇不入规则。
t1 = t2 // i or t1 = t2 // t3 计算底数,其余部分(如果有)将被丢弃。在第二种情况下,将返回整数。 (3)
t1 = t2 % t3 余数为一个 timedelta 对象。(3)
q, r = divmod(t1, t2) 通过 : q = t1 // t2 (3) and r = t1 % t2 计算出商和余数。q是一个整数,r是一个 timedelta 对象。
+t1 返回一个相同数值的 timedelta 对象。
-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] 的字符串,当 t 为负数的时候, D 也为负数。 (5)
repr(t) 返回一个 timedelta 对象的字符串表示形式,作为附带正规属性值的构造器调用。

转化为秒数

timedelta.total_seconds()

返回期间占用了多少秒。等价于 td / timedelta(seconds=1)。对于秒以外的间隔单位,直接使用除法形式 (例如 td / timedelta(microseconds=1))。

需要注意的是,时间间隔较大时,这个方法的结果中的微秒将会失真(大多数平台上大于270年视为一个较大的时间间隔)。

1
2
3
total_seconds=delta.total_seconds()
print('The total_seconds of delta is :',total_seconds)
# 5558756.00001

datetime.date对象

首先,创建一个日期对象

创建日期对象

创建日期对象

1
2
3
# 创建一个日期对象
birth = datetime.date(2004, 2, 18)
print(birth) # Output: 2004-01-28

日期对象的表示范围

最小值是公元元年1月1日,最大值是公元9999年12月31日

1
2
3
# 表示范围
print('datetime.date的最大值:',datetime.date.max) # 9999-12-31
print('datetime.date的最小值:',datetime.date.min) # 0001-01-01

获取各个年/月/日

直接调用其属性,year,month,day

1
2
3
4
5
# 获得各个部分
y=birth.year
m=birth.month
d=birth.day
print('The month of birth:',m) # 输出: 2

日期对象格式化为字符串、修改日期

使用strftime精细控制格式化

使用方法是mydate.strftime('格式化字符串')

1
2
3
# 使用strftime精细控制,表示时、分或秒的格式代码值将为 0
print("formated birth is :",birth.strftime("%Y年%m月%d日"))
# 输出2004年02月18日

格式化为YYYY-MM-DD

使用方法是mydate.isoformat()

1
2
3
4
5
# 输出iso8601日期格式字符串YYYY-MM-DD
birth_iso_format=birth.isoformat()
print(f'birth_iso_format is {birth_iso_format}')
# 2004-02-18

格式化为:’Weekday month day h-m-s YYYY’

使用方法是mydate.ctime()

1
2
3
4
# 日期格式化为:'Wed Dec  4 00:00:00 2002'
birth_ctime=birth.ctime()
print(f'birth_ctime is {birth_ctime}')
# Wed Feb 18 00:00:00 2004

修改日期

使用方法是mydate.replace(year=newyear,month=newmonth,day=newday)

1
2
3
4
# 修改日期
# newdate=date.replace(year=self.year, month=self.month, day=self.day)
revised_birth= birth.replace(month=1,day=28)
print('修改了月份和天的birth是:',revised_birth)

关于周几和距离公元元年1月1日的距离

获取0~6表示的weekday

mydate.weekday()返回一个整数代表星期几,星期一为0,星期天为6

1
2
3
# 返回一个整数代表星期几,星期一为0,星期天为6
week = 1 + birth.weekday()
print('birth是周',week)

获取1~7表示的weekday

mydate.isoweekday()返回一个整数代表星期几,星期一为1,星期天为7

1
2
3
# 直接用iso标准,1~7
week=birth.isoweekday()
print('birth是周',week)

获取『某年某周周几』是『某年某月某日』

mydate.fromisocalendar(YYYY,week,weekday)返回确切的年月日

1
2
3
4
# 获取『某年某周周几』是『几月几日』
day3=datetime.date.fromisocalendar(2024,45,1)
print('2024年45周周一是:',day3)
# 2024-11-04

获取『某年某月某日』是『某年某周周几』

mydate.fromisocalendar(YYYY,week,weekday)返回确切的年月日

1
2
3
4
# 获取当前日期的iso历法 :year, week 和 weekday
birth=datetime.date(2004,2,18)
birth_iso_cal=birth.isocalendar()
print(f'2004-2-18 is {birth_iso_cal}') #datetime.IsoCalendarDate(year=2004, week=8, weekday=3)

其他(字符串解析为日期对象、修改日期、获取当前日期)

字符串解析为日期对象

使用datetime.datetime.striptime(myString,'格式化字符串')方法。

1
2
3
4
# 将字符串解析为日期对象
str_date='2004-01-28'
obj_str_date=datetime.datetime.strptime(str_date,"%Y-%m-%d").date()
print('obj_str_date的类型是:',type(obj_str_date)) # 输出 <class 'datetime.date'>

修改日期

使用方法是mydate.replace(year=newyear,month=newmonth,day=newday)

1
2
3
4
# 修改日期
# newdate=date.replace(year=self.year, month=self.month, day=self.day)
revised_birth= birth.replace(month=1,day=28)
print('修改了月份和天的birth是:',revised_birth)

获取当前日期

使用datetime.datetime.today法。

1
2
print('datetime.datetime'.center(40,'-'))
print('今天是:',datetime.date.today()) # 今天是: 2024-08-05

支持数学算术运算

支持的运算:

运算 结果:
date2 = date1 + timedelta date2 将为 date1 之后的 timedelta.days 日。可以后退 (1)
date2 = date1 - timedelta 计算 date2 使得 date2 + timedelta == date1。 (2)
timedelta = date1 - date2 (3)精确结果
date1 == date2

date1 != date2
相等性比较。 (4)
date1 < date2

date1 > date2

date1 <= date2

date1 >= date2
顺序比较。 (5)

注释:

  1. 如果 timedelta.days > 0date2 将在时间线上前进,如果 timedelta.days < 0 则将后退。 操作完成后 date2 - date1 == timedelta.daystimedelta.secondstimedelta.microseconds 会被忽略。 如果 date2.year 将小于 MINYEAR 或大于 MAXYEAR 则会引发 OverflowError

  2. timedelta.secondstimedelta.microseconds 会被忽略。

  3. 该值是精确的,且不会溢出。 运算后 timedelta.secondstimedelta.microseconds 均为 0,且 date2 + timedelta == date1

  4. date 对象在表示相同的日期时相等。

  5. date1 的时间在 date2 之前则认为 date1 小于 date2。 换句话说,当且仅当 date1.toordinal() < date2.toordinal()date1 < date2

在布尔运算中,所有 date 对象都会被视为真值。

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, monthday 参数是必须的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 异常。

获取当前时间

利用datetime.datetime.today()或者datetime.datetime.now()

1
2
3
4
5
6
7
8
# 当前日期和时间
# 方法一
today1=datetime.datetime.today()
print('今天是:',today1) # 今天是: 2024-08-05 18:40:49.937493

# 方法二
today2=datetime.datetime.now()
print('今天是:',today2) # 今天是: 2024-08-05 18:42:38.699239

距离『公元元年1月1日』的距离

获得距离『公元元年1月1日』指定天数的具体日期(某年某月某日』)

利用datetime.datetime.fromordinal(天数)

1
2
after999999=datetime.datetime.fromordinal(999999)
print('999999days after 1,1,1 is :',after999999) # 2738-11-27 00:00:00

字符串解析为datetime对象

用datetime.datetime.fromisoformat(yourString)方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>>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)))

strptime()方法将字符串解析为datetime.datetime对象

用strptime()方法:

datetime.strptime(*date_string*, *format*)

1
2
3
4
5
6
birth='2004年2月18日'
birth_datetime=datetime.datetime.strptime(birth,'%Y年%m月%d日')
print('birth_datetime is:',birth_datetime)
print('The type of birth_datetime is:',type(birth_datetime))
# 2004-02-18 00:00:00
# <class 'datetime.datetime'>

datetime类格式化为字符串、计算周几

1
2
3
4
5
6
7
birth=datetime.datetime(2004,2,18)
birth_1=birth.weekday() # 2
birth_2=birth.isoweekday() # 3
birth_3=birth.isocalendar() # datetime.IsoCalendarDate(year=2004, week=8, weekday=3)
birth_4=birth.isoformat() # '2004-02-18T00:00:00'
birth_5=birth.ctime() # 'Wed Feb 18 00:00:00 2004'
birth_6=birth.strftime('%Y年%m月%d日') # '2004年02月18日'

注意:

datetime.isoformat(*sep='T'*, *timespec='auto'*)

返回一个以 ISO 8601 格式表示的日期和时间字符串:

datetime.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。 所有参数默认值均为 0 但 tzinfo 除外,其默认值为 None

类属性:

  • time.min

早最的可表示 time, time(0, 0, 0, 0)

  • time.max

最晚的可表示 time, time(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)

datetime.time对象格式化为字符串

使用time.isoformat(timespec=’auto’)方法

返回表示为下列 ISO 8601 格式之一的时间字符串:

可选参数 timespec 要包含的额外时间组件值 (默认为 'auto')。它可以是以下值之一:

  • 'auto': 如果 microsecond 为 0 则与 'seconds' 相同,否则与 'microseconds' 相同。

  • 'hours': 以两个数码的 HH 格式 包含 hour

  • 'minutes': 以 HH:MM 格式包含 hourminute

  • 'seconds': 以 HH:MM:SS 格式包含 hour, minutesecond

  • 'milliseconds': 包含完整时间,但将秒值的小数部分截断至毫秒。 格式为 HH:MM:SS.sss

  • 'microseconds': 以 HH:MM:SS.ffffff 格式包含完整时间。

备注

排除掉的时间部分将被截断,而不是被舍入。

使用 datetime.time.strftime(format)方法

方法参见datetime.datetimedatetime.date对象的方法

字符串解析为datetime.time对象

使用datetime.time.fromisoformat(‘string’)方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>>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)

修改datetime.time类

time.replace(*hour=self.hour*, *minute=self.minute*, *second=self.second*, *microsecond=self.microsecond*, *tzinfo=self.tzinfo*, ***, *fold=0*)

返回一个具有同样属性值的 time,除非通过任何关键字参数指定了某些属性值。 请注意可以通过指定 tzinfo=None 从一个感知型 time 创建一个简单型 time,而不必转换时间数据。

参考文章