关于日期:使用python计算时差

Calculate time difference using python

我想知道是否有一种方法或内置库可以从两个字符串输入中找到时间差异。

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

  • '2013-10-05t01:21:07z'
  • '2013-10-05t01:21:16z'
  • 如何计算时间差并将其打印为输出。

    我知道这听起来有点傻,但对此任何帮助都是感激的。


    您似乎在使用ISO 8601格式的日期时间。这种格式在许多地方都使用,包括GPS交换格式。

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

    使用日期时间:

    1
    2
    3
    4
    5
    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:

    1
    2
    3
    4
    5
    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安装python dateutil)
    • 引发闰秒的异常,如"2012-06-30t23:59:60z"

    使用alfe建议的time.strptime和time.mktime

    优势:

    • 内置于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"之间损失一个闰秒(在不知道下一个闰秒何时发生的情况下不可避免)


    使用strptime()解析字符串:

    1
    2
    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')

    这将把给定的时间字符串解析为本地时间(将夏令时(DST)设置为自动),结果是时间结构。这些仍然反映DST是显式关闭(0)、打开(1)还是隐式自动(-1)。将这些转换为浮点(1970-01-01之后的秒数):

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

    然后计算差异(秒):

    1
    d = b - a

    并将其转换为天/小时/分钟/秒:

    1
    2
    3
    4
    days = int(d) / 86400
    hours = int(d) / 3600 % 24
    minutes = int(d) / 60 % 60
    seconds = int(d) % 60

    最后一个块只适用于正差异,因此注意不要交换ab;-)

    但是@j.f.sebastian正确地指出,这可能不是你想要的。从符号来看,字符串描述的是UTC时间,而不是本地时间。对于纯粹的时间差异,这是相关的情况下,您的时间跨度超过了DST开关。在这种情况下,当然会导致一个小时的时差太大或一个小时太小(因为UTC总是没有DST)。

    为了避免这种情况,您可以将DST标志从自动(-1)设置为固定值(例如,0表示关闭),并使用这些值:

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

    或者,正如@j.f.sebastian指出的那样,您可以忘记time模块,而是使用datetime.datetime模块,它不知道DST方面:

    1
    2
    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这样的东西,这很可能正是你想要的。


    1
    2
    3
    4
    5
    6
    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)

    这里是原始答案