19

In Python, I want to get the current Unix timestamp and then store the value for the long term and be handled by non-Python systems. (I am not merely trying to compute the difference between two timestamps within the same program run.)

Calling the function time.time() seems to be a very reasonable and concise way to get the desired timestamp... until I read the documentation:

Return the time in seconds since the epoch as a floating point number. The specific date of the epoch and the handling of leap seconds is platform dependent. On Windows and most Unix systems, the epoch is January 1, 1970, 00:00:00 (UTC) and leap seconds are not counted towards the time in seconds since the epoch. This is commonly referred to as Unix time. To find out what the epoch is on a given platform, look at gmtime(0).

[...]

(Versions: 3.5~3.9)

The phrase "epoch ... is platform dependent" is a warning sign. A weasel phrase is "most Unix systems". What are examples of Unix or non-Unix systems where Python's time.time()'s epoch is not 1970-01-01T00:00:00Z?

Is time.time() subtly unsafe for my goal? Should I look to alternatives like datetime.datetime.now().timestamp()?


Digging deeper, I also noticed that previous versions of Python didn't seem to have these caveats for time.time():

Return the time in seconds since the epoch as a floating point number. Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.

(Versions: 2.7, 3.2~3.4)

And even older wording:

Return the time as a floating point number expressed in seconds since the epoch, in UTC. Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.

(Versions: 2.2~2.6, 3.0~3.1)

Nayuki
  • 17,911
  • 6
  • 53
  • 80
  • 3
    I think any system conforming to POSIX must use that epoch. – Barmar Feb 26 '21 at 22:54
  • As the documentation directs "To find out what the epoch is on a given platform, look at gmtime(0)" – itprorh66 Feb 27 '21 at 15:24
  • 2
    side note: `datetime.timestamp()` falls back to `time.time()` - [docs](https://docs.python.org/3/library/datetime.html#datetime.datetime.timestamp), [src](https://github.com/python/cpython/blob/1e3c68246ee738b5ec5450b1eb39af2fca300cb9/Lib/datetime.py#L1696) – FObersteiner Feb 28 '21 at 16:24
  • You say you want to save a time value to be used by any system. The issue is what do you define as a system. Most desktop/server systems today are 64 bit machines, however, microprocessors are sometimes 32 bit machines. I believe, this potential difference is the rationale behind the statement that the epoch machine dependent. – itprorh66 Jan 09 '23 at 22:25
  • @itprorh66 is correct afaik. [here](https://stackoverflow.com/questions/57154794/micropython-and-epoch) is another thread which explore this topic for micropython. I suppose one pragmatic solution until this question is solve is to check max unit size or check the platform to address how far time.time() can go. – fsan Feb 03 '23 at 11:40
  • The epoch reference is dependent on the OS and/or the application from which the time is derived. See [System Time](https://en.wikipedia.org/wiki/System_time) for further details – itprorh66 Feb 03 '23 at 15:10
  • What's up with the spike in activity this past month? Is it due to some software release where this issue became quite relevant? – Nayuki Feb 14 '23 at 05:43

1 Answers1

3

If you don't want to depend upon the time.time() implementation and the (maybe) variable epoch, you can simply calculate the Unix Timestamp yourself by getting the current datetime, and substract the datetime of the epoch you want for unix timestamp (January 1st 1970), and get the seconds:

from datetime import datetime

unix_timestamp = (datetime.now() - datetime(1970, 1, 1)).total_seconds()

NOTE: you might want to add the timezone information maybe.

danielcaballero88
  • 343
  • 1
  • 2
  • 10
  • although mentioned already by you in the notes, I want to add the following `unix_timestamp = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()` this will give you the correct time format, as the Unix Time is defined in UTC – jodá Aug 04 '23 at 06:36