【问题标题】:How to handle date with and without zone如何处理带和不带区域的日期
【发布时间】:2019-09-23 08:15:56
【问题描述】:

我的客户以 ISO8601 格式向我发送日期,其中有时包含带区域的毫秒,有时不包含毫秒和区域。

例如:2019-05-01T06:55:43+01:00, 2019-05-01T06:55

我正在使用新的 Java 8 API(LocalDateTimeDateTimeFormatter 等)。

我没有找到带有格式化程序的Date 类,它可以同时处理毫秒和区域,而没有这个。

我正在尝试使用单一格式进行输入日期验证

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(templateFormat, locale);


    try {
        ldt = LocalDateTime.parse(context, formatter );
        String result = ldt.format(formatter);
        return result.equals(context);
    } catch (DateTimeParseException e) {
        try {
            LocalDate ld = LocalDate.parse(context, formatter );
            String result = ld.format(formatter);
            return result.equals(context);

我在问是否有一个格式化器可以同时缓存两者,我可以使用多个日期类,如果我失败继续下一个,例如(LocalDateTime、LocalDate、OffsetDateTime)但我需要使用一个格式化器

【问题讨论】:

  • 你想如何处理每一个?我的意思是因为它们不包含相同的信息。
  • 这很相似,但不一样:How to parse different ISO date/time formats with Jackson and java.time?(不处理没有任何 UTC 偏移量的格式,只处理该 UTC 偏移量的不同格式)。
  • 这是您第一次输入时的 UTC 偏移量,而不是区域。时区有一个名称,例如Africa/Casablanca,而不仅仅是小时-分钟-秒数。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。
  • 不过,你仍然让我感到困惑。我现在明白这是为了验证,但您对有效或无效日期时间字符串的准确标准是什么?

标签: java date


【解决方案1】:

不同的类型

作为 Ole V.V.评论,您的意见:

  • 2019-05-01T06:55:43+01:00
  • 2019-05-01T06:55

……是两种不同的动物。

第一个代表一个时刻,时间轴上的一个特定点。该值包括三条信息:

  • 日期
  • 一天中的时间
  • 从 UTC 偏移

第二个输入只有日期和时间。它缺少time zoneoffset-from-UTC 的上下文。所以这个值确实代表片刻。它不是时间线上的一个点。该值代表大约 26-27 小时范围内的潜在时刻,即全球时区范围。第二个是指东京的早上 6 点吗?还是巴黎,当早上 6 点出现在几个小时后?或者在早上 6 点到达魁北克时再过几个小时?

因此,如果数据源向您提供这些值的任意组合,您的数据源就会混淆或损坏。我建议咨询该数据的发布者以确定他们的意图,并可能教育他们了解含义的差异。

解析

例如:2019-05-01T06:55:43+01:00, 2019-05-01T06:55

回答您的具体问题:

DateTimeParseException 的陷阱。如果在解析一个类时抛出,请尝试与其他类一起解析。

两个输入都是标准的ISO 8601 格式。 java.time 类在解析/生成字符串时默认使用标准格式。因此无需指定格式模式。

try {
    OffsetDateTime odt = OffsetDateTime.parse( input ) ;
    …
} catch ( DateTimeParseException e ) {
    LocalDateTime ldt = LocalDateTime.parse( input ) ;
    …
}

【讨论】:

  • “我建议咨询该数据的发布者以确定他们的意图,并可能教育他们了解意义的差异。” – 很好的建议。实际上是客户端坏了,所以他们需要修复这个问题。
  • 如果我想提供格式化程序,格式化程序应该是什么。我正在获取日期,解析日期并使用格式使用反向函数,然后检查相等性。我这样做是为了输入日期验证
  • 谢谢,你能看到我在我的问题中添加了什么吗?我正在尝试使用单个格式化程序进行输入日期验证
  • @user1116404 正如我在 Answer 的示例代码中所示,验证这些输入的方法是捕获 DateTimeParseException。如果您尝试解析为这两种类型并且仍然得到异常,那么您知道您的输入有误。尝试使用单个格式化程序是没有意义的,因为您有两个不同的输出:一个是片刻,另一个不是。显然你还没有理解我的答案中的教训。我建议你花点时间阅读课程文档、Oracle 日期时间教程,并搜索 Stack Overflow。
  • 我得到了你的答案,我的问题是是否有 ia 格式化程序可以捕获其中一个,可能是具有可选模式的格式化程序,这意味着格式化程序表明我们可能会获取此数据但它不是必须得到这个,例如,格式化程序告诉我们可能会得到毫秒
猜你喜欢
  • 1970-01-01
  • 2018-07-02
  • 2021-03-24
  • 1970-01-01
  • 2018-07-05
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多