使用datetime与timedelta减法时出现意外毫秒偏移问题
解决FreeTime类字符串断言的毫秒差异问题
- 根本原因是二进制浮点精度误差:Python里用浮点数(比如
0.1秒)实例化timedelta时,很多十进制小数无法被二进制浮点精确表示,实际存储的是近似值。比如你想表示100毫秒,用timedelta(seconds=0.1)的话,底层存储的可能是0.09999999999999999秒,转成字符串时就会出现毫秒位的差异。 - 别用浮点数实例化
timedelta:换成整数单位来构造,比如timedelta(milliseconds=100)或者timedelta(microseconds=100000),彻底避开浮点精度坑。 - 强制控制字符串格式化的小数位数:如果FreeTime的字符串输出是自己实现的(比如
__str__方法),格式化时固定保留三位毫秒数。比如:
def __str__(self): total_seconds = self.duration.total_seconds() # 拆分时分秒并格式化,强制保留三位毫秒 hours = int(total_seconds // 3600) minutes = int((total_seconds % 3600) // 60) seconds = total_seconds % 60 return f"{hours}:{minutes:02d}:{seconds:06.3f}"
如果用默认的str(timedelta),可以先把timedelta转成固定精度的数值再格式化,避免默认输出的精度波动。
- 调整单元测试的断言方式:如果不想改类的实现,也可以换断言逻辑——不用直接对比完整字符串,先用
assertAlmostEqual断言时长的总秒数在误差范围内(比如self.assertAlmostEqual(freetime.duration.total_seconds(), expected_sec, places=3)),再单独验证字符串的格式是否符合预期,或者用正则表达式匹配(比如忽略毫秒后多余的小数位)。
内容的提问来源于stack exchange,提问作者lorenzo
相关产品推荐
相关产品推荐

