Skip to content

WinBase.FILETIME toLong() method switches units and epochs #546

@dbwiddis

Description

@dbwiddis

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;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions