Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to represent dates before epoch as a UNIX timestamp

It occurred to me that I'm not aware of a mechanism to store dates before 1970 jan. 1 as Unix timestamps. Since that date is the Unix "epoch" this isn't much of a surprise.

But - even though it's not designed for that - I still wish to store dates in the far past in Unix format.
I need this for reasons.

So my question is: how would one go about making unix-timestamps contain "invalid" but still working dates? Would storing a negative amount of seconds work? Can we even store negative amounts of seconds in a unix-timestamp? I mean isn't it unsigned?

Also if I'm correct then I could only store dates as far back as 1901. dec. 13 20:45:52 could this be extended any further back in history by any means?

like image 837
Wolfer Avatar asked Jul 29 '15 18:07

Wolfer


People also ask

Is Unix timestamp same as epoch?

The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).

Why is Jan 1 1970 the epoch?

Unix time is the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970, excluding leap seconds. This time is named the Unix epoch, because it is the start of the Unix time.

What is the format of Unix timestamp?

Unix epoch timestamps are supported in the following formats: 10 digit epoch time format surrounded by brackets (or followed by a comma). The digits must be at the very start of the message. For example, [1234567890] or [1234567890, other] followed by the rest of the message.

Is epoch always UTC?

In a computing context, an epoch is the date and time relative to which a computer's clock and timestamp values are determined. The epoch traditionally corresponds to 0 hours, 0 minutes, and 0 seconds (00:00:00) Coordinated Universal Time (UTC) on a specific date, which varies from system to system.


1 Answers

Unix Time is usually a 32-bit number of whole seconds from the first moment of 1970 in UTC, the epoch being 1 January 1970 00:00:00 UTC. That means a range of about 136 years with about half on either side of the epoch. Negative numbers are earlier, zero is the epoch, and positive are later. For a signed 32-bit integer, the values range from 1901-12-13 to 2038-01-19 03:14:07 UTC.

This is not written in stone. Well, it is written, but in a bunch of different stones. Older ones say 32-bit, newer ones 64-bit. Some specifications says that the meaning is "implementation-defined". Some Unix systems use an unsigned int to extend only into the future past the epoch, but usual practice has been a signed number. Some use a float rather than an integer. For details, see Wikipedia article on Unix Time, and this Question.

So, basically, your Question makes no sense. You have to know the context of your programming language (standard C, other C, Java, etc.), environment (POSIX-compliant), particular software library, or database store, or application.

Avoid Count-From-Epoch

Add to this lack of specificity the fact that a couple dozen other epochs have been used by various software systems, some extremely popular and common. Examples include January 1, 1601 for NTFS file system & COBOL, January 1, 1980 for various FAT file systems, January 1, 2001 for Apple Cocoa, and January 0, 1900 for Excel & Lotus 1-2-3 spreadsheets.

Further add the fact that different granularities of count have been used. Besides whole seconds, some systems use milliseconds, microseconds, or nanoseconds.

I recommend against tracking date-time as a count-from-epoch. Instead use specific data types where available in your programming language or database.

ISO 8601

When data types are not available, or when exchanging data, follow the ISO 8601 standard which defines sensible string formats for various kinds of date-time values.

  • Date
    • 2015-07-29
  • A date-time with an offset from UTC (Z is zero/Zulu for UTC) (note padding zero on offset)
    • 2015-07-29T14:59:08Z
    • 2001-02-13T12:34:56.123+05:30
  • Week (with or without day of week)
    • 2015-W31
    • 2015-W31-3
  • Ordinal date (day-of-year)
    • 2015-210
  • Interval
    • "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"
  • Duration (format of PnYnMnDTnHnMnS)
    • P3Y6M4DT12H30M5S = "period of three years, six months, four days, twelve hours, thirty minutes, and five seconds"

Search StackOverflow.com for many more Questions and Answers on these topics.

like image 147
Basil Bourque Avatar answered Oct 10 '22 08:10

Basil Bourque