pythondatetimeskyfield

Skyfield timescale object does not include leapseconds during creation of a UTC date?


Say I have a unix epoch time stamp 1664203669. When generating a UTC date from this time stamp using datetime I get the following date.

import datetime
datetime.datetime.utcfromtimestamp(1664203669).strftime("%Y-%m-%d %H:%M:%S")
Out[25]: '2022-09-26 14:47:49'

Though when using skyfield I get the following date

from skyfield.api import load
load.timescale().utc(1970, 1, 1, 0, 0, 1664203669).utc_strftime()
Out[27]: '2022-09-26 14:47:22 UTC'

These UTC times are 27 seconds apart. Corresponding with the total number of leap seconds since 1970 to the given time stamp. From the skyfield documentation this construction should handle leap seconds, but it doesn't seem to?

Why are these two date different?


Solution

  • You have asked the two libraries two different questions, and they each answered correctly.

    You asked Python's datetime module: What does the Unix timestamp 1664203669 correspond to?

    To make the math easy, Unix timestamps treat each day as containing exactly 60×60×24 seconds. This means that Unix timestamps can't refer to leap seconds; they skip them as if they don't exist. So datetime can simply divide 1664203669 by the number of seconds in a normal day, and then compute hours and minutes from the remainder.

    You asked Skyfield something different: What UTC date and time followed exactly 1,664,203,669 seconds after the beginning of 1970?

    Because Skyfield knows all about leap seconds, it understands that 27 of those 1.66-million seconds get eaten up by leap seconds through the years between 1970 and 2022, so it returns a time of day that's earlier.