【问题标题】:Java datetime inconsistent between local application and Jenkins deployment本地应用程序和 Jenkins 部署之间的 Java 日期时间不一致
【发布时间】:2019-11-14 15:45:26
【问题描述】:

我在我的应用程序中收到一个日期时间作为字符串。在那里我需要提取小时,以便可以将它与其他一些东西一起写入文件。对于我的单元测试,字符串看起来像这样

2019-10-26T00:00:00+01:00

我用来提取小时的代码是这样的

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public static int extractHour(String dateInString) {
    DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ");
    DateTime dateTime = formatter.parseDateTime(dateInString);
    return dateTime.getHourOfDay();
}

我的测试在本地通过了预期的 00 小时和实际的 00 小时,但是当我通过 Jenkins 部署时,实际小时显示为 23,而我的预期是 00。

【问题讨论】:

  • 时区或偏移问题...您的本地系统的语言环境是什么?您的部署目标是什么?
  • 你必须在你的格式化程序中指定本地,我也建议使用java.time而不是joda
  • @YCF_L 在格式化程序中指定时区对我有用,如果你愿意,可以将其作为答案,我会接受
  • 很高兴听到这个消息,这是我身边的一个镜头:),我会让你发布答案,我会紫外线 :)

标签: java datetime parsing jenkins time


【解决方案1】:

如果您不以其他方式指示 Joda-Time,formatter.parseDateTime() 会在您的默认时区解析为 DateTime

因此,例如,如果您的本地时区设置为 Europe/Dublin 或 Europe/London,则解析结果将是 2019-10-26T00:00:00.000+01:00DateTime(因为 10 月 26 日是夏令时 (DST) 的最后一天)在那些时区),一天中的小时将是 0,如您所料。如果你的 Jenkins 服务器的时区设置是 UTC——这很常见——你的字符串在那里被解析为2019-10-25T23:00:00.000Z。显然,一天中的 23 小时。

如果您希望将字符串的偏移量保留在DateTime 中,解决方法是:

    DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ")
            .withOffsetParsed();

但是,请三思。一天中的小时仅相对于偏移量才有意义。在夏令时结束的晚上,您可能会收到2019-10-27T01:00:00+01:00 的字符串,一小时后,当时钟更改时,2019-10-27T01:00:00+00:00。两个字符串的时间都是 1,但它们之间有一个小时。你真的想要同样的结果吗?如果有一天你得到一串2020-02-16T00:00:00-05:00怎么办?

编辑:

你会建议什么而不是使用 withOffsetParsed()[?]

我首先建议你决定你想要的不同偏移量的字符串的结果,例如2020-03-06T18:00:00+05:302020-04-18T04:00:00-08:00。你应该比我更清楚。

通常推荐的跨偏移处理时间的做法是使用 UTC 处理所有内容。这可能是您已经找到并在评论中提到的解决方案的一个特例,在格式化程序上指定时区:

    DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ")
            .withZoneUTC();

这保证了一致的结果,显然与您在 Jenkins 服务器上获得的结果相同。所以在你的例子中是 23。

PS 如果这是新代码,您可能不应该使用 Joda-Time。 The Joda-Time homepage 说:

请注意,Joda-Time 被认为是一个基本“完成”的项目。 没有计划进行重大改进。如果使用 Java SE 8,请迁移 到java.time (JSR-310)。

【讨论】:

  • 你会建议什么而不是使用 withOffsetParsed()
猜你喜欢
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 2017-08-09
  • 1970-01-01
  • 2013-09-18
  • 2015-03-26
  • 2018-10-28
相关资源
最近更新 更多