强制 Java 8 LocalTime toString 报告遗漏值
Forcing Java 8 LocalTime toString to report omitted values
我有以下日期时间辅助方法,可将 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'。而我希望它包含任何清零的 second/minute/hour 组件(例如 2018-06-08'T'12:35:00'Z').
有什么想法吗?
似乎没有开箱即用的解决方案。最简单的方法是编写自己的 class 扩展 DateTimeFormatter 并重写方法 public String format(TemporalAccessor temporal)
,您将在其中调用原始方法,然后在需要时修改输出字符串。请参阅格式化程序的标志 'Z'。如果存在该标志,那么您将需要修改原始输出。
我不明白为什么 Java 的实际输出看起来像 2018-06-08T12:35Z[ 时,你为什么将默认输出描述为将其字母括在单引号中=20=],但无论如何,这里是按需生成它的代码,没有遗漏:
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
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 也会打印。
- 在第二个示例中,milliseoncds 被省略了,即使它们不为零(您看到我指定的毫秒值以 555 结尾)。
综上所述,无论您有 2018-06-08T12:35Z
、2018-06-08T12:35:00Z
甚至 2018-06-08T12:35:00.000000000Z
,输出都符合 ISO 8601 格式。因此,在麻烦定义自己的格式化程序之前,您可能需要再次检查是否出于您的目的而遗漏了第二个作品。
我有以下日期时间辅助方法,可将 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'。而我希望它包含任何清零的 second/minute/hour 组件(例如 2018-06-08'T'12:35:00'Z').
有什么想法吗?
似乎没有开箱即用的解决方案。最简单的方法是编写自己的 class 扩展 DateTimeFormatter 并重写方法 public String format(TemporalAccessor temporal)
,您将在其中调用原始方法,然后在需要时修改输出字符串。请参阅格式化程序的标志 'Z'。如果存在该标志,那么您将需要修改原始输出。
我不明白为什么 Java 的实际输出看起来像 2018-06-08T12:35Z[ 时,你为什么将默认输出描述为将其字母括在单引号中=20=],但无论如何,这里是按需生成它的代码,没有遗漏:
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
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 也会打印。
- 在第二个示例中,milliseoncds 被省略了,即使它们不为零(您看到我指定的毫秒值以 555 结尾)。
综上所述,无论您有 2018-06-08T12:35Z
、2018-06-08T12:35:00Z
甚至 2018-06-08T12:35:00.000000000Z
,输出都符合 ISO 8601 格式。因此,在麻烦定义自己的格式化程序之前,您可能需要再次检查是否出于您的目的而遗漏了第二个作品。