3

I'm really hoping you can help me with this. I have a date outputted by a python program that I need to be able to access in another program.

The problem is that I have no idea how this date is formatted:

Format               Date
129893779638930000 - 2012-08-13 17:32:43

It is both date and time, and I'm really hoping somebody recognizes what format it is in, as I don't know python very well. Bonus points if you can show me how to convert it to a unix timestamp.

EDIT: The program that does this is a component for Foobar2000 (an extension for a music program). The component is shown here: http://www.foobar2000.org/components/view/foo_playcount, and it is the XML export feature that generates the odd date/timestamp.

Jess
  • 8,628
  • 6
  • 49
  • 67
  • Do you mean that 129893678626216000 should decode to 2012-08-13 14:44:22, and you’re trying to find the decoding algorithm? – Vasiliy Faronov Aug 14 '12 at 07:08
  • Yes, exactly, which is why I know it isn't a variant of the unix timestamp. – Jess Aug 14 '12 at 07:10
  • Do you have the source code for the program that outputs it? If not, can you at least hint at what that program is? I don’t know but this could be a domain-specific convention or something. – Vasiliy Faronov Aug 14 '12 at 07:14
  • Definitely, sorry I didn't think it would be helpful as it is a compiled dll, but again I don't know much about python, it might be decompilable. It's a component to Foobar2000 - http://www.foobar2000.org/components/view/foo_playcount. The XML export is what uses the odd encoding of date/timestamps – Jess Aug 14 '12 at 07:16
  • Another thing, it says somewhere it uses a 64 bit file time "A file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC)", but I have no clue what that is (not a python guy) – Jess Aug 14 '12 at 07:20
  • related: [Convert Windows Filetime to second in Unix/Linux](http://stackoverflow.com/q/6161776/4279) – jfs Aug 14 '12 at 08:22

3 Answers3

11

129893678626216000 looks like the unix timestamp in 1e-8 seconds (tens of nanoseconds): 1,298,936,786.262,160,00. It would represent:

>>> from datetime import datetime
>>> datetime.utcfromtimestamp(129893678626216000/1e8)
datetime.datetime(2011, 2, 28, 23, 46, 26, 262160)

EDIT: However your information "A file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC)" tells me to use:

>>> from datetime import datetime, timedelta
>>> datetime(1601, 1, 1, 0, 0, 0) + timedelta(seconds = 129893678626216000/1e7)
datetime.datetime(2012, 8, 13, 21, 44, 22, 621599)

where you get exactly what you awaited.

You can also convert it directly to unix timestamp (number of seconds since 1970-01-01 00:00:00 UTC):

>>> 129893678626216000 / 1e7 - 11644473600
1344894262.6215992
eumiro
  • 207,213
  • 34
  • 299
  • 261
2

It seems like Windows file time:

A file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC). The system records file times when applications create, access, and write to files. The NTFS file system stores time values in UTC format, so they are not affected by changes in time zone or daylight saving time. The FAT file system stores time values based on the local time of the computer. For example, a file that is saved at 3:00pm PST in Washington is seen as 6:00pm EST in New York on an NTFS volume, but it is seen as 3:00pm EST in New York on a FAT volume.

See also FILETIME Structure.

The important bit is that the time might be both in UTC and local timezone. If there might be FAT filesystem; check whether the plugin reads the filetimes directly from disk without any transformations to find out whether you need take into account local timezone.

For UTC case (adapting C++ answer):

WINDOWS_TICK_INTERVAL  = 100e-9 # 100 nanoseconds intervals
SEC_TO_UNIX_EPOCH = (datetime(1970, 1, 1) - datetime(1601, 1, 1)).total_seconds()
# -> 11644473600

def WindowsTickToUnixSeconds(windowsTicks):
    return windowsTicks * WINDOWS_TICK_INTERVAL - SEC_TO_UNIX_EPOCH

To convert it to datetime object:

from datetime import datetime

filetime = 129893779638930000
dt = datetime.utcfromtimestamp(WindowsTickToUnixSeconds(filetime))
print(dt.strftime("%Y-%m-%d %H:%M:%S.%f-00:00"))
# -> 2012-08-14 00:32:43.893000-00:00

It seems correspond to the time in your question: 2012-08-13 17:32:43-07:00 (maybe PDT).

To handle DST for filetimes in local timezone (from FAT) from the past you might need pytz library.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
1

All is happy with the world, a filetime is like a unix timestamp but measured from 12:00 A.M. January 1, 1601, so subtracting the right amount of seconds and dividing to seconds gives you a unix timestamp, try this: (FILETIME - 116444736000000000) / 10000000

Jess
  • 8,628
  • 6
  • 49
  • 67