Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

convert unix timestamp to time in C++

3,252 views
Skip to first unread message

Piranha

unread,
Aug 18, 2008, 7:39:33 PM8/18/08
to
I´m having no problem to convert the local PC´s time to a string,
using

time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
char MyLocalTime [80];
strftime (MyLocalTime,80,"Time: %H:%M",timeinfo);

But how do you do the same with some unix timestamp that doesn´t match
your local time?

Richard Heathfield

unread,
Aug 18, 2008, 9:02:14 PM8/18/08
to
Piranha said:

You seem to have misunderstood what localtime() does.

It is the time() call that gets the current time as a time_t object.

All that localtime() does is convert a time represented in time_t format,
giving a struct tm format as output. It doesn't have to convert the
current time - if you have a time_t object with some other time in it,
localtime() will cheerfully convert it into a struct tm for you. (If
localtime() doesn't meet your needs, you may find that gmtime() does.)

The mktime() function goes the other way - you can create a time_t value
representing any in-range time you like, just by populating a struct tm
object (fully!, using 0s for anything you don't care about) and handing
that data to mktime().

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Piranha

unread,
Aug 19, 2008, 8:48:52 AM8/19/08
to

Then the question is, how do you convert an int or double to time_t?
I guess I can not simply do:

time_t sometime = (time_t)somevalue;

or can I?

Richard Heathfield

unread,
Aug 19, 2008, 10:39:44 AM8/19/08
to
Piranha said:

<snip>



> Then the question is, how do you convert an int or double to time_t?

It's a simple three-stage process:

1) decide what date and time the int, or double, represents;
2) use that information to populate a struct tm as I mentioned earlier;
3) call mktime.

> I guess I can not simply do:
>
> time_t sometime = (time_t)somevalue;
>
> or can I?

Your compiler will let you do it, but whether it does what you want is
anyone's guess. It depends on the value in the int (or double, or
whatever) - was it a time_t originally? If so, beware that moving the data
to an int or double and back may conceivably lose information (not all
types are required to be equally wide), and if not, what possible meaning
could the line have?

Piranha

unread,
Aug 19, 2008, 1:17:04 PM8/19/08
to

"somevalue" is from start a const uint, set as a fixed value on start,
never converted from or to anything, its value is in a range between 0
and time(NULL), meaning it represents a valid unix time.

Richard Heathfield

unread,
Aug 19, 2008, 11:11:15 PM8/19/08
to
Piranha said:

> On 19 Aug., 16:39, Richard Heathfield <r...@see.sig.invalid> wrote:
>> Piranha said:
>>
>> <snip>
>>
>> > Then the question is, how do you convert an int or double to time_t?
>>
>> It's a simple three-stage process:
>>
>> 1) decide what date and time the int, or double, represents;
>> 2) use that information to populate a struct tm as I mentioned earlier;
>> 3) call mktime.
>>
>> > I guess I can not simply do:
>>
>> > time_t sometime = (time_t)somevalue;
>>
>> > or can I?
>>
>> Your compiler will let you do it, but whether it does what you want is
>> anyone's guess. It depends on the value in the int (or double, or
>> whatever) - was it a time_t originally? If so, beware that moving the
>> data to an int or double and back may conceivably lose information (not
>> all types are required to be equally wide), and if not, what possible
>> meaning could the line have?
>>

> "somevalue" is from start a const uint, set as a fixed value on start,
> never converted from or to anything, its value is in a range between 0
> and time(NULL), meaning it represents a valid unix time.

Then it is conceivable that you might just get away with the wrong solution
that you propose. Sadly, this probably means you'll do just that.

Piranha

unread,
Aug 20, 2008, 6:24:47 AM8/20/08
to
> "Usenet is a strange place" - dmr 29 July 1999- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -

I´d love to have a proper one, yet it seems there is no such thing.
Different from PHP dats() which will accept any int value as argument,
in C it depends on localtime, where localtime accepts only time_t
format, while the only valid way to get a proper tim_t format is
time() which doesn´t take any arguments, but uses the computers clock.
A function that converts int to time_t seems not to exist, yet it isn
´t even sure what the format of time_t is, there is only some kind of
"mostly" it is 00:00:00 but you never know what it really is.

I actually have a working solution, I just don´t like it.
Since the application frequently connects via WinInet to a PHP script
on my homepage, I simply let PHP calculate the proper date() and send
it back to me as string.
While C is the mother od all languages, it seems weird to let the kids
work for the mother, but at least this is a solution within the rules.

Richard Heathfield

unread,
Aug 20, 2008, 6:37:48 AM8/20/08
to
Piranha said:

> On 20 Aug., 05:11, Richard Heathfield <r...@see.sig.invalid> wrote:
>> Piranha said:
>>

<snip>


>>
>> > "somevalue" is from start a const uint, set as a fixed value on start,
>> > never converted from or to anything, its value is in a range between 0
>> > and time(NULL), meaning it represents a valid unix time.
>>
>> Then it is conceivable that you might just get away with the wrong
>> solution that you propose. Sadly, this probably means you'll do just
>> that.
>

> I´d love to have a proper one, yet it seems there is no such thing.
> Different from PHP dats() which will accept any int value as argument,
> in C it depends on localtime, where localtime accepts only time_t
> format, while the only valid way to get a proper tim_t format is
> time()

I've already explained that you can get any time_t you like, using
mktime(), provided only that you know what date and time you wish to
represent (and of course provided that it's in range).

> which doesn´t take any arguments,

time() does in fact take an argument, but you're right that it doesn't do
you any good in your case.

> but uses the computers clock.

Yes, but that's its job - that's what it's for!

> A function that converts int to time_t seems not to exist,

Right. Feel free to write one. The first question you'll have to ask
yourself is "what does an int /mean/, in date and time terms?" - and once
you know the answer to that, you'll discover that the rest is easy - just
use mktime. But *until* you know the answer to that (and, as far as I'm
aware, nobody does), you're stuck.

> yet it isn
> ´t even sure what the format of time_t is, there is only some kind of
> "mostly" it is 00:00:00 but you never know what it really is.

time_t doesn't /have/ a format. It's just an arithmetic type that is
capable of representing times in a way that mktime, localtime, gmtime and
the like can understand. How it does that, precisely, is up to your
implementation.

Charlie Gibbs

unread,
Aug 20, 2008, 1:40:56 PM8/20/08
to
In article <Gt6dnXoMRPtibzbV...@bt.com>,
r...@see.sig.invalid (Richard Heathfield) writes:

> Piranha said:
>
>> yet it isn´t even sure what the format of time_t is, there is only
>> some kind of "mostly" it is 00:00:00 but you never know what it
>> really is.
>
> time_t doesn't /have/ a format. It's just an arithmetic type that is
> capable of representing times in a way that mktime, localtime, gmtime
> and the like can understand. How it does that, precisely, is up to
> your implementation.

Not that I'd recommend fiddling with them directly, but generally
time_t is a 32-bit signed integer containing the number of seconds
since the start of January 1, 1970.

I'll often do things like adding 300 to the value returned by time()
to get a time 5 minutes in the future, or subtracting one time_t from
another to get the time difference in seconds. But if you wanted to
be strictly correct there are functions that do that sort of thing,
which are guaranteed to still work should the format of time_t ever
change. (And it has to change someday, since a 32-bit signed time_t
will overflow in January of 2038.)

--
/~\ cgi...@kltpzyxm.invalid (Charlie Gibbs)
\ / I'm really at ac.dekanfrus if you read it the right way.
X Top-posted messages will probably be ignored. See RFC1855.
/ \ HTML will DEFINITELY be ignored. Join the ASCII ribbon campaign!

Roberto Baggio

unread,
Aug 21, 2008, 5:09:56 AM8/21/08
to
"Charlie Gibbs" <cgi...@kltpzyxm.invalid> wrote in message
news:1377.189T2...@kltpzyxm.invalid...

> In article <Gt6dnXoMRPtibzbV...@bt.com>,
> r...@see.sig.invalid (Richard Heathfield) writes:
>
>> Piranha said:
>>
>>> yet it isn´t even sure what the format of time_t is, there is only
>>> some kind of "mostly" it is 00:00:00 but you never know what it
>>> really is.
>>
>> time_t doesn't /have/ a format. It's just an arithmetic type that is
>> capable of representing times in a way that mktime, localtime, gmtime
>> and the like can understand. How it does that, precisely, is up to
>> your implementation.
>
> Not that I'd recommend fiddling with them directly, but generally
> time_t is a 32-bit signed integer containing the number of seconds
> since the start of January 1, 1970.
>
> I'll often do things like adding 300 to the value returned by time()
> to get a time 5 minutes in the future, or subtracting one time_t from
> another to get the time difference in seconds. But if you wanted to
> be strictly correct there are functions that do that sort of thing,
> which are guaranteed to still work should the format of time_t ever
> change. (And it has to change someday, since a 32-bit signed time_t
> will overflow in January of 2038.)


With VS2005, it has changed, as time_t defaults to a 64 bit value.


Michael Wojcik

unread,
Aug 21, 2008, 1:41:59 PM8/21/08
to
Richard Heathfield wrote:
>
> time_t doesn't /have/ a format. It's just an arithmetic type that is
> capable of representing times in a way that mktime, localtime, gmtime and
> the like can understand. How it does that, precisely, is up to your
> implementation.

While this is true of C's time_t, the Single Unix Specification
requires that time_t be an integer or floating type, and that time()
return a count of seconds since the Epoch, as a time_t. See:

http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/types.h.html
http://www.opengroup.org/onlinepubs/009695399/functions/time.html

(The SUSv3 standard explicitly marks the seconds-since-the-Epoch
requirement as an extension to the C standard, as it should.)

Those two requirements essentially do constrain the format of time_t
for conforming Unix implementations, and the OP's subject line
suggests that the value in question is, in fact, a time_t from some
Unix implementation. (Whether the OP wants to trust in its SUS
conformance is another question.)

Thus the OP, faced with a "unix timestamp" value, may be able to
assume it contains seconds since the Epoch. And that, in turn, would
permit using mktime to convert it to a time_t (for his implementation)
- much as you suggested.

To the OP: intialize a struct tm. Set tm_year (years since 1900) to
70; this is the beginning of the epoch. Set tm_sec to the value of
your Unix timestamp. (We will assume this value was correctly
converted from the source implementation's time_t to the
representation you have.) tm_sec will, of course, have a non-canonical
value (greater than 61) - but mktime is required to deal with this
correctly.

Pass a pointer to this structure to mktime, and the return value
should be a time_t, as represented by your implementation, for the
time represented by your Unix timestamp value. (Check that it is not
(time_t)-1, indicating an error.)

Then you may use localtime on that time_t to get it as a struct tm in
your local timezone, etc.

The key here is knowing that, if your source Unix system conforms to
the Unix standard and the value from it correctly represents a time_t
on that system, then the value you have is in fact seconds since
midnight on 1/1/1970. That information is sufficient to convert it to
a time_t for your C implementation, and then to a struct tm in
canonical form.

--
Michael Wojcik
Micro Focus
Rhetoric & Writing, Michigan State University

Piranha

unread,
Aug 21, 2008, 5:05:58 PM8/21/08
to
On 21 Aug., 19:41, Michael Wojcik <mwoj...@newsguy.com> wrote:
> Richard Heathfield wrote:
>
> > time_t doesn't /have/ a format. It's just an arithmetic type that is
> > capable of representing times in a way that mktime, localtime, gmtime and
> > the like can understand. How it does that, precisely, is up to your
> > implementation.
>
> While this is true of C's time_t, the Single Unix Specification
> requires that time_t be an integer or floating type, and that time()
> return a count of seconds since the Epoch, as a time_t. See:
>
> http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/types.h.htmlhttp://www.opengroup.org/onlinepubs/009695399/functions/time.html

Thanks very much, this really helped.

0 new messages