The FILETIME structure contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC) (the Windows API epoch). This is represented in JNA's WinBase.FILETIME class.
WinBase.FILETIME.toDate() converts this value to a java.util.Date value. Then WinBase.FILETIME.toLong() simply reconverts this date to milliseconds since the Unix Epoch, January 1, 1970 (UTC), using java.util.Date.getTime().
This is problematic for several reasons:
- The conversion loses a factor of 10000, by converting 100-nanosecond intervals to milliseconds.
- The conversion switches epochs from 1601 to 1970, requiring the user to add a constant ((369L * 365L + 89L) * 86400L * 1000L = 11644473600000L, see
FILETIME.EPOCH_DIFF) to the returned value to properly reference the time to the Windows API.
- The
FILETIME.toLong() method is completely undocumented, so the user has no way short of experimentation (or reading the source code) to figure this out.
I'll be happy to submit a PR to fix this, given further direction on the desires of the developers. Options include one or more of:
- Leave code as-is, but document the conversion
- Expose the
EPOCH_DIFF constant to the API
- Add a new
toTime() method to correspond to java.ultil.Date's method, returning the existing value and documenting the epoch change
- Change the existing
toLong() method to take the exiting result, add EPOCH_DIFF, and multiply by 10000 in order to have the returned long value match the expected value per documentation. (Note: this would truncate the last 4 digits, and is probably inaccurate, but is what the dateToFileTime() method currently does, so at least it would be consistent.)
- Change the existing
toLong() method to properly calculate the 100-nanosecond intervals to have the returned long value match the expected value per documentation using (long) high << 32 | low & 0xffffffffL;
The FILETIME structure contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC) (the Windows API epoch). This is represented in JNA's WinBase.FILETIME class.
WinBase.FILETIME.toDate()converts this value to ajava.util.Datevalue. ThenWinBase.FILETIME.toLong()simply reconverts this date to milliseconds since the Unix Epoch, January 1, 1970 (UTC), using java.util.Date.getTime().This is problematic for several reasons:
FILETIME.EPOCH_DIFF) to the returned value to properly reference the time to the Windows API.FILETIME.toLong()method is completely undocumented, so the user has no way short of experimentation (or reading the source code) to figure this out.I'll be happy to submit a PR to fix this, given further direction on the desires of the developers. Options include one or more of:
EPOCH_DIFFconstant to the APItoTime()method to correspond tojava.ultil.Date's method, returning the existing value and documenting the epoch changetoLong()method to take the exiting result, add EPOCH_DIFF, and multiply by 10000 in order to have the returnedlongvalue match the expected value per documentation. (Note: this would truncate the last 4 digits, and is probably inaccurate, but is what thedateToFileTime()method currently does, so at least it would be consistent.)toLong()method to properly calculate the 100-nanosecond intervals to have the returnedlongvalue match the expected value per documentation using(long) high << 32 | low & 0xffffffffL;