I have been using tools like iperf3 when using its --timestamps feature that uses strftime under the hood for formatting time. Although I have seen examples that show the conversion specifier %s used for epoch timestamp, I have not been able to see official documentation on its use. In the source code for strftime.c, there are no comments/notes mentioning its absence from documentation. While the functionality seems to work well for my purposes, I've come across suggestions or mentions (mostly related to the python datetime module) cautioning against reliance on this format.
I'm curious to understand the implications of using %s, including any historical context. Any insights or knowledge on this topic would be appreciated!
%s is not part of the C standard, it depends on the implementation. Here on MacOS, which has BSD roots, it is.
%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3)).
The manual explains...
STANDARDS
The strftime() function conforms to ISO/IEC 9899:1990 (“ISO C90”) with a lot of extensions including ‘%C’, ‘%D’, ‘%E*’, ‘%e’, ‘%G’, ‘%g’, ‘%h’, ‘%k’, ‘%l’, ‘%n’, ‘%O*’, ‘%R’, ‘%r’, ‘%s’, ‘%T’, ‘%t’, ‘%u’, ‘%V’, ‘%z’, and ‘%+’.
The peculiar week number and year in the replacements of ‘%G’, ‘%g’, and ‘%V’ are defined in ISO 8601: 1988.
Epoch time is the number of seconds since the epoch, so %s.
If we look at the first version of strftime.c in NetBSD we see this.
188 1.1 mrg case 's':
189 1.1 mrg if (!_secs(t))
190 1.1 mrg return(0);
191 1.1 mrg continue;
_secs for seconds is just a thin wrapper around mktime. Likely the C standard people felt %s was redundant with mktime, and the BSD people felt it was convenient.
Many languages implemented in C, such as Python, still rely on strftime and so only document the standard ones and some common extensions. For example, in Python datetime.now().strftime("%:z") on MacOS simply prints :z because MacOS strftime does not implement %:z. Whereas Ruby has its own strftime implementation and Time.now.strftime('%:z') works.
It's documented in places where it's supported. For example in GNU strftime:
%s
The number of seconds since the epoch, i.e., since 1970-01-01 00:00:00 UTC. Leap seconds are not counted unless leap second support is available.
This format is a GNU extension.
BSD strftime also has a similar extension
The strftime() function conforms to ISO/IEC 9899:1999 (``ISO C99''). The `%C', `%D', `%e', `%g', `%G', `%h', `%k', `%l', `%n', `%r', `%R', `%s', `%t', `%T', `%u', `%V', and `%v' conversion specifications are extensions.
All will declare it as an extension because the C standard doesn't support it. %s is not defined in the POSIX standard either so it's not safe to assume all *nix and *nix-like OSes will have it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With