Reverse function for gmtime()? 
Author Message
 Reverse function for gmtime()?

I can use localtime() to convert a time_t to a broken-down struct tm,
and mktime() to go the other way.

Is there a way to convert from a broken-down struct tm, expressed in
UTC, to a time_t?  gmtime() goes the other way, but I find nothing in
the standard C library which would allow me this.

The only solution I've found so far was to call

        setenv("TZNAME","UTC",1)

beforehand.  Yes, that's a horrible hack, and UNIX-specific, too.  Does
anybody have anything better, short of reinventing that particular
wheel?



Thu, 10 Jun 1999 03:00:00 GMT  
 Reverse function for gmtime()?


Quote:

>Is there a way to convert from a broken-down struct tm, expressed in
>UTC, to a time_t?  gmtime() goes the other way, but I find nothing in
>the standard C library which would allow me this.

I submitted to the Apache folks the following function to get the offset
from GMT for the current machine.  I haven't looked to see if it has made
it into a recent release.

Obviously, once you know what the delta between UTC and local time is, it's
a small matter of programming to convert the results of mktime() to
UTC.  In fact, it's one add.

- - - - - 8< cut here - - - - -

/* This code ought to work for any system that has mktime, localtime, and
 * gmtime from the ANSI C spec */

struct tm *get_gmtoff(long *tz) {
    time_t tt;
    struct tm *loc_t;
    struct tm *gmt_t;

    tt = time(NULL);
    loc_t = localtime(&tt);
    gmt_t = gmtime(&tt);

    *tz = mktime(loc_t) - mktime(gmt_t);

    return loc_t;

Quote:
}

--


    Free time?  There's no such thing.  It just comes in varying prices...


Fri, 11 Jun 1999 03:00:00 GMT  
 Reverse function for gmtime()?


Quote:
>I submitted to the Apache folks the following function to get the offset
>from GMT for the current machine.  I haven't looked to see if it has made
>it into a recent release.
>- - - - - 8< cut here - - - - -
>/* This code ought to work for any system that has mktime, localtime, and
> * gmtime from the ANSI C spec */
>struct tm *get_gmtoff(long *tz) {
>    time_t tt;
>    struct tm *loc_t;
>    struct tm *gmt_t;

>    tt = time(NULL);
>    loc_t = localtime(&tt);
>    gmt_t = gmtime(&tt);

>    *tz = mktime(loc_t) - mktime(gmt_t);

>    return loc_t;
>}
>--


>    Free time?  There's no such thing.  It just comes in varying prices...

I see two possible problems.  First, this assumes that the subtraction of
two time_t values (as returned by mktime) is meaningful.  On many systems,
the time is kept as the number of seconds since some epoch, so such a
subtraction works.  However, the standard permits the time_t value to be,
for example, bit fields holding the date, month, year, etc.  To be general,
declare tz to be double and use difftime().

Also, many parts of the world use daylight time part of the year, so the
delta between UTC and local time changes by an hour depending upon the
time of year.  It is necessary to check the is_dst component of the
returned loc_t to determine whether this delta is for standard or daylight
time.

--
Roger Wells



Sun, 13 Jun 1999 03:00:00 GMT  
 Reverse function for gmtime()?



Quote:


>>Is there a way to convert from a broken-down struct tm, expressed in
>>UTC, to a time_t?  gmtime() goes the other way, but I find nothing in
>>the standard C library which would allow me this.
...
>Obviously, once you know what the delta between UTC and local time is, it's
>a small matter of programming to convert the results of mktime() to
>UTC.  In fact, it's one add.

Provided, that is, that you aren't dealing with an "anomaly" such
as the transition to/from daylight savings time.  Especially
"from", as there is an inherent abiguity in the overlapped
local time in this case.

In answer to Thomas Koening's question, there is not such a function
in the C89 standard.  I certainly hope that this is corrected in
the C9x standard.

NB: I don't know what environment you're working in, or why
you need the time_t value, but if you are in an situation where
it is appropriate to use the POSIX.1 definition of time the
formula:
        ((((year-70)*365+(year-69)/4+yday)*24+hour)*60+min)*60+sec
(using UTC time) gives POSIX seconds-since-the-epoch.  (Note that
this standard explicity does *not* account for leap-seconds, nor
is this formula appropriate for most non-POSIX C environments.)

                --Ken Pizzini



Sun, 13 Jun 1999 03:00:00 GMT  
 Reverse function for gmtime()?

Quote:

>I can use localtime() to convert a time_t to a broken-down struct tm,
>and mktime() to go the other way.

>Is there a way to convert from a broken-down struct tm, expressed in
>UTC, to a time_t?  gmtime() goes the other way, but I find nothing in
>the standard C library which would allow me this.

There isn't a standard function (although I feel there should be).  I've
been working on this with considerable frustration.  If all you want is
the time_t value, the following will work, provided you somehow supply
the number of seconds difference between UTC and your local STANDARD time
(on POSIX, this value can be obtained from the global variable timezone.
In any case, it is constant for any given locale.)  Assume TIMEZONE is
somehow set to this value:

time_t mkgmtime(struct tm *timeptr)
{
        timeptr->tm_isdst = 0;
        timeptr->tm_sec -= TIMEZONE;

        return mktime(timeptr);

Quote:
}

If the time is a few hours after the earliest time your system handles,
this may fail.  For example, on a UNIX system which doesn't handle times
before 1 Jan 1970 UTC, in the Pacific Time Zone (8 hours earlier than UTC)
it will fail for times before 08:00 on 1 Jan 1970.  And, of course, the
components of the struct tm will be in error.

In the general case, the time_t value must be considered a magic cookie.
However, on many systems (including UNIX and MS-DOS) you are guaranteed
that it is a count of seconds since the start of some epoch date.  If this
is the case, you can avoid the above problems near the start of the epoch
with the following:

time_t mkgmtime(struct tm *timeptr)
{
        time_t tmvalue;

        timeptr->tm_isdst = 0;

        tmvalue = mktime(timeptr);
        /* check for error */
        if (tmvalue != -1)
                tmvalue -= TIMEZONE;

        return tmvalue;

Quote:
} /* mkgmtime */

The struct tm components may still be off by an hour because of the
daylight time adjustment.  I've been trying to find a simple way to get
both the time_t value and struct tm components correct.  It's particularly
frustrating because most of the effort is in undoing the time-zone
adjustment, which is one of the most complicated adjustments that localtime
and mktime have to make.  (In other words, doing a lot of work to undo the
effect of a lot of work someone else did.)

--
Roger Wells (speaking only for myself)



Sun, 13 Jun 1999 03:00:00 GMT  
 Reverse function for gmtime()?

Quote:
>NB: I don't know what environment you're working in, or why
>you need the time_t value, but if you are in an situation where
>it is appropriate to use the POSIX.1 definition of time the
>formula:
>    ((((year-70)*365+(year-69)/4+yday)*24+hour)*60+min)*60+sec
>(using UTC time) gives POSIX seconds-since-the-epoch.  (Note that
>this standard explicity does *not* account for leap-seconds, nor
>is this formula appropriate for most non-POSIX C environments.)

>            --Ken Pizzini

While on the subject of Local Time and Summer Time.
Please remember that Summer Time here ( October through to March ) is
Univeral plus _13_ hours.
More than one purportably professional package simply ignore this.
One actually re-set my hardware clock ( secretively ).

Sincerely etc.,

--
 +-------------PLEASE, PLEASE, NO ADVERTISING E-MAIL!!!----------------+
 | NAME  Christopher Sawtell                                           |
 | SNAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.|

 +---------PLEASE NOTE THAT LOCAL TIME IS GMT PLUS 13 HOURS------------+



Thu, 17 Jun 1999 03:00:00 GMT  
 Reverse function for gmtime()?

Quote:

> I've been trying to find a simple way to get
> both the time_t value and struct tm components correct.

There's no simple way to do it that works in all C environments.
However, here are a few ways that should work in all Posix environments
(other than munging TZ, which is inefficient and error-prone):

1.  Use the Olson public domain `timegm' function in
    <URL:ftp://elsie.nci.nih.gov/pub/>, with:

        timegm (gmtime (t)) == t

    This requires replacing some C library functions like `localtime', though.

2.  Use RCS's src/maketime.c with:

        tm2time (gmtime (t), 0) == t

    This doesn't give you full mktime functionality, though -- i.e. it
    only inverts the output of gmtime; it doesn't do mktime-style arithmetic.

3.  Use Emacs's src/mktime.c with Posix 1003.1-1996 gmtime_r and:

        static time_t gmtime_offset;
        ...
        __mktime_internal (gmtime (t), gmtime_r, &gmtime_offset) == t

    This is perhaps the easiest solution of the three.  It's easy to
    write a non-reentrant gmtime_r in terms of gmtime if you lack gmtime_r.

All the above solutions will work even on (non-Posix) hosts that have
leap second support.



Sat, 19 Jun 1999 03:00:00 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Does gmtime() function works with...

2. Microsoft C time and gmtime functions.

3. Functions- Reverse a digit

4. Problem with making a reverse-string function

5. Reverse video function in ANSI C?

6. memory leaks for gmtime() and ctime()

7. converting from localtimes to gmtime

8. Question about mktime, localtime, gmtime

9. Unix and gmtime()

10. source for gmtime()?

11. converting from localtimes to gmtime

12. Anyone have portable source code for inverse of gmtime()

 

 
Powered by phpBB® Forum Software