Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > mktime

Reply
Thread Tools

mktime

 
 
Anders Wegge Keller
Guest
Posts: n/a
 
      12-06-2012

According to the C2011 draft I have available, the values in the
struct tm, passed to mktime(), are not restricted to the normalized
ranges. (2.27.2.3 §2).

Is this to be taken literally, such that any combination of values in
the tm struct, that corresponds to something that can be expressed in
a time_t is a valid input?

As I read the following paragrahp, that seem to be the case. Which
lead me to think of exxtreme cases like tm_sec, tm_min, tm_hour,
tm_mday and tm_mon all at INT_MAX, and tm_year set to a sufficiently
large negative value.

Am I missing something, or would a conforming implementation have to
handle this?

--
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      12-06-2012
On 12/06/2012 09:25 AM, Anders Wegge Keller wrote:
>
> According to the C2011 draft I have available, the values in the
> struct tm, passed to mktime(), are not restricted to the normalized
> ranges. (2.27.2.3 §2).
>
> Is this to be taken literally, such that any combination of values in
> the tm struct, that corresponds to something that can be expressed in
> a time_t is a valid input?


Yes. This feature, allows performance of date arithmetic. For instance,
take a struct tm that represents 2012-12-06 09:41, subtract 7 from
tm_mday, and pass it to mktime(), which should normalize that struct to
describe 2012-11-29 09:41. This is, in fact, the main thing I've ever
used mktime() for. mktime() has to know how many days there are in each
month, which years are leap years, what day of the week each date is; so
it saves me from having to write all that logic in my own code.

> As I read the following paragrahp, that seem to be the case. Which
> lead me to think of exxtreme cases like tm_sec, tm_min, tm_hour,
> tm_mday and tm_mon all at INT_MAX, and tm_year set to a sufficiently
> large negative value.
>
> Am I missing something, or would a conforming implementation have to
> handle this?


Yes, it would.
--
James Kuyper
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      12-06-2012
On 12/6/2012 9:25 AM, Anders Wegge Keller wrote:
>
> According to the C2011 draft I have available, the values in the
> struct tm, passed to mktime(), are not restricted to the normalized
> ranges. (2.27.2.3 §2).


ITYM 7.27.2.3.

> Is this to be taken literally,


That's the usual way to take normative text ...

> such that any combination of values in
> the tm struct, that corresponds to something that can be expressed in
> a time_t is a valid input?


Yes, keeping in mind that time_t's range is implementation-
defined (7.27.1p4). If the tm_xxx values correspond to a time_t
value in that implementation-defined range, 7.27.2.3p3 requires
mktime() to return that time_t value.

Clearly, the intent is to relieve the programmer of the burden
of all that date arithmetic. If you've got a struct tm representing
some time T and you want to determine the time at T plus 01:23:45,
you can blithely add 1*3600+23*60+45 to the tm_sec field and call
mktime(), and mktime() will figure things out.

> As I read the following paragrahp, that seem to be the case. Which
> lead me to think of exxtreme cases like tm_sec, tm_min, tm_hour,
> tm_mday and tm_mon all at INT_MAX, and tm_year set to a sufficiently
> large negative value.
>
> Am I missing something, or would a conforming implementation have to
> handle this?


I think so. The only out I can imagine is that if mktime()
cannot determine whether Standard or Daylight time prevails, it
may be unable to find "the" corresponding time_t value and could
then return (time_t)-1 to indicate failure. But if the question
boils down to "Must mktime() be careful about overflow in its
internal computations?" I think the answer must be "Yes."

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d
 
Reply With Quote
 
Anders Wegge Keller
Guest
Posts: n/a
 
      12-06-2012
Eric Sosman <(E-Mail Removed)> writes:

> On 12/6/2012 9:25 AM, Anders Wegge Keller wrote:


>> According to the C2011 draft I have available, the values in the
>> struct tm, passed to mktime(), are not restricted to the normalized
>> ranges. (2.27.2.3 §2).


> ITYM 7.27.2.3.


yes.

>> Is this to be taken literally,


> That's the usual way to take normative text ...


As for legislative works, the wording of normative standards doesn't
always mean what the un-initiated takes them to mean.

...

> then return (time_t)-1 to indicate failure. But if the question
> boils down to "Must mktime() be careful about overflow in its
> internal computations?" I think the answer must be "Yes."


I guess my question can be reduced to exactly that.

--
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-06-2012
On 12/6/2012 11:40 AM, Anders Wegge Keller wrote:
> Eric Sosman <(E-Mail Removed)> writes:
>> [...]
>> then return (time_t)-1 to indicate failure. But if the question
>> boils down to "Must mktime() be careful about overflow in its
>> internal computations?" I think the answer must be "Yes."

>
> I guess my question can be reduced to exactly that.


Okay: I'm sticking with "Yes."

FWIW, PJ Plauger seems to agree (he's non-normative, but since
he served on the library subcommittee for the original ANSI Standard,
he's a pretty good indicator of intent). In "The Standard C Library"
he exhibits a sample implementation of mktime(), and in describing
its underpinnings he writes

"You can start with the year 2000, back up 2,000 months,
and advance 2 billion seconds, for example. [...] The
logic is carefully crafted to avoid integer overflow
regardless of argument values."

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-06-2012
Eric Sosman <(E-Mail Removed)> writes:
[...]
> Clearly, the intent is to relieve the programmer of the burden
> of all that date arithmetic. If you've got a struct tm representing
> some time T and you want to determine the time at T plus 01:23:45,
> you can blithely add 1*3600+23*60+45 to the tm_sec field and call
> mktime(), and mktime() will figure things out.

[...]

Or you can add 1 to tm_hour, 23 to tm_min, and 45 to tm_sec, and let
mktime() figure *everything* out.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"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
 
      12-06-2012
Eric Sosman <(E-Mail Removed)> writes:

> On 12/6/2012 11:40 AM, Anders Wegge Keller wrote:
>> Eric Sosman <(E-Mail Removed)> writes:
>>> [...]
>>> then return (time_t)-1 to indicate failure. But if the question
>>> boils down to "Must mktime() be careful about overflow in its
>>> internal computations?" I think the answer must be "Yes."

>>
>> I guess my question can be reduced to exactly that.

>
> Okay: I'm sticking with "Yes."
>
> FWIW, PJ Plauger seems to agree (he's non-normative, but since
> he served on the library subcommittee for the original ANSI Standard,
> he's a pretty good indicator of intent). In "The Standard C Library"
> he exhibits a sample implementation of mktime(), and in describing
> its underpinnings he writes
>
> "You can start with the year 2000, back up 2,000 months,
> and advance 2 billion seconds, for example. [...] The
> logic is carefully crafted to avoid integer overflow
> regardless of argument values."


You can advance 2 billion seconds *if* int is at least 32 bit (tm_sec is
of type int).

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Anders Wegge Keller
Guest
Posts: n/a
 
      12-06-2012
Keith Thompson <(E-Mail Removed)> writes:

> Eric Sosman <(E-Mail Removed)> writes:
> [...]
> > Clearly, the intent is to relieve the programmer of the burden
> > of all that date arithmetic. If you've got a struct tm representing
> > some time T and you want to determine the time at T plus 01:23:45,
> > you can blithely add 1*3600+23*60+45 to the tm_sec field and call
> > mktime(), and mktime() will figure things out.

> [...]
>
> Or you can add 1 to tm_hour, 23 to tm_min, and 45 to tm_sec, and let
> mktime() figure *everything* out.


Yep

I should have thought about this possibility 10 years ago, and spared
myself a lot of trouble.

--
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-06-2012
On 12/6/2012 3:28 PM, Keith Thompson wrote:
> Eric Sosman <(E-Mail Removed)> writes:
>
>> FWIW, PJ Plauger seems to agree (he's non-normative, but since
>> he served on the library subcommittee for the original ANSI Standard,
>> he's a pretty good indicator of intent). In "The Standard C Library"
>> he exhibits a sample implementation of mktime(), and in describing
>> its underpinnings he writes
>>
>> "You can start with the year 2000, back up 2,000 months,
>> and advance 2 billion seconds, for example. [...] The
>> logic is carefully crafted to avoid integer overflow
>> regardless of argument values."

>
> You can advance 2 billion seconds *if* int is at least 32 bit (tm_sec is
> of type int).


Don't complain to me; complain to the quoted author. Besides:

for (int count = 0; count < 100; ++count) {
mktime(tm);
tm->tm_sec += 20000;
}
mktime(tm);
printf("So there, nyaaah!\n");

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-06-2012
On 12/6/2012 5:36 PM, Eric Sosman wrote:
> On 12/6/2012 3:28 PM, Keith Thompson wrote:
>> Eric Sosman <(E-Mail Removed)> writes:
>>
>>> FWIW, PJ Plauger seems to agree (he's non-normative, but since
>>> he served on the library subcommittee for the original ANSI Standard,
>>> he's a pretty good indicator of intent). In "The Standard C Library"
>>> he exhibits a sample implementation of mktime(), and in describing
>>> its underpinnings he writes
>>>
>>> "You can start with the year 2000, back up 2,000 months,
>>> and advance 2 billion seconds, for example. [...] The
>>> logic is carefully crafted to avoid integer overflow
>>> regardless of argument values."

>>
>> You can advance 2 billion seconds *if* int is at least 32 bit (tm_sec is
>> of type int).

>
> Don't complain to me; complain to the quoted author. Besides:
>
> for (int count = 0; count < 100; ++count) {
> mktime(tm);
> tm->tm_sec += 20000;
> }
> mktime(tm);
> printf("So there, nyaaah!\n");


Oh, ratz.

for (int a = 0; a < 1000; ++a) {
for (int b = 0; b < 1000; ++b) {
mktime(tm);
tm->tm_sec += 2000;
}
}
mktime(tm);
printf("So there, this time for sure!\n");

--
Eric Sosman
(E-Mail Removed)d
 
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.mktime problem McBooCzech Python 4 09-05-2005 09:35 AM
mktime segfault Florian Quetting C++ 2 12-31-2004 05:45 PM
time.mktime memory access violation bug Bengt Richter Python 6 11-21-2003 03:07 AM
mktime and DST. Gore C Programming 1 10-07-2003 09:29 AM
GMT equivalent of mktime Rajmohan C Programming 1 07-14-2003 09:27 PM



Advertisments