如何自定义格式化 FileTime

How to custom format a FileTime

给定一个 FileTime fileTime,如何以自定义方式将其格式化为字符串?

String s = fileTime.toString() 仅提供 ISO 格式。

String s = DateTimeFormatter.ofPattern("uuuu-MMM-dd HH:mm:ss")
                              .format(fileTime.toInstant());

抛出 UnsupportedTemporalTypeException: Unsupported field: Year

您不能使用查询年份的 DateTimeFormatter 实例格式化 Instant。

一个Instant代表时间线上的一个点。这就是为什么无法对 "what's the year/day/time?" 问题给出 correct/unique 答案的原因。这取决于问题是在世界的哪个地方被问到的:在纽约,它不同于悉尼。 但是您的 DateTimeFormatter 正是在问这个问题。这就是为什么你得到 UnsupportedTemporalTypeException.

您必须至少将 Instance 转换为 LocalDateTime

System.out.println(timestampFormatter.format(
    LocalDateTime.ofInstant(fileTime.toInstant(), ZoneId.systemDefault()));

如果你的时间是这样的

2015-01-01T10:10:09

使用

yyyy-MM-dd'T'HH:mm:ss

格式化 Instant 需要时区。这可以使用 withZone(ZoneId):

来实现
String s = DateTimeFormatter.ofPattern("uuuu-MMM-dd HH:mm:ss")
                 .withZone(ZoneId.systemDefault())
                 .format(fileTime.toInstant());

我个人认为错误消息 "Unsupported field: Year" 具有误导性。 真正的原因是缺少时区。需要此信息来帮助格式化程序在内部将给定的瞬间转换为人类时间表示。 解决方案:提供时区。 然后支持格式化或解析 Instant - 与@flo 的答案相反。

正在打印:

String s = 
  DateTimeFormatter.ofPattern("uuuu-MMM-dd HH:mm:ss", Locale.ENGLISH)
    .withZone(ZoneId.systemDefault())
    .format(Instant.now());
System.out.println(s); // 2015-Oct-30 15:22:32

正在解析:

相反的过程——解析——不幸的是不能以同样的直接方式工作,因为 java.time 的格式化引擎被设计成格式化程序只有 returns 一个原始的 TemporalAccessor 需要转换为真正需要的类型。示例:

Instant instant =
  Instant.from(
    DateTimeFormatter.ofPattern("uuuu-MMM-dd HH:mm:ss", Locale.ENGLISH)
    .withZone(ZoneId.systemDefault())
    .parse("2015-Oct-30 15:22:32"));
System.out.println("=>" + instant); // 2015-10-30T14:22:32Z

如果要解析的输入包含时区偏移或标识符,那么您可以修改模式(符号 x、X、z、Z、VV 等)并省略对 withZone(...) 的调用,并且在偏移量的情况下 - 你真的应该省略那个调用,否则格式化程序不会使用你输入的时区偏移量,而是使用提供的一个区域(我在自己的测试中观察到的一个陷阱)。

ZonedDateTime 可以解析您从 FileTime.toString() 获得的默认字符串: (在下面的代码片段中提供您自己的 'path')

FileTime fileTime = Files.getLastModifiedTime(path);
ZonedDateTime zonedDateTime = ZonedDateTime.parse(fileTime.toString());
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEEE, MMMM d, yyyy   HH:mm:ss");   
System.out.println(dtf.format(zonedDateTime));

结果:2020 年 4 月 18 日,星期六 13:43:29