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.