What is the proper behavior of gmtime()?

R

red floyd

I have a copy of the C++ standard. Unfortunately, I don't have a copy
of the C89 standard, and the question I have is related to something
incorporated by reference.

Specifically, what does the Standard say about the behavior of gmtime()
when the argument is negative (i.e. before the epoch)?

Is it UB? Should gmtime() return NULL/0? Should it return a pointer to
a time_t with valid pre-epoch values?
 
V

Victor Bazarov

red said:
I have a copy of the C++ standard. Unfortunately, I don't have a copy
of the C89 standard, and the question I have is related to something
incorporated by reference.

Perhaps asking in comp.lang.c would make more sense in that case, no?
Specifically, what does the Standard say about the behavior of gmtime()
when the argument is negative (i.e. before the epoch)?

The argument of 'gmtime' is not arithmetic. It's "time_t*". There is no
"epoch" in C90 (C89). You seem to be in the implementation-specific
territory.

One thing is certain that if 'time' function can't function due to absence
(or unavailability) of a system calendar, it returns (time_t)(-1). You
can get 'time_t' from 'mktime', but, again, if the time cannot be
represented, you'd get (time_t)(-1). Don't pass that value to 'gmtime'.
Is it UB? Should gmtime() return NULL/0? Should it return a pointer to
a time_t with valid pre-epoch values?

'gmtime' returns NULL if it cannot convert the value you pass to it.

V
 
R

red floyd

Victor said:
Perhaps asking in comp.lang.c would make more sense in that case, no?

Perhaps, but I don't read comp.lang.c, don't want to spend the time
sifting through any unrelated chaff there, and since the C89 standard is
incorporated (by reference) into the C++ Standard, it would seem to be
relevant and on-topic here.

I'm well aware that gmtime() takes a time_t*. I was wondering what
gmtime is supposed to do if the *value pointed to by its parameter* is
pre-epoch (negative). I had figured that was implicitly understood. I
had forgotten that -1 is the "invalid time_t" value.

So it's implementation specific (what "negative time" does). That's
what I was looking for. Since I'm looking for portability, I'll check
for negative values pre-call, or 0 returns from gmtime.
 
V

Victor Bazarov

red said:
Perhaps, but I don't read comp.lang.c, don't want to spend the time
sifting through any unrelated chaff there, and since the C89 standard is
incorporated (by reference) into the C++ Standard, it would seem to be
relevant and on-topic here.

I'm well aware that gmtime() takes a time_t*. I was wondering what
gmtime is supposed to do if the *value pointed to by its parameter* is
pre-epoch (negative).

Here you go again!.. There is no "epoch". Negative values, except the
single negative value of (-1) can still be valid. Nothing in the Standard
says that 'time_t' is an arithmetic (or integral) type, either. It is
possible that in C++ the type 'time_t' is a user-defined type that simply
has a conversion from, say, 'int', and supplying (-1) creates an object of
type 'time_t' that is somehow "invalid". Since you're not supposed to be
looking at the contents of 'time_t' in a portable program, and only use it
to pass back and forth between time functions, any implementation of that
type is possible.
> I had figured that was implicitly understood.

There is nothing implicit when it comes to Standards. I thought that was
implicitly understood.
> I
had forgotten that -1 is the "invalid time_t" value.

So it's implementation specific (what "negative time" does). That's
what I was looking for. Since I'm looking for portability, I'll check
for negative values pre-call, or 0 returns from gmtime.

You can't portably "check for negative values". It is unspecified that
_any_ negative value of 'time_t' is bad. It specifies that only
(time_t)(-1) is "invalid", meaning that no calendar time is available.

There are two functions in the C Standard Library that return a time_t
value: 'time' and 'mktime'. For all we know they _may_ return something
like (time_t)(-7777) and it should be considered a _valid_ value (in that
particular implementation).

V
 
D

Default User

red said:
I have a copy of the C++ standard. Unfortunately, I don't have a
copy of the C89 standard, and the question I have is related to
something incorporated by reference.

Specifically, what does the Standard say about the behavior of
gmtime() when the argument is negative (i.e. before the epoch)?

Is it UB? Should gmtime() return NULL/0? Should it return a pointer
to a time_t with valid pre-epoch values?


Most of what you ask is implementation-specific. Check your
documentation. Here's what the last public draft of C89 (it's identical
in the C99 draft as well) said:

4.12.3.3 The gmtime function

Synopsis

#include <time.h>
struct tm *gmtime(const time_t *timer);

Description

The gmtime function converts the calendar time pointed to by timer
into a broken-down time, expressed as Coordinated Universal Time
(UTC).

Returns

The gmtime function returns a pointer to that object, or a null
pointer if UTC is not available.




Brian
 
R

red floyd

Victor, Mateusz, and Default User,

Thank you for your help. Not having the C89 spec, I had some
misconceptions about the nature of time_t, based on POSIX experience.

I will make sure to validate returns from gmtime() (luckily it's
encapsulated in only one or two places).
 
D

Default User

Mateusz Åoskot wrote:

Perhaps, you should start from the start...the documentation:
http://www.opengroup.org/onlinepubs/009695399/functions/gmtime.html


Their claims about being "aligned with the ISO C standard" are bogus.

"The gmtime() function shall convert the time in seconds since the
Epoch pointed to by timer into a broken-down time, expressed as
Coordinated Universal Time (UTC)."


There's NO "Epoch" in the C standard, nor does time_t have to represent
any kind of seconds at all. The only thing the standard says about
time_t is that it is an arithmetic type capable of representing times.
It could be a long double with the number of microseconds since the
founding of Rome.

In short, I wouldn't use this as a reference unless you were sure it
applied to your platform. A better source would be the system
documention, if available.




Brian
 
D

Default User

Then almost all related manual pages are wrong, see [snip]

That reflects implementation-specific information. That's a normal and
expected feature of manuals. That's why they exist.

The C standard (and so by inclusion C++), is deliberately vague in this
case. I suspect there were a few common implementations that didn't
handle time anything like the UNIX "epoch" approach at that time. So
they left all this up to the implementation.



Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top