使用Python计算时间差

8 投票
3 回答
18978 浏览
提问于 2025-04-18 07:41

我在想有没有什么方法或者内置的库可以用来计算两个字符串输入之间的时间差。

我的意思是,如果我有两个输入字符串:

  1. '2013-10-05T01:21:07Z'
  2. '2013-10-05T01:21:16Z'

我该怎么计算它们之间的时间差,并把结果打印出来呢。

我知道这听起来有点傻,但任何帮助都非常感谢。

3 个回答

-2
import datetime
a = datetime.datetime.now()
b = datetime.datetime.now()
c = b - a
datetime.timedelta(0, 8, 562000)
divmod(c.days * 86400 + c.seconds, 60)

原始回答可以在 这里 找到。

8

你似乎在使用一种叫做ISO 8601格式的日期时间。这种格式在很多地方都能见到,比如GPS交换格式。

[-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]

使用datetime:

import datetime
a = datetime.datetime.strptime("2013-10-05T01:21:07Z", "%Y-%m-%dT%H:%M:%SZ")
b = datetime.datetime.strptime("2013-10-05T01:21:16Z", "%Y-%m-%dT%H:%M:%SZ")
c = b - a
print(c)

优点:

  • 这是Python标准库自带的功能
  • 使用面向对象的方式,比较简单

缺点:

  • 需要手动处理其他有效的ISO 8601格式,比如'2013-10-05T01:21:16+00:00'
  • 对于闰秒(比如'2012-06-30T23:59:60Z')会报错

使用python-dateutil:

import dateutil.parser
a = dateutil.parser.parse("2013-10-05T01:21:07Z")
b = dateutil.parser.parse("2013-10-05T01:21:16Z")
c = b - a
print(c)

优点:

  • 几乎可以自动处理任何时间格式

缺点:

  • 需要安装python-dateutil库(可以用pip install python-dateutil来安装)
  • 对于闰秒(比如'2012-06-30T23:59:60Z')会报错

使用time.strptime和time.mktime,正如Alfe所建议的那样

优点:

  • 这是Python标准库自带的功能
  • 可以解析闰秒(比如'2012-06-30T23:59:60Z')

缺点:

  • 需要手动处理其他有效的ISO 8601格式,比如'2013-10-05T01:21:16+00:00'
  • 在'2012-06-30T23:59:60Z'和'2012-07-01T00:00:00Z'之间会损失一个闰秒(这在不知道下一个闰秒何时发生的情况下是无法避免的)
9

使用 strptime() 来解析你的时间字符串:

a = time.strptime('2013-10-05T01:21:07Z', '%Y-%m-%dT%H:%M:%SZ')
b = time.strptime('2013-10-05T01:21:16Z', '%Y-%m-%dT%H:%M:%SZ')

这个方法会把给定的时间字符串解析为本地时间(自动处理夏令时),结果会是时间结构体。这些结构体会显示夏令时的状态:是关闭(0)、开启(1),还是自动(-1)。接下来,你可以把这些转换成一个浮点数(自1970年1月1日以来的秒数):

a = time.mktime(a)
b = time.mktime(b)

然后计算时间差(以秒为单位):

d = b - a

接着把它们转换成天/小时/分钟/秒:

days = int(d) / 86400
hours = int(d) / 3600 % 24
minutes = int(d) / 60 % 60
seconds = int(d) % 60

最后一段代码只适用于正的时间差,所以要小心不要把 ab 搞混了 ;-)

不过 @J.F.Sebastian 正确指出,这可能不是你想要的结果。从你的字符串来看,它们似乎描述的是 UTC 时间,而不是本地时间。对于时间差来说,这在跨越夏令时切换时是很重要的。在这种情况下,结果可能会导致时间差多出一个小时或少一个小时(因为 UTC 时间总是没有夏令时的)。

为了避免这个问题,你可以把夏令时标志从自动(-1)设置为固定值(例如,0表示关闭),然后使用这些值:

a = time.mktime(a[:-1] + (0,))  # switch DST to off
b = time.mktime(b[:-1] + (0,))

或者,正如 @J.F.Sebastian 所指出的,你可以不使用 time 模块,而是使用 datetime.datetime,它不受夏令时的影响:

a = datetime.datetime.strptime('2013-10-05T01:21:07Z', '%Y-%m-%dT%H:%M:%SZ')
b = datetime.datetime.strptime('2013-10-05T01:21:16Z', '%Y-%m-%dT%H:%M:%SZ')

这样得到的结果就是 datetime 对象,可以直接相减,得到一个 timedelta 对象,表示你想要的时间差。打印出来的结果会是类似 0:00:05 的格式,这可能正是你所需要的。

撰写回答