kre wrote:
Paul Gilmartin wrote: | That doesn't happen with date +format or | with well-designed C code which can call sprintf with the time_t | used to generate the struct tm.
I know that too, which is what I think I said, or at least, implied.
The bottom line is that %s is a really, really odd strftime format -- and it's not surprising (it's manifestly inherent) that it's hard to implement. Here's the backstory, at least as I see it: Ordinary C code has no use for %s. Ordinary C code typically starts with a time_t value, and only calls localtime or gmtime to construct a struct tm if it needs to. And pretty much the only reason to call localtime or gmtime to construct a struct tm is so that you can print out a human-readable time string, perhaps using strftime. But of course %s is not a human-readable time string. And ordinary C code wouldn't need strftime %s to print a raw time_t value in the first place, because (as I was just saying) ordinary C code typically has raw time_t values rattling around already, which are easier to print with printf anyway. (Yes, as kre pointed out, it's unclear whether you'd want %ld or %lld, or some other variant, to do so, but that's another story.) But, despite their non-human-readableness, time_t values are now so ubiquitous that they are occasionally of interest to humans, so at some point along the way, the 'date' command acquired "%s" as one of its custom output format specifiers. So the specification for the 'date' command was really strange: when you asked it to print a custom string using "date +fmt", the specification for the format string was basically "anything strftime can do, plus %s". I don't know off the top of my head how the "official" date command implemented this. I know that in my own work I've several times found myself writing code that took a "strftime-plus-%s" format string, manually scanned for and interpolated any %s specifiers, then handed it off to strftime to take care of the rest. This was unremittingly ugly -- but it was (to my mind, anyway) still vastly preferable to trying to have strftime handle %s by itself, because strftime just doesn't have the right information available to it. I gather from this thread that someone has decided to "solve" this problem anyway, by officially adding %s to the supported strftime formats. However, it seems to me that the only "problem" here is that the 'date' program has been difficult to write. My own opinion is that dragging the whole rest of the world through this mudpit is not the right way of solving date's implementation problem -- but then, I'm not on the Posix committee, so it doesn't matter what I think. (Me, I'd say that if strftime is to support %s, then either (a) struct tm has to be augmented with a new field for the original time_t value, or (b) %s has to be supported only with a new strftime variant where you explicitly pass in the time_t value for %s to use, if necessary: strftime_s(char *buf, size_t bufsize, const char *format, struct tm *timeptr, time_t t). I hope that, in the absence of either of these admittedly radical proposals, Posix is at least mandating tm_gmtoff, which we've long needed anyway, and which would at least make the implicit mktime call, necessitated by %s, a tractable problem.)