Java:Files.getLastModifiedTime中的错误时区

3

我想要打印出文件的最后修改时间。不知何故,返回的时间戳不正确且与系统时间不同。

Files.getLastModifiedTime(Paths.get(directory, filename))

会输出2019-01-14T11:48:47.312493Z

实际上系统时间是:

LocalDateTime.now()  <- 2019-01-14T19:48:50.495242600

我该如何解决这个问题并使getLastModifiedTime返回本地时区的时间?

3
时间是正确的 - 你可以从最后一个字符Z看出来(顺便说一句,你可能复制粘贴时出错了,应该是大写的Z),时间处于"Zulu"时区——也就是UTC。而另一个时间则是你所在地的当地时间。 - Erwin Bolwidt
根据文档,“表示文件上次修改的时间,或者在文件系统不支持用于指示上次修改时间的时间戳时的实现特定默认值”。你的文件系统支持时间戳吗? - therealprashant
1
我的意思是我可以右键单击并查看文件的属性,看看最后修改时间是否已更改。我猜这意味着我的文件系统支持时间戳,对吗? - user1769197
2个回答

2
LocalDateTime是本地日期和时间,它依赖于机器上配置的时区,该机器可能运行在UTC+8。要获取无时区的日期时间(例如getLastModifiedTime()返回的),请使用Instant.now()而不是LocalDateTime.now()

或者您可以将通过getLastModifiedTime(...).toInstant()返回的Instant转换为本地日期时间:

Instant modified = Files
    .getLastModifiedTime(Paths.get(directory, filename))
    .toInstant();
LocalDateTime modifiedDateTime = modified
    .atZone(ZoneId.systemDefault())
    .toLocalDateTime();

其中ZoneId.systemDefault()是系统默认配置的时区。您也可以使用固定的时区,例如中国标准时间ZoneId.of("CST")。但我强烈建议尽可能使用Instant,因为这样您就不会意外比较来自不同时间戳的日期时间,并避免由代码运行环境不同引起的错误。


1
Files.getLastModifiedTime returns a FileTime object, not an Instant - Erwin Bolwidt
2
“这取决于机器配置的时区。”并非完全如此。LocalDateTime本身不依赖于任何时区。它表示一些本地日期和时间。在将其与偏移量或时区关联之前,它无法代表时间线上的任何点,但是该时区可以是任意定义的,并且无需是由机器配置的时区。 - scottb

2

看起来 FileTime#toString() 返回的日期时间字符串是以 UTC 为准的,这里是它的源代码片段:

ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);

您可以从FileTime获取Instant,然后使用系统时区将其转换为LocalDateTime

FileTime fileTime = Files.getLastModifiedTime(Paths.get(directory, filename));
LocalDateTime localDateTime = LocalDateTime.ofInstant(fileTime.toInstant(), ZoneId.systemDefault());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接