强制Java 8 LocalTime toString报告省略的值

时间:2018-04-24 08:01:47

标签: java-8 tostring localtime

我有以下日期时间辅助方法,它将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() 故意剥离零时间组件。例如,如果我有一个Date实例代表 2018年6月8日12:35:00 UTC 。然后上面这个方法的输出是: 2018-06-08'T'12:35'Z'。而我希望它包含任何清零的秒/分钟/小时组件(例如 2018-06-08'T'12:35:00'Z')。

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

当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

答案 2 :(得分:0)

似乎没有开箱即用的解决方案。最简单的方法是编写自己的扩展DateTimeFormatter的类并覆盖方法public String format(TemporalAccessor temporal),您可以在其中调用原始方法,然后根据需要修改输出String。看到旗帜' Z'格式化程序。如果存在该标志,则需要修改原始输出。