Date: Wed, 30 Sep 1998 16:01:33 +0200 From: Antoine Leca <Antoine.Leca@renault.fr> Paul Eggert wrote, discussing with Markus:
let's just use a signed integer count of the number of time intervals since the epoch. We can define a type stime_t for this integer, and a stime_t macro STIMES_PER_SEC giving the number of time intervals per second. This makes time arithmetic much, much easier.
Hmm. I am not sure to follow you here, since for the vast majority of applications, struct xtime arithmetic will be defined as following struct xtime addxtime(struct xtime x, struct xtime y) { return (struct xtime){.sec = x.sec+y.sec}; } But this gives an answer that can be off by as much as two seconds; an inaccuracy like that would break many applications. Your remark reinforces my impression that the struct xtime method is too error-prone in practice. This proposal have a clear drawback: like clock_t in C89, it requires to specify the resolution of the type itself requiring a lot of multiplication/division with a constant like XTIME_PER_SEC But any time proposal must specify the resolution somehow. struct xtime specifies it as nanoseconds, for example; so there is an implied XTIME_PER_SEC value of 1000000000. I don't see this as a special drawback of my proposal. *if* we disregard subseconds, Markus' proposal is essentialy the same as the initial POSIX, isn't it? Yes; but that's also true for my proposal. If STIMES_PER_SEC is 1, then it degenerates to the original POSIX.1 as a special case. Another idea is striking me right now: - keeping struct xtime - specifying that the first member, named sec, typed int_fast64_t, should be what it is now with Markus' draft - allowing others fields, providing they are self-containing, for counting more precise quantities - adding to the draft addxtime, diffxtime, mulxtime, divxtime - adding to the draft a way to convert from double to xtime and back, either with an API (well, two), or with a macro giving the precision or any subfield. What about this sketch? Something like that could be done, but it is complicated; if you're going to have that level of complexity, you might as well make struct xtime be an opaque type (xtime_t, say) and be done with it. That way, I could define xtime_t to be a signed integer value, and Markus could make it a structure. This would be a reasonable committee-like compromise that might satisfy neither of us (:-). In practice, though, I hope that the signed-integer-value approach would win out, as it is so much more convenient to use; much as the POSIX.1 time_t won out over the C89 opaque time_t.
How would you represent leap seconds in your stime_t arithmetic type?
The most natural approach is to have xtime_get (or a variant) return a boolean flag specifying whether the timestamp is within a leap second. This would be needed only with TIME_UTC timestamps.
This way way, we should add a parameter to both xtime_make and xtime_breakup: either an input argument, or an output one. Yes, this would be needed if we use a separate boolean. Furthermore, there should be some way for xtime_breakup to disambiguate between UTC and TAI: so one more parameter... I don't understand this comment. xtime_breakup is defined to work only on TIME_UTC timestamps. There's no need to break up TIME_TAI timestamps.
For stime_get however this is not an option: the return value is certainly required for comfortable error checking.
No, you can return a negative number -E such that E is suitable as an argument to strerror. This is a natural way to report errors for many of the xtime functions.
Yes, but it should not be *required* to be done this way: the Committee have strong feeling against standardizing this way, since errno-mechanism is very problematic to be used in some environments (this was tolerated for math.h because of wide existing practice). The approach that I'm suggesting does not use errno -- it returns a value suitable as an argument to strerror, without communicating it via errno. So I think the suggestion shouldn't run afoul of the anti-errno sentiment.
It's that sense in which struct xtime is not a completely portable type; you can't output it from one implementation and read it back into another, even in textual form, without possibly having some problems.
In textual form, I do not see the problem. What is wrong with fprintf(output, PRIdFAST64 ":" PRIdFAST32 "\n", xt.sec, xt.nsec); then fscanf (input, SCNdFAST64 ":" SCNdFAST32 "\n", xt.sec, xt.nsec); That code doesn't report overflow well if the destination host's sec field is smaller than the source's. However, my comments were about binary I/O. If you're willing to go to textual form, then the signed integer approach is also portable, though I admit that it's a bit trickier, as you must also output the resolution.
I don't think the Olson-style names should be required; but they should be suggested, at least in a footnote with a URL.
This is not standard practice in the text of an ISO Standard (I think this is even prohibited). Wow, an ISO standard can't say ``should''? OK, if so, the Rationale would be fine.
That doesn't work in the presence of leap seconds.
Yes it does (using Markus' acceptation of xtime)... unless of course you are referring to the point I avoided above, that is if the beginning point was in a leap second. Sorry, I should have been clearer. You are correct: adding 3 * 86400 to the sec field doesn't work if the starting timestamp is within a leap second. Also, even ignoring the problem of starting within a leap second, there is a difference between wanting a time that is 3*86400 seconds later, and wanting a time that is 3 days later, because the former wants to respect leap seconds but the latter wants to ignore them. C89 mktime supports both sorts of requests (assuming int is large enough to represent 3*86400) but the struct xtime proposal supports only the latter. Or perhaps the intent is that if you want to add 3*86400 seconds then you have to convert your TIME_UTC timestamp to some other clock type, do the arithmetic there, and then convert back? If so, which clock type is recommended? TIME_TAI would be the best, but presumably it's not always available. So I'm a bit puzzled if this is indeed the intent.
there is still one value that is quite inconvenient to get via strftime: the UTC offset (to the nearest second, please! :-). Perhaps a new format spec could be added to get that?
I think this should be left to the programmer, using first strfxtime("%z"...), then parsing the result and multiplying the hour count by 3600, the minute count by 60. That is inconvenient, but it would work, so long as %Z outputs the UTC offset to 1-second resolution if necessary, not just the 1-minute in the current proposal.