Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Reverse of gmtime? (http://www.velocityreviews.com/forums/t957290-reverse-of-gmtime.html)

 Francois Grieu 02-05-2013 11:02 AM

Reverse of gmtime?

The gmtime function in header <time.h>
converts the calendar time pointed to by some
pointer to time_t into a broken-down time,
expressed as UTC.

Is there a canonical way to do the reverse?

Francois Grieu

 James Kuyper 02-05-2013 12:01 PM

Re: Reverse of gmtime?

On 02/05/2013 06:02 AM, Francois Grieu wrote:
> The gmtime function in header <time.h>
> converts the calendar time pointed to by some
> pointer to time_t into a broken-down time,
> expressed as UTC.
>
> Is there a canonical way to do the reverse?

The closest you can come to doing that is to extract the numbers from
the time string yourself, place them into a struct tm, and then call
mktime() to convert to time_t.

POSIX supports strptime(), which is essentially the inverse of
strftime(), which can do the first part of that process for you. I've no
idea why strftime() is in the C standard library, but strptime() is not.
--
James Kuyper

 Johann Klammer 02-05-2013 12:12 PM

Re: Reverse of gmtime?

Francois Grieu wrote:
> The gmtime function in header <time.h>
> converts the calendar time pointed to by some
> pointer to time_t into a broken-down time,
> expressed as UTC.
>
> Is there a canonical way to do the reverse?
>
>
> Francois Grieu

GNU/Linux and BSD has nonstandard function

NAME
timegm, timelocal - inverses of gmtime and localtime

CONFORMING TO
These functions are nonstandard GNU extensions that are also
present on the BSDs. Avoid their
use; see NOTES.

 Francois Grieu 02-05-2013 01:01 PM

Re: Reverse of gmtime?

On 05/02/2013 13:01, James Kuyper wrote:
> On 02/05/2013 06:02 AM, Francois Grieu wrote:
>> The gmtime function in header <time.h>
>> converts the calendar time pointed to by some
>> pointer to time_t into a broken-down time,
>> expressed as UTC.
>>
>> Is there a canonical way to do the reverse?

>
> The closest you can come to doing that is to extract the numbers from
> the time string yourself, place them into a struct tm, and then call
> mktime() to convert to time_t.

I'm assuming I have a struct tm filled-in, as
on output of gmtime in the absence of error.

struct tm *gmtime(const time_t *timer);

Problem is, mktime uses local time, not UTC.

Auxiliary problem is, mktime is ill-specified.
How far in the past does it go without reporting
an error?
Is it allowed to account for past law changes, that
could have modified the offset from UTC to local
(non-DST) time?
That happens more rarely than change of DST rules,
but here are two recent precedents:
- in Lybia, that offset changed by 1 hour on
10 November 2012
http://www.timeanddate.com/worldcloc...=252&year=2012
- in Samoa island, that offset changed by 24 hours
before the last day of 2011
http://en.wikipedia.org/wiki/Samoa#21st_century

Francois Grieu

 Francois Grieu 02-06-2013 09:51 AM

Re: Reverse of gmtime?

On 05/02/2013 20:56, William Ahern wrote:
> Francois Grieu <fgrieu@gmail.com> wrote:
>> The gmtime function in header <time.h>
>> converts the calendar time pointed to by some
>> pointer to time_t into a broken-down time,
>> expressed as UTC.

>
>> Is there a canonical way to do the reverse?

>
> No. Many systems have timegm(3) (Linux, *BSD, OS X), but many don't
> (Solaris, Windows).

Indeed there is no such function. I hoped there was a
consensus on a portable method.

> Writing timegm is fairly simple, though, using a prolepetic Gregorian
> calendar, which is pretty much the de facto calendar for most Unix systems.

Computing (non-leap) seconds between two UTC dates passed as
struct tm is possible portably (and not too difficult if
we exclude dates before March 1, 1562, which are only
representable as struct tm by some stretch of imagination).

But portably converting that to time_t without mktime ?
If that was easy, difftime would be replaceable by a mere
subtraction of time_t, followed by cast to double.
I'm reading the C standard as allowing time_t to be e.g.
a 64-bit type with the date and time BCD-coded as read from
a physical clock IC such as
http://datasheets.maximintegrated.com/en/ds/DS1375.pdf
If that's the case, we can not even count on the linearity of
difftime.

Francois Grieu

 James Kuyper 02-06-2013 01:16 PM

Re: Reverse of gmtime?

On 02/06/2013 04:51 AM, Francois Grieu wrote:
....
> I'm reading the C standard as allowing time_t to be e.g.
> a 64-bit type with the date and time BCD-coded as read from
> a physical clock IC such as
> http://datasheets.maximintegrated.com/en/ds/DS1375.pdf
> If that's the case, we can not even count on the linearity of
> difftime.

You're right. In C2011, the only requirement on time_t's type is that it
be real - it could be anything from _Bool to long double. In C99, it was
allowed to be any arithmetic type, but I guess somebody was listening to

There are no requirements imposed on how time_t represents time.
(time_t)(-1) should be a value distinguishable from a normal return from
time(), but even that's just a matter of QoI, not an actual requirement.
--
James Kuyper

 Heinrich Wolf 02-06-2013 02:38 PM

Re: Reverse of gmtime?

"William Ahern" <william@wilbur.25thandClement.com> schrieb im Newsbeitrag
news:4p48u9-khi.ln1@wilbur.25thandClement.com...

....

> Writing timegm is fairly simple, though, using a prolepetic Gregorian
> calendar, which is pretty much the de facto calendar for most Unix
> systems.

I believe, that timegm is not such simple to write in it's full complexity
with leap seconds. I have not tried timegm, only mktime with leap seconds,
using TZ="right/Etc/GMT". Maybe the unixes use some historical lookup table
for the leap seconds.

> I wrote such a function--timeutc()--for an OpenSSL binding to Lua, to
> convert ASN1_TIME to a timestamp. Checkout ext/openssl.c from
> http://25thandclement.com/~william/p...s/cqueues.html. (Although, times
> prior to 1BC may be off; I couldn't find two implementations which
> consistently gave the same results, and need to do more research to make
> sure my math is correct.)
>

 Keith Thompson 02-06-2013 05:56 PM

Re: Reverse of gmtime?

Francois Grieu <fgrieu@gmail.com> writes:
> On 05/02/2013 20:56, William Ahern wrote:
> > Francois Grieu <fgrieu@gmail.com> wrote:
> >> The gmtime function in header <time.h>
> >> converts the calendar time pointed to by some
> >> pointer to time_t into a broken-down time,
> >> expressed as UTC.

> >
> >> Is there a canonical way to do the reverse?

> >
> > No. Many systems have timegm(3) (Linux, *BSD, OS X), but many don't
> > (Solaris, Windows).

>
> Indeed there is no such function. I hoped there was a
> consensus on a portable method.

For restricted values of "consensus" and "portable":

My Linux system has timegm(). Here's an excerpt from the man page (also
available at
<http://www.kernel.org/doc/man-pages/online/pages/man3/timegm.3.html>):

NOTES
The timelocal() function is equivalent to the POSIX standard
function mktime(3). There is no reason to ever use it.

For a portable version of timegm(), set the TZ environment
variable to UTC, call mktime(3) and restore the value of TZ.
Something like

#include <time.h>
#include <stdlib.h>

time_t
my_timegm(struct tm *tm)
{
time_t ret;
char *tz;

tz = getenv("TZ");
setenv("TZ", "", 1);
tzset();
ret = mktime(tm);
if (tz)
setenv("TZ", tz, 1);
else
unsetenv("TZ");
tzset();
return ret;
}

My own notes on the above:

I'm not sure why it refers to mktime() as a "POSIX standard function".
It is, but it's also defined by the C standard.

The assumption that the time zone is controlled by the "TZ" environment
variable, and the existence of the setenv() and unsetenv() functions,
are portable to POSIX systems, but not to C implementations in general.

[...]
> I'm reading the C standard as allowing time_t to be e.g.
> a 64-bit type with the date and time BCD-coded as read from
> a physical clock IC such as
> http://datasheets.maximintegrated.com/en/ds/DS1375.pdf
> If that's the case, we can not even count on the linearity of
> difftime.

That's correct. clock_t and time_t are merely "real types capable
of representing times"; nothing more is guaranteed.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

 Keith Thompson 02-06-2013 09:16 PM

Re: Reverse of gmtime?

William Ahern <william@wilbur.25thandClement.com> writes:
[...]
> I should note that encoding leap seconds into time_t is inherently fuzzy,
> because you cannot reliably predict leap seconds into the future. That makes
> difftime() calculations indeterminate for dates merely years into the
> future. (And perhaps partly explains why there's no strptime or timegm in
> C.) For example, global climate change will unpredictably effect the earth's
> rotation as the mass of water from the poles moves toward the equator. That
> will accelerate the earth's shift to being tidally locked with the Sun
> (notwithstanding it being incinerated before then). Changes in earth's core
> as well as various tectonic events also unpredictably accelerate and
> declerate the Earth's rotation. Even if these changes are too small to add
> or subtract an entire second, they certainly shift the onset of the next
> leap second.

[...]

Earth is expected to become tidally locked with the Moon, not the Sun.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

 Eric Sosman 02-06-2013 09:49 PM

Re: Reverse of gmtime?

On 2/6/2013 4:16 PM, Keith Thompson wrote:
> William Ahern <william@wilbur.25thandClement.com> writes:
> [...]
>> I should note that encoding leap seconds into time_t is inherently fuzzy,
>> because you cannot reliably predict leap seconds into the future. That makes
>> difftime() calculations indeterminate for dates merely years into the
>> future. (And perhaps partly explains why there's no strptime or timegm in
>> C.) For example, global climate change will unpredictably effect the earth's
>> rotation as the mass of water from the poles moves toward the equator. That
>> will accelerate the earth's shift to being tidally locked with the Sun
>> (notwithstanding it being incinerated before then). Changes in earth's core
>> as well as various tectonic events also unpredictably accelerate and
>> declerate the Earth's rotation. Even if these changes are too small to add
>> or subtract an entire second, they certainly shift the onset of the next
>> leap second.

> [...]
>
> Earth is expected to become tidally locked with the Moon, not the Sun.

... in January 2038, right?

--
Eric Sosman
esosman@comcast-dot-net.invalid

All times are GMT. The time now is 12:56 AM.