A Hundred Million TimeStamps
Ian Whiffin
Posted: 27th Jan 2020

One of the earliest tools that I made to make my forensicating easier was a timestamp converter. Despite there being a good number of great tools out there, I decided that writing my own tool would be a good way to learn more about the various timestamps that different systems use ranging from familiar timestamps such as UNIX and MAC Absolute to the somewhat more obscure like GPS Time.

As I coded it, I started to add more and more features that eventually made it my timestamp tool of choice. Features such as Auto-Detecting a timestamp type, respecting timezone offsets, reversing timestamps and calculating time differences (including a feature that allowed timestamp corrections to be made on incorrect clocks such as you may find on a DVR).

I've been trying to get around to rewriting this tool for a while now to refine it from it's initial state. It is now what I believe to be one of the most useful standalone time conversion tools available. It's not got the entire range of features that the earlier version had yet but those features will be added soon.

For now, I thought it would be nice to take a closer look at the different timestamps that Epoch works with. If you can think of an additional timestamps that I've missed, please contact me and I'll try to get it updated.

UNIX

Example : The current time in UNIX TimeStamp is 00000000.

Epoch Date 1st January 1970
Unit Seconds
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of seconds since midnight on 1st January 1970.
Put even more simply, a UNIX TimeStamp of 1 would be 00:00:01 on 1st January 1970. A UNIX TimeStamp of 60 would be 00:01:00 on 1st January 1970. And so on.

Convert your own UNIX TimeStamp here : =



UNIX MilliSecond

Example : The current time in UNIX MilliSecond TimeStamp is 00000000.

Epoch Date 1st January 1970
Unit MilliSeconds
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of milliseconds (thousandth of a second) since midnight on 1st January 1970.
Put even more simply, a UNIX Millisecond TimeStamp of 1 would be 00:00:00 on 1st January 1970. A UNIX Millisecond TimeStamp of 1000 would be 00:00:01 on 1st January 1970. And so on.

Convert your own UNIX MilliSecond TimeStamp here : =


 

UNIX 32bit (Hex)

The UNIX 32bit Hex Timestamp can be shown in either Big or Little Endian.

Example : The current time in UNIX 32bit Hex (Big Endian) TimeStamp is 00000000.
Example : The current time in UNIX 32bit Hex (Little Endian) TimeStamp is 00000000.

Epoch Date 1st January 1970
Unit Seconds
Expression Hex
TimeZone UTC

This timestamp is simply the UNIX time (seconds since midnight on 1st January 1970) expressed as Hex.

Convert your own UNIX (Big Endian) TimeStamp here : =

Convert your own UNIX (Little Endian) TimeStamp here : =


 

Apple MAC Absolute

Example : The current time in MAC Absolute TimeStamp is 00000000.
Example : The current time in MAC Absolute (NanoSeconds) TimeStamp is 00000000.

Epoch Date 1st January 2001
Unit Seconds or NanoSeconds
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of seconds since midnight on 1st January 2001.
Put even more simply, a MAC Absolute TimeStamp of 1 would be 00:00:01 on 1st January 2001. A MAC Absolute TimeStamp of 60 would be 00:01:00 on 1st January 2001.

This timestamp may also be expressed as a long number which is the number of nanoseconds since midnight on 1st January 2001.
Put even more simply, a MAC Absolute TimeStamp of 1 would be 00:00:01 on 1st January 2001. A MAC Absolute TimeStamp of 60 would be 00:01:00 on 1st January 2001.

Convert your own MAC Absolute TimeStamp here : =

Convert your own MAC Absolute (NanoSecond) TimeStamp here : =


 

Apple MAC HFS+

Example : The current time in MAC HFS+ TimeStamp is 00000000.

Epoch Date 1st January 1904
Unit Seconds
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of seconds since midnight on 1st January 1904.
Put even more simply, a MAC HFS+ TimeStamp of 1 would be 00:00:01 on 1st January 1904. A MAC HFS+ TimeStamp of 60 would be 00:01:00 on 1st January 1904

Convert your own MAC HFS+ TimeStamp here : =


 

Apple WebKit

Example : The current time in Apple Webkit TimeStamp is 00000000.

Epoch Date 1st January 2001
Unit Seconds
Expression Decimal
TimeZone UTC

This timestamp is expressed as a decimal number which is the number of seconds since midnight on 1st January 2001. However, this timestamp is shown with a decimal number that appears to do nothing.

I'm sure there is a valid reason for it and it may well be an important level of accuracy or uniqueness in some circumstances. But for real-world purposes, simply ignoring everything after the decimal seems perfectly fine.

Convert your own MAC Apple Webkit TimeStamp here : =



DOS FileTime

The DOS TimeStamp can be viewed in either Date/Time or Time/Date order. The method for calculating both is the same however.

Example : The current time in DOS (Date/Time)TimeStamp is 00000000.
Example : The current time in DOS (Time/Date) TimeStamp is 00000000.

Epoch Date N/A
Unit N/A
Expression Hex
TimeZone Local

Start by splitting the byte up into two nibbles. These represent the Date and Time (Or Time and Date).

In this example I will use the Date/Time format.

3050C57B
Date Time
3050 C57B

Next, the nibbles need to be switched around to read in the opposite endian.

3050C57B
Date Time
3050 C57B
5030 7BC5

Now convert the values into Binary

CA7B3050
50307BCA
Date Time
5030 7BC5
0101000000110000 0111101111000101

The Binary is then broken up into sections.

Note that only 5 bits are available to record the seconds. That would usually mean a maximum number of seconds of 31 (16 + 8 + 4 + 2 + 1). We obviously need more than that but there aren't enough bits available. The decision was made that accuracy to 2 seconds would be enough. That meant that you can assume that the least significant bit is always 0. So by adding a 0 to the right side, you end up with 6 bits.

Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6 Max Value
  1 1 1 1 1 31
1 1 1 1 1 0 62
Inserting the bit in red at the end shifts all bits to the left

 

CA7B3050
50307BCA
Date Time
5030 7BC5
0101000000110000 0111101111000101
Bits Value Description Bits Value Description
0-6 0101000 Year 0-4 01111 Hour
7-10 0001 Month 5-10 011110 Minute
11-15 10000 Day 11-15 001010 Second

Each Binary value is converted back into Decimal:

CA7B3050
50307BCA
Date Time
5030 7BCA
0101000000110000 0111101111001010
Bits Value   Description Bits Value   Description
0-6 0101000 40 Year 0-4 01111 15 Hour
7-10 0001 1 Month 5-10 011110 30 Minute
11-15 10000 16 Day 11-15 001010 10 Second

So you have the 16th January 40AD at 15:30:10... Oh wait... You may have realised that the year is a little off.

When this timestamp was created, they realized that seconds, minutes, hours, days and months are all finite, with top values of 60, 60, 24, 31 and 12 respectively. Years however presents an issue as they go on (hopefully) almost infinitely.

To combat this, the developers decided that 1980 would be a good place to start and so the YEAR value is added to 1980 in every case. In the example above, the year value is 40. Therefore, 1980 + 40 = 2020.

So the final date is 16th January 2020 at 15:30:10.

Note that these are always LOCAL TIME.

Convert your own DOS Date/Time TimeStamp here : =

Convert your own DOS Time/Date TimeStamp here : =


 

BlackBerry 7 Email

The BlackBerry 7 Email Timestamp is remarkably similar to the DOS FileTime with the exception of the year.

Example : The current time in BlackBerry 7 Email TimeStamp is 00000000.

Epoch Date N/A
Unit N/A
Expression Hex
TimeZone Local

Split the Byte up into two nibbles. These represent the Date and Time.

303748BD
Date Time
3037 48BD

Now convert the values into Binary

303748BD
Date Time
3037 48BD
0011000000110111 0100100010111101

The Binary is then broken up into sections.

303748BD
Date Time
3037 48BD
0011000000110111 0100100010111101
Bits Value Description Bits Value Description
0-6 0011000 Year 0-4 01001 Hour
7-10 0001 Month 5-10 000101 Minute
11-15 10111 Day 11-15 11101 Second

Each Binary value is converted back into Decimal:

Note that only 5 bits are available to record the seconds. That would usually mean a maximum number of seconds of 31 (16 + 8 + 4 + 2 + 1). We obviously need more than that but there aren't enough bits available. The decision was made that accuracy to 2 seconds would be enough. That meant that you can assume that the least significant bit is always 0. So by adding a 0 to the right side, you end up with 6 bits.

Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6 Max Value
  1 1 1 1 1 31
1 1 1 1 1 0 62
Inserting the bit in red at the end shifts all bits to the left

 

303748BD
Date Time
3037 48BD
0011000000110111 0100100010111101
Bits Value   Description Bits Value   Description
0-6 0011000 24 Year 0-4 01001 9 Hour
7-10 0001 1 Month 5-10 000101 5 Minute
11-15 10111 23 Day 11-15 111010 58 Second

The developers of this timestamp decided that 1996 would be a good place to start and so the YEAR value is added to 1996 in every case. In the example above, the year value is 24. Therefore, 1996 + 24 = 2020.

So the final date is 23rd January 2020 at 09:05:58.

Note that these are always LOCAL TIME.

Convert your own BlackBerry Email TimeStamp here : =



Windows 128bit

Example : The current time in Windows 128bit Hex (Big Endian) is 00000000.

Epoch Date N/A
Unit N/A
Expression Hex
TimeZone UTC

This timestamp is expressed as a 128bit hex number which breaks down into several parts.

Take the example time D9070B00010002000600090013000000.

First, it requires splitting into chunks of 2 bytes which must then be converted into decimal.

D9070B00010002000600090013000000
Split D907 0B00 0100 0200 0600 0900 1300 0000
Swapped 07D9 000B 0010 0002 0006 0009 0013 0000
Converted 2009 11 16 2 6 9 13 0

The Converted values are then;

D9070B00010002000600090013000000
Split D907 0B00 0100 0200 0600 0900 1300 0000
Swapped 07D9 000B 0001 0002 0006 0009 0013 0000
Converted 2009 11 1 2 6 9 13 0
Assignment Year Month Day Of Week Day Hr Min Sec MSec

Convert your own Windows 128bit TimeStamp here : =


 

Windows 64bit (Hex)

Windows 64bit Hex can be displayed in Big or Little Endian.

Example : The current time in Windows 64bit Hex (Big Endian) is 00000000.
Example : The current time in Windows 64bit Hex (Little Endian) is 00000000.

Epoch Date 1st January 1601
Unit Ticks
Expression Hex
TimeZone UTC

This timestamp is expressed as a hex number which is the number of ticks (one ten-millionth of a second) since midnight on 1st January 1601.

Convert your own Windows 64bit Hex (Big Endian) TimeStamp here : =

Convert your own Windows 64bit Hex (Big Endian) TimeStamp here : =


Google Chrome

Example : The current time in Google Chrome TimeStamp is 00000000.

Epoch Date 1st January 1601
Unit MicroSeconds
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of microseconds (one millionth of a second) since midnight on 1st January 1601.
Put even more simply, a Google Chrome TimeStamp of 1000000 would be 00:00:01 on 1st January 1601. A Google Chrome TimeStamp of 60000000 would be 00:01:00 on 1st January 1601

Convert your own Google Chrome TimeStamp here : =


FireFox

Example : The current time in FireFox TimeStamp is 00000000.

Epoch Date 1st January 1970
Unit MicroSeconds
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of microseconds (one millionth of a second) since midnight on 1st January 1970.

Convert your own FireFox TimeStamp here : =


 

Windows Ticks

Example : The current time in Windows Ticks is 00000000.

Epoch Date 1st January 0001
Unit Ticks
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of ticks (one ten-millionth of a second) since midnight on 1st January 0001.
Put even more simply, a Windows Tick of 10000000 would be 00:00:01 on 1st January 0001. A windows Tick of 600000000 would be 00:01:00 on 1st January 0001. And so on.

Convert your own UNIX TimeStamp here : =


 

Windows Cookie

Example : The current time in Windows Cookie Time is 00000000.

Epoch Date 1st January 1601
Unit Ticks
Expression Decimal
TimeZone UTC

This timestamp is displayed in two parts, separated by a comma.

Example : 481435648,30788937

Separate the two parts of the value and convert to hex.

481435648,30788937
481435648 30788937
1CB22000 1D5CD49

Now Swap the values around and combine them into one value before converting back to a decimal.

481435648,30788937
481435648 30788937
1CB22000 1D5CD49
1D5CD49 1CB22000
1D5CD491CB22000
132237477975040000

The resulting number is the number of Ticks (one ten-millionth of a second) since since midnight on the 1st January 1601.

1st January 1601 + 132237477975040000 Ticks = 2020/01/17 15:16:37

Convert your own Windows Cookie Time here : =



Microsoft OLE Automation (32bit)

Example : The current time in Microsoft OLE is 00000000.

Epoch Date 30th December 1899
Unit Days / Fraction of day
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of days (including fractions) since midnight on 30th December 1899.

Convert your own OLE (32bit)TimeStamp here : =


 

Microsoft OLE Automation (64 bit)

Example : The current time in Microsoft OLE (64bit) is 00000000.

Epoch Date 30th December 1899
Unit Days / Fractions of days
Expression Decimal
TimeZone UTC

This timestamp is expressed as a long number which is the number of days (including fractions) since midnight on 30th December 1899.
It is represented using the IEEE754 Floating Point Standard.

Original Hex BBD13DBF8B69E540
Swapped Endian 40E5698BBF3DD1BB
Float 43852.367094907408

Once you have the float, the decimal point is used to split the value. To the left of the decimal is the number of days since 30th December 1899. To the right of the decimal is the fraction of a day.
So 0 would be midnight, .25 would be 6AM, .5 would be 12PM and .75 would be 6PM.

Original Hex BBD13DBF8B69E540
Swapped Endian 40E5698BBF3DD1BB
Float 43852.367094907408
Split Float 43852 367094907408
  30th December 1899 + 43852 Days 36.7% of the day (1 day = 86400 seconds).
  Wed 22 Jan 2020

31700 seconds

  Wed 22 Jan 2020 08:48:36 (UTC 00:00)

Convert your own OLE(64bit) TimeStamp here : =


 

Hotmail Time

Example : The current time in Hotmail Time is 00000000.

Epoch Date 1st January 1601
Unit Ticks
Expression Decimal
TimeZone UTC

This timestamp is expressed in Hex as the number of ticks (one ten-millionth of a second) since midnight on 1st January 1601.

Split the value into two parts

6DCED501:803179C1
6DCED501 803179C1

Each part needs to switch endianess;

6DCED501:803179C1
6DCED501 803179C1
01D5CE6D C1793180

Join the two parts as one large hex value and convert it to decimal.

6DCED501:803179C1
6DCED501 803179C1
01D5CE6D C1793180
01D5CE6DC1793180
132238734870000000

The resulting value is the number of ticks.

So 1st January 1601 + 132238734870000000 Ticks = 19 JAN 2020 02:11:27

Convert your own Hotmail TimeStamp here : = <<<Not quite right


 

Semi-Octet

Example : The current time in Semi-Octet TimeStamp is 00000000.

Epoch Date N/A
Unit N/A
Expression Hex
TimeZone Local

This timestamp is displayed using 6 bytes; One for Year, Month, Day, Hour, Minute., Second..

Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7
Year Month Day Hour Minute Second TimeZone

To complicate matters a little, the nibbles aren't in the right order however. So where a nibble may show the value 91, you have to swap the nibbles around to get the value 19.

So the value 91 01 52 10 91 52 would be 19 10 25 01 19 25... Or 2019/10/25 01:19:52.

The Timezone offset is in 15 minute increments. So if byte 7 was 04 then the offset value would be 15mins * 4 = 1hour from UTC.

Note that the year is only shown as 2 digits. Based on the usage of this timestamp being primarily for things that occurred in the past or present (ie. sent messages) then I have made the presumption that the dates cannot be in the future and assigned the century appropriately.

Simply, if the 2 digit year on the timestamp if equal or less than the current year, then the current century is presumed. If the year in the timestamp is higher than the current year, then last century is presumed. This may not work in all cases so is something to be aware of when using this timestamp.

Convert your own Semi-Octet TimeStamp here : =


 

GPS Time

Example : The current time in GPS TimeStamp is 00000000.

Epoch Date 6th January 1980
Unit Seconds
Expression Decimal
TimeZone UTC

GPS Time is a the number of seconds since 6th Jan 1980.

What makes GPS Time unique is the inclusion of Leap Seconds; seconds that are occasionally added to compensate for the earth's uneven rotation.

Since 1980, only 18 Leap Seconds have ever been added. They have always been added one at a time at either the end of June or end of December.

It is important to note;

  • Leap Seconds can be added or removed dependent on if the earth's rotation called for it
  • Multiple seconds could be added/removed at a time if required.
  • Leap Seconds could be applied at any time of year, however historically they have always been added at the end of June or end of December.
  • The decision to implement a Leap Second is made by The International Earth Rotation and Reference Systems Service (IERS).
  • Leap Seconds are unrelated to Leap Years with the exception that both are methods to correct an imperfect time system.

A list of all Leap Second adjustments can be found on https://www.nist.gov/pml/time-and-frequency-division/atomic-standards/leap-second-and-ut1-utc-information

Convert your own GPS TimeStamp here : =


 

Kai OS Time

Example : The current time in Kai OS TimeStamp is 00000000.

Epoch Date 1st January 1970
Unit MilliSeconds
Expression Hex
TimeZone UTC

This timestamp is ultimately the number of milliseconds (one millionth of a second) since midnight on 1st January 1970.
However, the number is then represented by the IEEE 754 Floating Point standard.

Original Value 1C 30 AA D8 E7 F9 75 42
Swap Endianess 42 75 F9 E7 D8 AA 30 1C
Convert to Binary 01000010011110101111110011110011111011000101010100011000000011100
 

Sign : 0

Exponent : 10000100111

Significand : 0101111110011110011111011000101010100011000000011100

Decimal 1510192548515.0068
Date 1970/1/1 + 1510192548515.0068 = 2017/11/09 01:55:48 (UTC)

Convert your own Kai OS TimeStamp here : =

*The javascript for this feature was made possible by the sites http://www.tfinley.net and https://babbage.cs.qc.cuny.edu which is a great resources for more information about the IEEE754 standard.


 

Wrapping Up

Thank you for reading! I envisage this post being much more of a reference tool than an interesting read but hopefully you've found a few things that you find useful. I plan on adding to this list as time (pardon the pun) goes on.

If you find any errors/omissions in this article, please let me know. I wrote this article relatively quickly and wrote encoding/decoding tools in both C# and Javascript simultaneously. Every effort has been made to ensure the results are correct but mistakes do happen.

Remember, you can download my free time tool Epoch from the software section of my site.

 

 



< Previous Blog Article Next Blog Article >
"7bit PDU (GSM-7)" "Apple Pay Transactions"