5

I need to convert filetime to datetime. I am using this code filetime.py, from here as mentioned in this thread Datetime to filetime (Python).

In the code

EPOCH_AS_FILETIME = 116444736000000000  # January 1, 1970 as MS file time
HUNDREDS_OF_NANOSECONDS = 10000000

def filetime_to_dt(ft):
    """Converts a Microsoft filetime number to a Python datetime. The new datetime object is time zone-naive but is equivalent to tzinfo=utc.

    >>> filetime_to_dt(116444736000000000)
    datetime.datetime(1970, 1, 1, 0, 0)
    """
    # Get seconds and remainder in terms of Unix epoch
    (s, ns100) = divmod(ft - EPOCH_AS_FILETIME, HUNDREDS_OF_NANOSECONDS)
    # Convert to datetime object
    dt = datetime.utcfromtimestamp(s)
    # Add remainder in as microseconds. Python 3.2 requires an integer
    dt = dt.replace(microsecond=(ns100 // 10))
    return dt

datetime.utcfromtimestamp does not take negative value on windows system, so I can't convert filetime before Jan 1st 1970. But I can convert dates before 1970 on Mac using the exact same code (reason here). Is there any workaround for windows?

Community
  • 1
  • 1
Echo
  • 667
  • 3
  • 8
  • 19

4 Answers4

3

By adding a timedelta to a reference date you can use any date formula you'd like. timedelta is allowed to be positive or negative.

def filetime_to_dt(ft):
    us = (ft - EPOCH_AS_FILETIME) // 10
    return datetime(1970, 1, 1) + timedelta(microseconds = us)
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
1

According to docs, you have to use:

dt = datetime.fromtimestamp(s, datetime.timezone.utc)

instead of:

dt = datetime.utcfromtimestamp(s)
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
Aaron
  • 10,133
  • 1
  • 24
  • 40
0

first you need to convert it to a recognizable filetime format like this:

>>> dwLowDateTime = 0x0F7297A80
>>> dwHighDateTime = 0x1C3F10F << 32
>>> ft = (dwLowDateTime & 0xFFFFFFFF) | dwHighDateTime
127210265370000000

and then use this script, it converts filetime to datetime and vice versa https://gist.github.com/Mostafa-Hamdy-Elgiar/9714475f1b3bc224ea063af81566d873

>>> filetime_to_dt(ft)
2004-02-12 02:28:57
Alya Gomaa
  • 63
  • 1
  • 5
0

Use timedeltas to add/subtract/divide between time frames:

FILE_TIME_EPOCH = datetime.datetime(1601, 1, 1)
FILE_TIME_MICROSECOND = 10 # FILETIME counts 100 nanoseconds intervals = 0.1 microseconds, so 10 of those are 1 microsecond

def convert_from_file_time(file_time):
    microseconds_since_file_time_epoch = file_time // FILE_TIME_MICROSECOND
    return FILE_TIME_EPOCH + datetime.timedelta(microseconds=microseconds_since_file_time_epoch)

And the other side of this is:

def convert_to_file_time(date_time):
    microseconds_since_file_time_epoch = (date_time - FILE_TIME_EPOCH) // datetime.timedelta(microseconds=1)
    return microseconds_since_file_time_epoch * FILE_TIME_MICROSECOND
assembly_wizard
  • 2,034
  • 1
  • 17
  • 10