Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > time_t problem: representing an error value

Reply
Thread Tools

time_t problem: representing an error value

 
 
Dom Bannon
Guest
Posts: n/a
 
      05-06-2010
I need to represent dates going back to, potentially, ~1900 (on
Windows and Linux). The obvious way to do this is to use a time_t, but
this seems to have a flaw in that various library routines (mktime and
time, at least) use (time_t)-1 as an error return.

(time_t)-1 is a valid representation of the last second in 1969, so
it's only a matter of time before I need this as a valid date.

I suppose I'm just going to have to ignore this, and work around
problems as they arise. Thoughts? A better way to do this? If you've
got a database with dates in it, do you use time_t, or something else?

Thanks -

Dom
 
Reply With Quote
 
 
 
 
Öö Tiib
Guest
Posts: n/a
 
      05-06-2010
On May 6, 12:04 pm, Dom Bannon <(E-Mail Removed)> wrote:
> I need to represent dates going back to, potentially, ~1900 (on
> Windows and Linux). The obvious way to do this is to use a time_t, but
> this seems to have a flaw in that various library routines (mktime and
> time, at least) use (time_t)-1 as an error return.


time_t does not help if you need dates before 1970 because your dates
are outside of range for time_t then. Use something else that is also
portable (like Boost.Date_Time) for solutions where you need time
values (or granularity of time values) that time_t does not reach.

Otherwise it feels like you are trying to use signed chars where you
clearly need floats.
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      05-06-2010
On 5/6/2010 5:04 AM, Dom Bannon wrote:
> I need to represent dates going back to, potentially, ~1900 (on
> Windows and Linux). The obvious way to do this is to use a time_t, but
> this seems to have a flaw in that various library routines (mktime and
> time, at least) use (time_t)-1 as an error return.
>
> (time_t)-1 is a valid representation of the last second in 1969, so
> it's only a matter of time before I need this as a valid date.


That's a common practice, but time_t is not actually required to
be encoded this way. (I've a faint recollection that old Windows
versions counted from a different zero point; perhaps they changed
it? No matter, really.)

> I suppose I'm just going to have to ignore this, and work around
> problems as they arise. Thoughts? A better way to do this? If you've
> got a database with dates in it, do you use time_t, or something else?


If your dates will remain on the system where they were originally
computed (or on compatible systems), and if you know that they're in
range for that system's time_t, go ahead and use it. But if there's
a chance that they'll need to move to another system or that they might
get outside time_t's span (as in your case), I think you'd do better
to adopt another representation. Unless you have a compelling reason
not to use it, ISO 8601 looks attractive.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
Dom Bannon
Guest
Posts: n/a
 
      05-06-2010
On Thu, 06 May 2010 06:03:16 -0500, Sam <(E-Mail Removed)> wrote:

>(time_t)-1 is used as an error indication by library functions whose domain
>is defined solely as Jan 1, 1970, and after. There is no ambiguity in those
>cases.


Curious - I haven't found that in the C spec (1999-12-01, 7.23.2.3,
7.23.2.4). I haven't checked the C++ spec.

-Dom
 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      05-06-2010
On May 6, 8:27*am, Dom Bannon <(E-Mail Removed)> wrote:
> On Thu, 06 May 2010 06:03:16 -0500, Sam <(E-Mail Removed)> wrote:
> >(time_t)-1 is used as an error indication by library functions whose domain
> >is defined solely as Jan 1, 1970, and after. There is no ambiguity in those
> >cases.

>
> Curious - I haven't found that in the C spec (1999-12-01, 7.23.2.3,
> 7.23.2.4). I haven't checked the C++ spec.
>
> -Dom


man 2 time

RETURN VALUE
On success, the value of time in seconds since the Epoch is
returned. On error, ((time_t) -1) is returned, and errno is set
appropriately.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-06-2010
Sam <(E-Mail Removed)> writes:
> Dom Bannon writes:
>> I need to represent dates going back to, potentially, ~1900 (on
>> Windows and Linux). The obvious way to do this is to use a time_t, but
>> this seems to have a flaw in that various library routines (mktime and
>> time, at least) use (time_t)-1 as an error return.
>>
>> (time_t)-1 is a valid representation of the last second in 1969, so
>> it's only a matter of time before I need this as a valid date.
>>
>> I suppose I'm just going to have to ignore this, and work around
>> problems as they arise. Thoughts? A better way to do this? If you've
>> got a database with dates in it, do you use time_t, or something else?

>
> (time_t)-1 is used as an error indication by library functions whose domain
> is defined solely as Jan 1, 1970, and after. There is no ambiguity in those
> cases.
>
> If you need to work with date values before Jan 1, 1970, you'll have to
> defined your own class, and provide methods for mapping your date value
> to/from a time_t for the date ranges that time_t can represent.


(time_t)-1 is an error indication for the time() function, *not* for the
time_t type. No functions other than time() treat (time_t)-1 specially.

The C standard says only that time_t is an arithmetic type capable of
representing times. I presume the C++ standard says the same thing.
(The cross-post to comp.lang.c and comp.lang.c++ probably wasn't a good
idea.)

The most common time_t representation is a signed integer representing
the number of seconds since 1970-01-01 00:00:00 GMT. On systems I've
used, negative values are handled normally and can be used to
represent times before 1970. (time_t)-1 is going to be a problem
only if you set your system clock back to the end of 1969 and call
the time() function. But if time_t is 32 bits (which is still
very common), the earliest representable time is some time on December
13, 1901, so it's probably not going to be suitable for the OP's
requirements.

One possibility is to use a 64-bit signed integer representing seconds
since some epoch other than 1970. For most systems, converting between
time_t and this representation is just a matter of converting and adding
or subtracting an offset. If you ever need to run on a system that uses
some exotic time_t representation, you can write conversion functions
for that system.

I would have suggested using 1970 as the epoch, but then bugs in which
you forget to do the conversion would be very hard to track down.

Or you can just use seconds since 1970 (in 64 bits) and not worry about
supporting systems that use a different epoch and/or granularity. If
you ever do need to support such a system, you'll have a lot of redesign
to do, but that's unlikely to happen.

Or you can represent times as character strings in ISO 8601 format.
For example, the current time is 2010-05-06 15:54:58 UTC.

Decide in advance what you want to do about time zones. Since you're
dealing with times back to 1900, leap seconds probably aren't a
concern, but take a moment to convince yourself you can safely
ignore them.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-06-2010
William Ahern <william@wilbur.25thandClement.com> writes:
> Dom Bannon <(E-Mail Removed)> wrote:
>> I need to represent dates going back to, potentially, ~1900 (on
>> Windows and Linux). The obvious way to do this is to use a time_t, but
>> this seems to have a flaw in that various library routines (mktime and
>> time, at least) use (time_t)-1 as an error return.

>
> time_t doesn't represent a calendar date, it stores a value from the system
> clock. The only type in C defined to store a calendar date is struct tm.


Yes, but there's a one-to-one correspondence between calendar
dates and system clock values, and standard functions to convert
between them.

[...]

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Michael Angelo Ravera
Guest
Posts: n/a
 
      05-06-2010
On May 6, 2:04*am, Dom Bannon <(E-Mail Removed)> wrote:
> I need to represent dates going back to, potentially, ~1900 (on
> Windows and Linux). The obvious way to do this is to use a time_t, but
> this seems to have a flaw in that various library routines (mktime and
> time, at least) use (time_t)-1 as an error return.
>
> (time_t)-1 is a valid representation of the last second in 1969, so
> it's only a matter of time before I need this as a valid date.
>
> I suppose I'm just going to have to ignore this, and work around
> problems as they arise. Thoughts? A better way to do this? If you've
> got a database with dates in it, do you use time_t, or something else?


I've used time64, the number of microseconds since the last calendral
convergence which also is the base for JulianDates.

struct timeb t2;
ftime (& t2);
return ((_int64)t2.time * 1000 + t2.millitm) * 1000 +
210866760000000000;


 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-06-2010
William Ahern <william@wilbur.25thandClement.com> writes:
> Keith Thompson <(E-Mail Removed)> wrote:
>> William Ahern <william@wilbur.25thandClement.com> writes:
>> > Dom Bannon <(E-Mail Removed)> wrote:
>> >> I need to represent dates going back to, potentially, ~1900 (on
>> >> Windows and Linux). The obvious way to do this is to use a time_t, but
>> >> this seems to have a flaw in that various library routines (mktime and
>> >> time, at least) use (time_t)-1 as an error return.
>> >
>> > time_t doesn't represent a calendar date, it stores a value from
>> > the system clock. The only type in C defined to store a calendar
>> > date is struct tm.

>
>> Yes, but there's a one-to-one correspondence between calendar
>> dates and system clock values, and standard functions to convert
>> between them.

>
> There isn't a one-to-one correspondence where the system clock has
> sub-second granularity, nor is there a one-to-one correspondence for a clock
> tracking TAI intead of UTC*. And there isn't necessarily any fixed
> correspondence for some leap second schemes.


Conceded.

[...]

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-07-2010
On 6 May, 12:03, Sam <(E-Mail Removed)> wrote:
> Dom Bannon writes:
> > I need to represent dates going back to, potentially, ~1900
> > (on Windows and Linux). The obvious way to do this is to use
> > a time_t, but this seems to have a flaw in that various
> > library routines (mktime and time, at least) use (time_t)-1
> > as an error return.


> > (time_t)-1 is a valid representation of the last second in
> > 1969, so it's only a matter of time before I need this as
> > a valid date.


> > I suppose I'm just going to have to ignore this, and work
> > around problems as they arise. Thoughts? A better way to do
> > this? If you've got a database with dates in it, do you use
> > time_t, or something else?


> (time_t)-1 is used as an error indication by library functions
> whose domain is defined solely as Jan 1, 1970, and after.
> There is no ambiguity in those cases.


That's true for Unix, but the C standard is much, much looser.
The domain is implementation defined (and could reasonably start
much later than Jan. 1, 1970), and the C standard doesn't even
guarantee that time_t is an integral type (although it must be
numeric).

> If you need to work with date values before Jan 1, 1970,
> you'll have to defined your own class, and provide methods for
> mapping your date value to/from a time_t for the date ranges
> that time_t can represent.


More generally, if you're doing anything with dates more than
a few years from the present, you're unlikely to be able to use
time_t. (Note that this is true for the future as well: where
I work, we sometimes have to calculate 50 years into the future,
or more, and the 32 bit time_t common on most Unixes doesn't
work for this either.)

--
James Kanze
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
time_t problem: representing an error value Dom Bannon C++ 13 05-17-2010 08:40 AM
The maximum value held by a time_t ? Chris McDonald C Programming 4 04-30-2009 07:52 AM
Acessing the "time" Part of time_t Value Mike Copeland C++ 2 11-20-2008 01:43 PM
Incorrect time_t value from time() in signal handler Sven C Programming 18 08-20-2006 08:24 AM
Does C++ have a standard symbol representing the value Pi? Steven T. Hatton C++ 9 04-30-2004 02:35 AM



Advertisments