What's an epoch?

An epoch is a point in time, marked as the origin of time for a given time format, and is usually used as a reference point to track movement through time. While we'll omit any philosophical discussion associated with measuring time, we'll use and reference an epoch as the starting point for a given time format in this chapter.

There're two major epoch times associated with most timestamps: 1970-01-01 00:00:00 and 1601-01-01 00:00:00. The first, starting in 1970, is traditionally referred to as POSIX time as it's a common timestamp in Unix and Unix-like systems. In most Unix systems, timestamps are measured as seconds elapsed since POSIX time. This carries over to some applications as well, and variations exist that use milliseconds since the same epoch.

The second noted epoch, based in 1601, is commonly found on Windows-based systems and is used because it was the start of the first 400-year cycle of the Gregorian calendar to include leap years. The 400-year cycle starting in 1601 is the first cycle where digital files existed, and so this value became another common epoch. It's common to see Windows system timestamps as a count of 100-nanosecond segments since that epoch. This value will often be stored in hex or as an integer.

The next code block describes the process used to convert timestamps of different epochs. As we've seen in previous chapters, we can use the datetime module's fromtimestamp() method to convert Unix timestamps because it uses the 1970 epoch. For 1601-based timestamps, we'll need to convert them before using the fromtimestamp() function.

To make this conversion easier, let's calculate the constant between these dates and use that constant to convert between the two epochs. On the first line, we import the datetime library. Next, we subtract the two timestamps to determine the time delta between 1970-01-01 and 1601-01-01. This statement produces a datetime.timedelta object, which stores the difference in time as a count of days, seconds, and microseconds between the two values.

In this instance, the difference between the 1970 and 1601 timestamps is exactly 134,774 days. We need to convert this into a microsecond timestamp to be able to accurately leverage it in our conversions. Therefore, in the third line, we convert the count of days (time_diff.days) into microseconds by multiplying it by 86400000000 (the product of 24 hours x 60 minutes x 60 seconds x 1,000,000 microseconds) and print the constant value of 11644473600000000. Take a look at the following code:

>>> import datetime
>>> time_diff = datetime.datetime(1970,1,1) - datetime.datetime(1601,1,1)
>>> print (time_diff.days * 86400000000)
11644473600000000

With this value, we can convert timestamps between both epochs and properly ingest 1601-based epoch timestamps.