如何使用 Python datetime 模块对日期时间进行运算?timedelta 类介绍
Python datetime 模块的 date,time,datetime 对象之间的运算
对于 Pythondatetime
模块的date
,time
以及datetime
对象,可使用减法运算符和比较运算符进行运算,参与运算的对象需要是相同的类型,比如date
对象不能与time
或datetime
对象进行运算。
使用减法运算符-
可以计算两个日期(date
对象)或日期时间(datetime
对象)之间的差值,这将返回 Pythondatetime
模块的timedelta
对象。
date1 - date2
datetime1 - datetime2
无法计算 Python datetime 模块的 time 对象之间的时间差值
你可以使用减法运算符-
计算日期或日期时间之间的差值,但对于 Pythondatetime
模块的time
对象,无法通过减法运算符-
计算他们之间的差值,这将导致异常TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'
。
from datetime import date, datetime
# 计算两个日期之间差值
date(2024, 10, 10) - date(2024, 10, 1)
datetime.timedelta(days=9)
# 计算两个日期时间之间差值
datetime(2024, 10, 1, 0, 0, 0, 1234) - datetime(2024, 10, 10, 0, 0, 1, 123)
datetime.timedelta(days=-10, seconds=86399, microseconds=1111)
使用比较运算符==
或!=
可以计算两个日期(date
对象),两个时间(time
对象)或日期时间(datetime
对象)是否相等或是否不相等。
date1 == date2
date1 != date2
time1 == time2
time1 != time2
datetime1 == datetime2
datetime1 != datetime2
表示相同日期的 Python datetime 模块的 date 与 datetime 对象不相等
即便表示了相同的日期,Pythondatetime
模块的date
和datetime
对象不会相等,比如,date(2024,1,1)
与datetime(2024,1,1)
不相等。
from datetime import date, time, datetime
# 两个日期相等
date(2024, 10, 3) == date(2024, 10, 3)
True
# 两个时间相等
time(1, 1) == time(1, 1, 0, 0)
True
# 两个日期时间相等
datetime(2024, 10, 3, 1) != datetime(2024, 10, 3, 1, 0)
False
# date 和 datetime 不相等
date(2024, 10, 3) == datetime(2024, 10, 3)
False
使用比较运算符<
或<=
可以计算一个日期(date
对象)是否小于或小于等于另一个日期,计算一个时间(time
对象)是否小于或小于等于另一个时间,计算一个日期时间(datetime
对象)是否小于或小于等于另一个日期时间。
使用比较运算符>
或>=
可以计算一个日期(date
对象)是否大于或大于等于另一个日期,计算一个时间(time
对象)是否大于或大于等于另一个时间,计算一个日期时间(datetime
对象)是否大于或大于等于另一个日期时间。
date1 < date2
date1 <= date2
time1 < time2
time1 <= time2
datetime1 < datetime2
datetime1 <= datetime2
date1 > date2
date1 >= date2
time1 > time2
time1 >= time2
datetime1 > datetime2
datetime1 >= datetime2
from datetime import date, time, datetime
# 日期 2024-10-3 更大
date(2024, 10, 3) < date(2024, 10, 1)
False
# 时间 23:59:59 更大
time(23, 59, 59) > time(23, 59)
True
# 日期时间 2024-10-3 23:59:59.123456 更大
datetime(2024, 10, 3, 23, 59, 59) <= datetime(2024, 10, 3, 23, 59, 59, 123456)
True
时区
如果你想了解时区信息对time
,datetime
对象运算的影响,那么可以查看Python datetime 模块的时区对象 tzinfo 对日期时间运算的影响一段。
Python datetime 模块的 timedelta 类
Pythondatetime
模块的timedelta
类,用于表示两个日期或两个日期时间之间的差值,该类的实例通常由包含减法运算符-
的表达式计算得到,也可以使用构造器创建,传递给构造器的参数将被换算累计为timedelta
对象的days
,seconds
和microseconds
的属性,这意味着转递的任意参数都将成为日期时间差值的一部分。
timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
- days 参数
days
参数表示日期时间差值持续的天数。- seconds 参数
seconds
参数表示日期时间差值持续的秒数。- microseconds 参数
microseconds
参数表示日期时间差值持续的微秒。- milliseconds 参数
milliseconds
参数表示毫秒数(1
秒等于1000
毫秒),他将被累计为微秒(1
毫秒等于1000
微秒)。- minutes 参数
minutes
参数表示分钟数,他将被累计为秒(1
分钟等于60
秒)。- hours 参数
hours
参数表示小时数,他将被累计为秒(1
小时等于3600
秒)。- weeks 参数
weeks
参数表示星期数,他将被累计为天(1
星期等于7
天),秒(如果有秒的部分)和微秒(如果有微秒的部分)。
Python datetime 模块的 timedelta 类的构造器参数可以是负数和小数
在 Pythondatetime
模块的timedelta
类的构造器中,构造器的参数可以是负数和小数,除了表示微秒的microseconds
,该参数可以是负数但不能是小数。此外,在参数milliseconds
所表示的毫秒被转换为微秒时,仅前三位小数有效(其余部分会被舍入),比如,毫秒11.2345
会被转换为微秒11235
,毫秒11.2344
会被转换为微秒11234
。
对于构造器参数days
,weeks
,hours
,minutes
和seconds
,如果拥有小数部分,则相当于将其计算为对应秒数,其微秒部分为六位(其余部分会被舍入)。比如,表达式timedelta(days=0.5555555555)
,其微秒部分的计算结果为9999952
,舍入后为999995
(datetime.timedelta(seconds=47999,microseconds=999995)
),表达式timedelta(days=0.55555555555)
,其微秒部分的计算结果为99999952
,舍入后为1
秒(datetime.timedelta(seconds=48000)
)。
from datetime import timedelta
# 创建 timedelta 对象
timedelta(days=1, hours=-24, minutes=60.5)
datetime.timedelta(seconds=3630)
timedelta(minutes=1, milliseconds=123, microseconds=111567)
datetime.timedelta(seconds=60, microseconds=234567)
timedelta(days=0.5, weeks=0.5, hours=0.5, minutes=0.5)
datetime.timedelta(days=4, seconds=1830)
timedelta(seconds=0.5, milliseconds=0.5)
datetime.timedelta(microseconds=500500)
获取 Python datetime 模块的 timedelta 对象所对应的日期时间差值信息
Pythondatetime
模块的timedelta
对象拥有以下只读属性,可用于获取日期时间差值的相关信息,其中days
属性表示日期时间差值所持续的天数(大于等于-999999999
,小于等于999999999
),seconds
属性表示日期时间差值所持续的秒数(大于等于0
,小于86400
),microseconds
属性表示日期时间差值所持续的微秒(大于等于0
,小于1000000
)。
timedelta.days
timedelta.seconds
timedelta.microseconds
Pythondatetime
模块的timedelta
对象的total_seconds
方法,可用于获取日期时间差值对应的总秒数(不同于seconds
属性),微秒部分将被表示为小数,因此,该方法的返回值是一个浮点数。
timedelta.total_seconds()
Python datetime 模块的 timedelta 对象的 seconds 属性和 total_seconds 方法的区别
Pythondatetime
模块的timedelta
对象的total_seconds
方法所返回的秒数可以表示完整的日期时间差值,而seconds
属性需要和days
,microseconds
属性一起才能表示完整的日期时间差值。
from datetime import timedelta
# 获取日期时间差值信息
td = timedelta(days=1, weeks=1, hours=0.5, milliseconds=1.234)
td.days
8
td.seconds
1800
td.microseconds
1234
# 总秒数
td.total_seconds()
693000.001234
Python datetime 模块的 timedelta 对象的 total_seconds 方法可能失真
这里需要指出,对于 Pythondatetime
模块的timedelta
对象的total_seconds
方法,如果日期时间的差值过大,那么其返回值的小数(微秒)部分可能会失真。
from datetime import timedelta
# 差值过大,微秒部分失真
timedelta(days=365 * 3000, microseconds=123456).total_seconds()
94608000000.12346
Python datetime 模块的 timedelta 对象所允许的最小和最大日期时间差值
Pythondatetime
模块的timedelta
类的类变量min
和max
,分别表示所允许的最小日期时间差值和最大日期时间差值,其中min
等价于表达式timedelta(days=-999999999)
运算得到的timedelta
对象,max
等价于表达式timedelta(days=999999999,hours=23,minutes=59,seconds=59,microseconds=999999)
或timedelta(days=999999999,seconds=86399,microseconds=999999)
运算得到的timedelta
对象。
timedelta.min
timedelta.max
from datetime import timedelta
# 最小日期时间差值
timedelta.min
datetime.timedelta(days=-999999999)
# 最大日期时间差值
timedelta.max
datetime.timedelta(days=999999999, seconds=86399, microseconds=999999)
Python datetime 模块的 timedelta 对象之间的运算
你可以使用某些运算符对 Pythondatetime
模块的timedelta
对象进行运算,如果运算的结果是一个新的timedelta
对象,并且日期时间差值超出了timedelta
对象的表达范围(比如-timedelta.max
),那么可能会引发异常OverflowError
,如果涉及除法运算(比如,取余或整除)的除数为0
或等价于timedelta()
的timedelta
对象,那么可能会引发异常ZeroDivisionError
。
使用加法运算符+
和减法运算符-
,可以在 Pythondatetime
模块的timedelta
对象之间进行加法或减法运算,这相当于将日期时间的差值相加或相减,其运算结果是一个新的timedelta
对象。
timedelta1 + timedelta2
timedelta1 - timedelta2
from datetime import timedelta
# 将两个日期时间差值相加
timedelta(days=1, hours=324) + timedelta(weeks=3)
datetime.timedelta(days=35, seconds=43200)
# 将两个日期时间差值相减
timedelta(hours=3, minutes=20) - timedelta(minutes=45)
datetime.timedelta(seconds=9300)
使用除法运算符/
,可以在 Pythondatetime
模块的timedelta
对象之间进行除法运算,这相当于将日期时间的差值相除,其运算结果是一个表示倍数关系的浮点数。
使用整除运算符//
,可以在 Pythondatetime
模块的timedelta
对象之间进行整除运算,这相当于将日期时间的差值整除(运算结果为整数,丢弃结果中的小数部分)。
timedelta1 / timedelta2
timedelta1 // timedelta2
from datetime import timedelta
# 将两个日期时间差值相除
timedelta(5) / timedelta(2)
2.5
timedelta(1) / timedelta(hours=48)
0.5
# 将两个日期时间差值整除
timedelta(5) // timedelta(2)
2
timedelta(1) // timedelta(hours=48)
0
使用取余运算符%
,可以在 Pythondatetime
模块的timedelta
对象之间进行取余运算,这相当于将日期时间的差值相除然后获取余数,其运算结果是一个新的timedelta
对象(两个timedelta
对象的days
,seconds
,microseconds
属性相除,并通过余数来创建新的timedelta
对象)。
timedelta1 % timedelta2
from datetime import timedelta
# 对两个日期时间差值取余
timedelta(days=5, hours=5, microseconds=5) % timedelta(days=2, minutes=120, milliseconds=0.002)
datetime.timedelta(days=1, seconds=3600, microseconds=1)
通过 Python 的divmod
函数,可同时完成对两个datetime
模块的timedelta
对象的整除和取余运算,运算的结果是一个 Python 元组,元组的第一个元素是整除的结果(与整除运算符//
的结果相同),第二个元素是取余的结果(与取余运算符%
的结果相同)。
divmod(timedelta1, timedelta2)
from datetime import timedelta
# 同时整除和取余
divmod(timedelta(5), timedelta(2))
(2, datetime.timedelta(days=1))
使用一元运算符+
,可以获得一个新的 Pythondatetime
模块的timedelta
对象,新对象所表示的日期时间差值与原有timedelta
对象相同。使用一元运算符-
,可以获得一个新的 Pythondatetime
模块的timedelta
对象,新对象将根据原有timedelta
对象的days
,seconds
以及microseconds
属性的相反数创建。
+timedelta
-timedelta
from datetime import timedelta
# 一元运算符
+timedelta(hours=23, minutes=59, seconds=59)
datetime.timedelta(seconds=86399)
-timedelta(hours=23, minutes=59, seconds=59)
datetime.timedelta(days=-1, seconds=1)
使用比较运算符==
或!=
可以计算两个日期时间差值(timedelta
对象)是否相等或是否不相等。
timedelta1 == timedelta2
timedelta1 != timedelta2
from datetime import date, timedelta
# 1 分钟等于 60 秒
timedelta(minutes=1) == timedelta(seconds=60)
True
# 两边表达式相等
timedelta(days=1) != date(2024, 10, 1) - date(2024, 9, 30)
False
使用比较运算符<
或<=
可以计算一个日期时间差值(timedelta
对象)是否小于或小于等于另一个日期时间差值。使用比较运算符>
或>=
可以计算一个日期时间差值(timedelta
对象)是否大于或大于等于另一个日期时间差值。
timedelta1 < timedelta2
timedelta1 <= timedelta2
timedelta1 > timedelta2
timedelta1 >= timedelta2
from datetime import timedelta
# 比较日期时间差值大小
timedelta(hours=1.5) > timedelta(minutes=80)
True
timedelta(milliseconds=1.234) > timedelta(microseconds=1235)
True
Python datetime 模块的 timedelta 对象与数字类型的运算
除了在 Pythondatetime
模块的timedelta
对象之间进行运算,以下运算符还可以完成timedelta
对象与数字类型之间的运算,如果运算的结果是一个新的timedelta
对象,并且日期时间差值超出了timedelta
对象的表达范围,那么可能会引发异常OverflowError
。
使用乘法运算符*
和除法运算符/
,可以完成timedelta
对象与 Python 整数或浮点数之间的乘法和除法运算,这相当日期时间差值被扩大或缩小指定的倍数,其运算结果是一个新的timedelta
对象。
使用整除运算符//
,可以完成timedelta
对象与 Python 整数之间的整除运算,该运算符与除法运算符/
类似,但会丢弃微秒的小数部分而不是进行舍入。
timedelta * int|float
int|float * timedelta
timedelta / int|float
timedelta1 // int
from datetime import timedelta
# 浮点数与日期时间差值相乘
3.5 * timedelta(days=1, hours=30)
datetime.timedelta(days=7, seconds=75600)
# 日期时间差值与整数相除
timedelta(days=1) / 35
# 微秒的小数部分会被舍入
datetime.timedelta(seconds=2468, microseconds=571429)
timedelta(days=1) // 35
# 丢弃微秒的小数部分
datetime.timedelta(seconds=2468, microseconds=571428)
Python datetime 模块的 timedelta 对象与 date,datetime 对象之间的运算
使用加法运算符+
和减法运算符-
,Pythondatetime
模块的timedelta
对象可以同date
或datetime
对象进行加法或减法运算,其运算结果是一个新的date
或datetime
对象,这相当于将日期时间增加或减去一个差值。
需要指出的是,对于 Pythondatetime
模块的date
对象,仅timedelta
对象的days
属性会参与运算。
date|datetime + timedelta
date|datetime - timedelta
timedelta + date|datetime
timedelta - date|datetime
from datetime import date, datetime, timedelta
# 增加 6 天
timedelta(weeks=0.9) + date(2024, 1, 1)
datetime.date(2024, 1, 7)
# 减去 1 天 11 小时
datetime(2024, 1, 1, 10, 10) - timedelta(days=1, hours=11)
datetime.datetime(2023, 12, 30, 23, 10)
时区
如果你想了解时区信息对timedelta
,datetime
对象运算的影响,那么可以查看Python datetime 模块的时区对象 tzinfo 对日期时间运算的影响一段。
获取 Python datetime 模块的 timedelta 对象所表示的日期时间差值的绝对值
通过 Python 的abs
函数,可以获取 Pythondatetime
模块的timedelta
对象所表示的日期时间差值的绝对值,当timedelta
对象的days
属性大于等于0
时,abs
函数的返回值等价于使用一元运算符+
,当timedelta
对象的days
属性小于0
时,abs
函数的返回值等价于使用一元运算符-
。
abs(timedelta)
from datetime import timedelta
# 虽然参数 days 为 1,但最终的 days 属性为 -1
td = timedelta(days=1, hours=-25)
td
datetime.timedelta(days=-1, seconds=82800)
abs(td)
# 等同于 timedelta(days=1, seconds=-82800)
datetime.timedelta(seconds=3600)
将 Python datetime 模块的 timedelta 对象所表示的日期时间差值转换为字符串
通过 Python 的repr
函数或字符串类型的构造器str
,可以将 Pythondatetime
模块的timedelta
对象所表示的日期时间差值转换为一个字符串。当然,调用timedelta
对象的__repr__
或__str__
方法可实现相同效果。
repr(timedelta)
str(timedelta)
timedelta.__repr__()
timedelta.__str__()
from datetime import timedelta
td = timedelta(days=3, hours=0.5, milliseconds=123)
# 将日期时间差值转换为字符串
str(td)
'3 days, 0:30:00.123000'
td.__repr__()
'datetime.timedelta(days=3, seconds=1800, microseconds=123000)'
Python datetime 模块的 timedelta 对象与布尔类型
对于 Pythondatetime
模块的timedelta
对象,如果其表示的日期时间差值不为0
,那么对象将被视为真(True
),否则将被视为假(False
)。
from datetime import timedelta
# 日期时间差值为 0 则等价于 False
bool(timedelta(days=1, hours=-24))
False
bool(timedelta())
False
# 日期时间差值不为 0 则等价于 True
bool(timedelta(microseconds=1))
True