Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the historical significance of %s in the strftime function and why is it not documented? [closed]

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!

like image 932
kyrlon Avatar asked Oct 15 '25 00:10

kyrlon


2 Answers

%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.

like image 116
Schwern Avatar answered Oct 17 '25 15:10

Schwern


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

like image 31
phuclv Avatar answered Oct 17 '25 14:10

phuclv



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!