6

Are there any Java libraries around for dealing with the win32 FILETIME/ time intervals ? It's basically a 64 bit timestamp in 100ns intervals since January 1, 1601.

(For my particular needs, converting to/from java.util.Date or an appropriate joda time equivalent would do, although I'll need access to at least microsecond resolution - which neither seems to provide.)

Lyke
  • 4,575
  • 6
  • 27
  • 26
  • Why exactly do you need that high resolution? – Thomas Mar 22 '11 at 22:25
  • have you looked at http://stackoverflow.com/questions/1712205/current-time-in-microseconds-in-java ? – Mat Mar 22 '11 at 22:28
  • Standard computer clocks can't even manage millisecond accuracy, never mind microsecond. Sounds like a classic case of precision over accuracy. – skaffman Mar 22 '11 at 22:30
  • 1
    @Thomas The timestamps are done in hardware, on E1/T1 cards whose clocks are locked to a reference signal which according to ITU G.811 needs an accuracy of 1x10 E-11 sec. (i.e. we don't get these timestamps from an unpredicatble OS call) – Lyke Mar 23 '11 at 16:47

3 Answers3

8

If you are fine with millisecond resolution, this would work:

/** Difference between Filetime epoch and Unix epoch (in ms). */
private static final long FILETIME_EPOCH_DIFF = 11644473600000L;

/** One millisecond expressed in units of 100s of nanoseconds. */
private static final long FILETIME_ONE_MILLISECOND = 10 * 1000;

public static long filetimeToMillis(final long filetime) {
    return (filetime / FILETIME_ONE_MILLISECOND) - FILETIME_EPOCH_DIFF;
}

public static long millisToFiletime(final long millis) {
    return (millis + FILETIME_EPOCH_DIFF) * FILETIME_ONE_MILLISECOND;
}

At this point, converting from ms to a Date object is quite straightforward.

Niraj Tolia
  • 541
  • 5
  • 5
2

Here's a Java 8+ java.time based solution that keeps 100-nanosecond precision:

public static final Instant ZERO = Instant.parse("1601-01-01T00:00:00Z");

public static long fromInstant(Instant instant) {
    Duration duration = Duration.between(ZERO, instant);
    return duration.getSeconds() * 10_000_000 + duration.getNano() / 100;
}

public static Instant toInstant(long fileTime) {
    Duration duration = Duration.of(fileTime / 10, ChronoUnit.MICROS).plus(fileTime % 10 * 100, ChronoUnit.NANOS);
    return ZERO.plus(duration);
}
Marco
  • 5,555
  • 2
  • 17
  • 23
0

Last time I solved this using JNI... (Although not on Windows, this was unix)

That is, a piece of C++ code that called the native OS functions, and then called that code using Java Native Interface.

A bit clunky, but it was the only way I could find (Also needed the i-node).

EDIT: Assuming the values are already obtained from some other source, Date4J can handle seconds with 9 decimals, but it is not as feature rich as Joda.

MarcB
  • 549
  • 6
  • 14
  • Looks like the OP doesn't need to fetch a native windows timestamp, but rather just deal with values representing a win32 timestamp – nos Mar 23 '11 at 17:47
  • But assuming he has one and just want to manipulate it, Joda does not have microsecond resolution. Date4J has up to 9 decimal places resolution though (on seconds). But its not as feature rich as Joda. – MarcB Mar 23 '11 at 19:49
  • Well, I parse the timestamp from (ASN.1/DER encoded) files simply. They're just a 64 bit number. I'll take a look at Date4j. – Lyke Mar 23 '11 at 21:16