【问题标题】:How does Git parse date string?Git如何解析日期字符串?
【发布时间】:2020-07-26 08:47:57
【问题描述】:

我有一个来自 Joda DateTime.toString 的日期字符串,如下所示:

2020-04-03T12:43:55.019-04:00"

如果我这样做

git commit --date="2020-04-03T12:43:55.019-04:00”

然后git log 查看日期,它返回Sun Apr 19 12:43:55 2020 -0400,这在日期部分似乎是错误的。

但如果我将时区从 04:00 稍微更改为 05:00,Git 似乎可以很好地解析日期:

git commit --date="2020-04-03T12:43:55.019-05:00”

当我运行git log 命令时会给我正确的日期时间:Fri Apr 3 12:43:55 2020 -0500

第一次约会有什么问题?为什么 Git 认为是 4 月 19 日而不是 4 月 3 日?

【问题讨论】:

    标签: git date time jodatime


    【解决方案1】:

    我认为你发现了一个错误。

    git-commit 声称它理解这些格式,但它试图理解更多。

       The GIT_AUTHOR_DATE, GIT_COMMITTER_DATE environment variables and the --date option
       support the following date formats:
    
       Git internal format
           It is <unix timestamp> <time zone offset>, where <unix timestamp> is the number
           of seconds since the UNIX epoch.  <time zone offset> is a positive or negative
           offset from UTC. For example CET (which is 1 hour ahead of UTC) is +0100.
    
       RFC 2822
           The standard email format as described by RFC 2822, for example Thu, 07 Apr
           2005 22:13:13 +0200.
    
       ISO 8601
           Time and date specified by the ISO 8601 standard, for example
           2005-04-07T22:13:13. The parser accepts a space instead of the T character as
           well.
    
               Note
               In addition, the date part is accepted in the following formats:
               YYYY.MM.DD, MM/DD/YYYY and DD.MM.YYYY.
    

    2020-04-03T12:43:55.019-04:00 是完全有效的ISO 8601 datetime,格式为 YYYY-MM-DDThh:mm:ss.sss±hh:mm。它应该工作。例如,这里是 Ruby on Rails。

    [1] pry(main)> Time.parse("2020-04-03T12:43:55.21-04:00")
    => 2020-04-03 12:43:55 -0400
    

    Git 似乎混淆了小数秒并将它们用作月日。是的,似乎还有一些关于 -04:00 时区的问题。

    • git commit --date='2020-04-03T12:43:55.021-04:00' -> Tue Apr 21 12:43:55 2020 -0700(带小数秒,0400 偏移,不正确)
    • git commit --date='2020-04-03T12:43:55-04:00' -> Fri Apr 3 12:43:55 2020 -0400(无小数秒,0400 偏移量,正确)
    • git commit --date='2020-04-03T12:43:55.021-05:00' -> Fri Apr 3 12:43:55 2020 -0500(小数秒,0500 偏移量,正确)
    • git commit --date='2020-04-03T12:43:22.023-04:00' -> Thu Apr 23 12:43:22 2020 -0700(派系秒数,不正确)
    • git commit --date='2020-04-03T12:43:22.024-04:00' -> 2020 年 4 月 3 日星期五 12:43:22 -0400(正确)

    我的猜测是 Git 的临时解析将“21-04”读取为 4 月 21 日。例如。

    • git commit --date='12:43:22 23-04' -> 2020 年 4 月 23 日星期四 12:43:22 -0700

    为什么会在 4 月 23 日停播,我不知道。

    它可能会在 23 点停止,因为没有 24 小时。

    错误可能在match_multi_number in date.c

    【讨论】:

    • Git 不会以任何方式存储或处理小数秒,因此您不应将其传递给小数秒。它确实使用其(未记录的)近似代码处理各种格式,并且您遇到了将点解析为日期分隔符的情况。
    • @bk2204 Git 声称接受 ISO 8601,它应该接受并忽略小数秒;这使得将 ISO 时间戳传递到 Git 中变得更加容易,而无需先删除 Git 不使用的部分。虽然点会混淆它,但它似乎并没有将它作为日期分隔符来读取。 22.023 作为日期没有意义。
    • 欢迎您向列表发送错误报告或补丁。我只是告诉你它现在做了什么,如果你想让事情按现在的样子工作,你应该怎么做。
    • @bk2204 我会试一试,但是做我的税比the Git bug report and patching process 更简单。
    【解决方案2】:

    Git 似乎对小数秒感到困惑,并将它们用作月份

    Schwern 在其answer 中提到并解决的错误开始在 Git 2.27(2020 年第二季度)中得到修复,其中approxidate 解析器学习用分数解析秒

    commit 544ed96commit b784840commit 4f89f4f(2020 年 4 月 24 日)和commit c933b28(2020 年 4 月 23 日)Đoàn Trần Công Danh (``)
    (由 @987654329 中的 Junio C Hamano -- gitster -- 合并@,2020 年 5 月 5 日)

    date.c:跳过 ISO-8601 的第二部分小数

    报告人:Brian M. Carlson
    帮助人:Junio C Hamano
    签字人:Đoàn Trần Công丹

    git-commit(1) 说 ISO-8601 是我们支持的日期格式之一。

    ISO-8601 允许时间戳具有小数秒数。我们仅以整秒表示时间,因此我们从不费心解析小数秒。
    但是,我们最好解析并丢弃小数部分,而不是完全拒绝解析时间戳。

    并且拒绝解析小数秒部分可能会混淆解析在此示例中将小数和时区视为日期和月份:

    2008-02-14 20:30:45.019-04:00
    

    在执行此操作时,请确保仅当且仅当日期已知时,我们才将秒后的数字和点解释为小数,因为只有 ISO-8601 允许小数部分,而且我们已经教导我们的用户将“12:34:56.7.days.ago”解释为指定相对于当前时间的时间。

    【讨论】:

      【解决方案3】:

      它的解析是临时的,它当然可以更好地处理这个输入(或者只是拒绝它),但是你的时间是错误的。 TZ 偏移没有冒号。

      git commit --date=2020-04-03T12:43:55.019-0400    # <-- `-0400`, not `-04:00`.
      

      有效。

      编辑:我看到时间戳的 ISO 规则允许在 RFC 822 规则不允许的偏移量中使用 :,这可能是这里造成混淆的原因。

      不过,不知何故,我对此感到兴奋不已,无法制作补丁。

      【讨论】:

      • 感谢您的回复。我不明白的是,Git 似乎能够在 TZ 偏移量中使用 -05:00 解析日期时间字符串,但不能解析 -04:00(顺便说一句,通过调用 Joda DateTime.toString 是标准输出)。对我来说似乎很随机。
      • 是的,Git 运行在较旧的 RFC822 时区规则上,这可以说是现代世界的一个错误,但我希望它需要一个补丁,而不仅仅是一个报告,才能修复它.
      猜你喜欢
      • 2018-04-18
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      • 2011-07-21
      • 2013-08-22
      • 2012-05-05
      相关资源
      最近更新 更多