URLhttps://learnscript.net/zh/python/date-times/datetime/operations/
    复制链接转到说明  示例

    如何使用 datetime 模块对日期时间进行运算?timedelta 类介绍

    我被代码海扁署名-非商业-禁演绎
    阅读 17:46·字数 5332·发布 

    date,time,datetime 对象之间的运算

    对于datetime以及datetime对象,可使用减法运算符和比较运算符进行运算,参与运算的对象需要是相同的类型,比如date对象不能与timedatetime对象进行运算。

    使用减法运算符-可以计算两个日期(date对象)或日期时间(datetime对象)之间的差值,这将返回timedelta对象。

    date1 - date2
    datetime1 - datetime2

    无法计算 time 对象之间的时间差值

    你可以使用减法运算符-计算日期或日期时间之间的差值,但对于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

    表示相同日期的 date 与 datetime 对象不相等

    即便表示了相同的日期,datedatetime对象不会相等,比如,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

    时区

    如果你想了解时区信息对timedatetime对象运算的影响,那么可以查看tzinfo 时区对象对日期时间运算的影响一段。

    datetime 模块的 timedelta 类

    datetime模块的timedelta类,用于表示两个日期或两个日期时间之间的差值,该类的实例通常由包含减法运算符-的表达式计算得到,也可以使用构造器创建,传递给构造器的参数将被换算累计为timedelta对象的dayssecondsmicroseconds的属性,这意味着转递的任意参数都将成为日期时间差值的一部分。

    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天),秒(如果有秒的部分)和微秒(如果有微秒的部分)。

    timedelta 类的构造器参数可以是负数和小数

    timedelta类的构造器中,构造器的参数可以是负数和小数,除了表示微秒的microseconds,该参数可以是负数但不能是小数。此外,在参数milliseconds所表示的毫秒被转换为微秒时,仅前三位小数有效(其余部分会被舍入),比如,毫秒11.2345会被转换为微秒11235,毫秒11.2344会被转换为微秒11234

    对于构造器参数daysweekshoursminutesseconds,如果拥有小数部分,则相当于将其计算为对应秒数,其微秒部分为六位(其余部分会被舍入)。比如,表达式timedelta(days=0.5555555555),其微秒部分的计算结果为9999952,舍入后为999995datetime.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)

    获取日期时间的差值信息

    timedelta对象拥有以下只读属性,可用于获取日期时间差值的相关信息,其中days属性表示日期时间差值所持续的天数(大于等于-999999999,小于等于999999999),seconds属性表示日期时间差值所持续的秒数(大于等于0,小于86400),microseconds属性表示日期时间差值所持续的微秒(大于等于0,小于1000000)。

    timedelta.days
    timedelta.seconds
    timedelta.microseconds

    timedelta对象的total_seconds方法,可用于获取日期时间差值对应的总秒数(不同于seconds属性),微秒部分将被表示为小数,因此,该方法的返回值是一个浮点数。

    timedelta.total_seconds()

    timedelta 对象的 seconds 属性和 total_seconds 方法的区别

    timedelta对象的total_seconds方法所返回的秒数可以表示完整的日期时间差值,而seconds属性需要和daysmicroseconds属性一起才能表示完整的日期时间差值。

    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

    timedelta 对象的 total_seconds 方法可能失真

    这里需要指出,对于timedelta对象的total_seconds方法,如果日期时间的差值过大,那么其返回值的小数(微秒)部分可能会失真。

    from datetime import timedelta
    # 差值过大,微秒部分失真
    timedelta(days=365 * 3000, microseconds=123456).total_seconds()
    94608000000.12346

    timedelta 对象所允许的最小和最大日期时间差值

    timedelta类的类变量minmax,分别表示所允许的最小日期时间差值和最大日期时间差值,其中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)

    timedelta 对象之间的运算

    你可以使用某些运算符对timedelta对象进行运算,如果运算的结果是一个新的timedelta对象,并且日期时间差值超出了timedelta对象的表达范围(比如-timedelta.max),那么可能会引发异常OverflowError,如果涉及除法运算(比如,取余或整除)的除数为0或等价于timedelta()timedelta对象,那么可能会引发异常ZeroDivisionError

    使用加法运算符+和减法运算符-,可以在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)

    使用除法运算符/,可以在timedelta对象之间进行除法运算,这相当于将日期时间的差值相除,其运算结果是一个表示倍数关系的浮点数。

    使用整除运算符//,可以在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

    使用取余运算符%,可以在timedelta对象之间进行取余运算,这相当于将日期时间的差值相除然后获取余数,其运算结果是一个新的timedelta对象(两个timedelta对象的dayssecondsmicroseconds属性相除,并通过余数来创建新的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函数,可同时完成对两个timedelta对象的整除和取余运算,运算的结果是一个元组,元组的第一个元素是整除的结果(与整除运算符//的结果相同),第二个元素是取余的结果(与取余运算符%的结果相同)。

    divmod(timedelta1, timedelta2)

    from datetime import timedelta
    # 同时整除和取余
    divmod(timedelta(5), timedelta(2))
    (2, datetime.timedelta(days=1))

    使用一元运算符+,可以获得一个新的timedelta对象,新对象所表示的日期时间差值与原有timedelta对象相同。使用一元运算符-,可以获得一个新的timedelta对象,新对象将根据原有timedelta对象的daysseconds以及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

    timedelta 对象与数字类型的运算

    除了在timedelta对象之间进行运算,以下运算符还可以完成timedelta对象与数字类型之间的运算,如果运算的结果是一个新的timedelta对象,并且日期时间差值超出了timedelta对象的表达范围,那么可能会引发异常OverflowError

    使用乘法运算符*和除法运算符/,可以完成timedelta对象与整数或浮点数之间的乘法和除法运算,这相当日期时间差值被扩大或缩小指定的倍数,其运算结果是一个新的timedelta对象。

    使用整除运算符//,可以完成timedelta对象与整数之间的整除运算,该运算符与除法运算符/类似,但会丢弃微秒的小数部分而不是进行舍入。

    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)

    timedelta 对象与 date,datetime 对象之间的运算

    使用加法运算符+和减法运算符-timedelta对象可以同datedatetime对象进行加法或减法运算,其运算结果是一个新的datedatetime对象,这相当于将日期时间增加或减去一个差值。

    需要指出的是,对于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)

    时区

    如果你想了解时区信息对timedeltadatetime对象运算的影响,那么可以查看tzinfo 时区对象对日期时间运算的影响一段。

    获取日期时间差值的绝对值

    通过 Python 的abs函数,可以获取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 的repr函数或字符串类型的构造器str,可以将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)'

    timedelta 对象与布尔类型

    对于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