Re: Extended-Range Time Type
- From: "Antoine Leca" <root@xxxxxxxxxxxxxxxxx>
- Date: Mon, 28 Jan 2008 18:06:46 +0100
En news:c0772e06-96df-403e-92b6-7e8c8d5c11c6@xxxxxxxxxxxxxxxxxxxxxxxxxxxx,
David R Tribble va escriure:
Something as simple as calculating the number of seconds
since UTC midnight of the current day can be done in ISO C,
Even that! First because "the current day" within ISO C will force you to
use the Gregorian calendar, which may not be what one really wants.
Second because mktime(), localtime(), and gmtime() are not required to
always deliver meaningful results (an obvious case is when the notion of the
local timezone is unknown.)
And finally, if that day happens to have a leap second (would be Jun or Dec
30th or 31st) and this leap second moment already happened, then the count
of second might be biased by one, without any easy way for you to know
(unless the implementation has be made aware of leap seconds, but then it
would break Posix conformance.)
but it takes a lot of work.
I believe the easiest way to do it is to use time(), localtime(),
strftime("%H%M%S%z"), and sscanf(). This assumes C99 conformance (for %z),
determinability of the local timezone, and that the timezone has a integer
number of minutes offset from Greenwich (which is the current case all
around the world for civil time.) Of course it cannot avoid any of the
pitfalls signaled above (even the corner case of the leap second cannot be
handled with an aware implementation.)
#include <stdio.h>
#include <time.h>
#include <string.h>
int main()
{
time_t t=(time_t)-1;
struct tm *tm=NULL;
char buf[15];
long s;
int h,m,zh,zm,n=0;
time(&t);
tm = t==(time_t)-1 ? NULL : localtime(&t);
n = tm ? strftime(buf, sizeof buf, "%H:%M:%S %z", tm) : 0;
if(n==14 && 5==sscanf(buf,"%2d:%2d:%2ld%4d%2d",&h,&m,&s,&zh,&zm)){
printf("Secondes depuis minuit UTC = %ld\n",
(s + 60L*(m+zm+60*(24+h+zh)) ) % 86400);
}
else puts("Cannot determine count of seconds from UTC midnight");
return 0;
}
With my longtime_t, it takes about two lines of code.
I agree with you that the quality requirement of checking the result of the
calls, plus the needed declarations and #include, makes the above solution a
bit long; besides, my style is a bit terse, so you might prefer something
more readable with more meaningful variable names or generous use of spaces.
Yet, the core of it is only 3 lines long, something like (assuming time_t
t=time(NULL) have been defined, so in fact you may count it as 4 lines
long...):
if( 14==strftime(buf, sizeof buf, "%H:%M:%S %z", localtime(&t))
&&5==sscanf(buf, "%2d:%2d:%2ld%4d%2d", &h, &m, &s, &zh, &zm) )
return (s + 60L*(m+zm+60*(24+h+zh)) ) % 86400;
Of course, this only pretends to show that it is often easier to deal with
ISO8601 formatted timestamps than trying to make overelaborated computations
with struct tm, something we already know for a long time (and a good reason
invoked to drop the C9x tmx stuff.)
I designed my longtime and calendar API for the majority of
"normal" civil applications.
By the way, I have a question regarding your calendar API
(david.tribble.com/text/c0xcalendar.html#func-calendaradd): what does mean
"Days [resp. Months] difference less than a month" [resp. year]?
Also what should this function do when the raw result of the computation is
ambiguous (lies in the fall back period, for example) or should be further
adjusted (results into the spring forward period, for example; or when the
starting point is some intermediary division, like day 31, a leap second,
veadar month, sans-culottides etc.)?
Is there some ways to implement different rules (like 360 vs. 365 vs 366 vs
365/360 etc., as used in banking)?
Just curious...
Antoine
.
- Follow-Ups:
- Re: Extended-Range Time Type
- From: Jonathan Leffler
- Re: Extended-Range Time Type
- From: David R Tribble
- Re: Extended-Range Time Type
- References:
- Extended-Range Time Type
- From: Mosfet
- Re: Extended-Range Time Type
- From: cr88192
- Re: Extended-Range Time Type
- From: David R Tribble
- Re: Extended-Range Time Type
- From: cr88192
- Re: Extended-Range Time Type
- From: David R Tribble
- Extended-Range Time Type
- Prev by Date: Re: scanf, whitespace characters and isspace
- Next by Date: Re: Extended-Range Time Type
- Previous by thread: Re: Extended-Range Time Type
- Next by thread: Re: Extended-Range Time Type
- Index(es):
Relevant Pages
|