When I read the mtime
of a file from Java using Files.getLastModifiedTime
, the return value is truncated to whole seconds. I know this works on other systems to get mtimes with millisecond resolution, so what could be different about mine?
Here is a complete standalone test which compiles and runs:
import java.nio.file.attribute.FileTime;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Test {
public static void main(String[] args) throws java.io.IOException {
FileTime timestamp = Files.getLastModifiedTime(Paths.get("/tmp/test"));
System.out.println(timestamp.toMillis());
}
}
The output is (with my particular test file) 1405602038000
, whereas ls
shows:
$ ls --full-time /tmp/test
-rw-rw-r-- 1 daniel daniel 0 2014-07-17 16:00:38.413008992 +0300 /tmp/test
I would expect the Java output to be 1405602038413
.
I'm running on Linux with ext4. I tried both openjdk 1.7 and Oracle jdk 1.8.
The ability to get file timestamps on *nix systems with higher precision was added in Java 8 by this commit, however, on the native side, it requires POSIX 2008 compliance:
#if (_POSIX_C_SOURCE >= 200809L) || defined(__solaris__)
(*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->st_atim.tv_nsec);
(*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->st_mtim.tv_nsec);
(*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->st_ctim.tv_nsec);
#endif
And, apparently, the Java build you are using doesn't set it, so nanoseconds part of the timestamp is not available and stays zero.
I looked at the source code:
In the Java 7 case, the method gives the last modified timestamp with 1 second precision:
In the Java 8 case, it looks like it should give microsecond precision:
But in either case, the code doesn't seem to provide a way to get the timestamp with a different precision.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With