【问题标题】:Forcing Java 8 LocalTime toString to report omitted values强制 Java 8 LocalTime toString 报告省略的值
【发布时间】:2018-10-04 09:38:40
【问题描述】:

我有以下日期时间助手方法,可将 UTC 分区的 Java 8 Date 转换为日期时间字符串:

public static String dateTimeString(Date date) {
    return date.toInstant().atZone(ZoneId.of("UTC")).toLocalDateTime().toString();
}

期望的结果是总是将结果字符串格式化为:

YYYY-MM-dd'T'HH:mm:ss'Z'

问题是,Java 8 LocalTime#toString() 有意去除了零的时间分量。例如,如果我有一个代表 2018 年 6 月 8 日 12:35:00 UTCDate 实例。那么上面这个方法的输出就是:2018-06-08'T'12:35'Z'。而我希望它包含任何归零的秒/分钟/小时组件(例如 2018-06-08'T'12:35:00'Z')。

有什么想法吗?

【问题讨论】:

  • 显然,您可以创建自己的 DateTimeFormat 来格式化它,除非没有遗漏。我没有别的想法。
  • 我会接受@DreamspacePresident (+1) 作为解决方案——关于该代码的外观有什么想法吗?
  • 感谢@OleV.V。 (+1) 但是,该问题的公认答案使用DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSS"),它不是 UTC 分区的。
  • 好的,hotmeatballsoup,我用代码作为答案发布了它。

标签: java-8 tostring localtime


【解决方案1】:
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");

public static String dateTimeString(Date date) {
    return date.toInstant().atOffset(ZoneOffset.UTC).format(formatter);
}

只需使用固定格式的模式字符串即可获得所需的格式。让我们试试吧:

    System.out.println(dateTimeString(new Date(0)));
    System.out.println(dateTimeString(new Date(1_524_560_255_555L)));

打印出来:

1970-01-01T00:00:00Z
2018-04-24T08:57:35Z
  • 在第一个示例中,小时、分钟和秒被打印,即使它们是 0。
  • 在第二个示例中,毫秒被省略,即使它们不为零(您会看到我指定的毫秒值以 555 结尾)。

综上所述,无论您有2018-06-08T12:35Z2018-06-08T12:35:00Z 还是2018-06-08T12:35:00.000000000Z,输出都符合ISO 8601 格式。因此,在您费心定义自己的格式化程序之前,您可能需要再次检查是否可以为您的目的省略第二个。

链接: Wikipedia article: ISO 8601

【讨论】:

    【解决方案2】:

    我不明白为什么当 Java 的实际输出看起来像 2018-06-08T12:35Z 时,您将默认输出描绘成用单引号括起来的字母,但无论如何,这是代码根据需要生成它,没有遗漏:

    final LocalDateTime ldt = LocalDateTime.of(2018, 6, 8, 12, 35, 0);
    
    final ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.of("Z"));
    
    final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'''T'''HH:mm:ss''X''", Locale.US);
    
    System.err.println(dtf.format(zdt));
    

    输出:

    2018-06-08'T'12:35:00'Z'
    

    就个人而言,我可能更喜欢这样的格式,包含毫秒,提供不需要用户额外知识的时区信息,并且没有多余的字符:

    FORMAT: "yyyy-MM-dd HH:mm:ss'.'SSS Z"
    
    OUTPUT: 2018-06-08 12:35:12.345 +0200
    

    【讨论】:

    • 感谢@Dreamspace 总裁 (+1)!我如何/在哪里可以将其格式化为 UTC 分区?
    • 我能做的最好是 GMT:将第 3 行的 4 行代码中的 X 替换为 OOOO,这会改变从 ZGMT 的输出。 JavaDocs 说“GMT+8; GMT+08:00; UTC-08:00”,但我无法用它来表示 UTC,它总是说 GMT。
    【解决方案3】:

    似乎没有现成的解决方案。最简单的方法是编写您自己的扩展DateTimeFormatter 并覆盖方法public String format(TemporalAccessor temporal) 的类,您将在其中调用原始方法,然后在需要时修改输出字符串。有关格式化程序,请参见标志“Z”。如果该标志存在,那么您将需要修改原始输出。

    【讨论】:

    • DateTimeFormatterclass 是最终的,你不能扩展(子类)它。也只是定义自己的格式模式字符串似乎更简单。
    • @Ole V.V. - 你是对的,我错过了。然后您可以拥有自己的包含 DateTimeFormatter 类的类,即包装类。您可以编写 DateTimeFormatter 的所有方法并将它们委托给原始方法,除了 public String format(TemporalAccessor temporal) 您需要根据需要对原始结果进行修改。更多的工作,但它会做
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 2016-09-04
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多