More Document Number: N2833
Submitter: Aaron Peter Bachmann
Submission Date: 2021-10-07
Add timegm() as non-optional part of <time.h> to C2X

Summary

For the local time we have localtime() and localtime_r()  to convert from time_t to struct tm and mktime() to convert back. For UTC we have gmtime() and gmtime_r() to convert from time_t to struct tm but the function to convert struct tm to UTC is missing from the C-Standard. This paper proposes the addition of the function time_t timegm(struct tm *timeptr) to fill the gap.

Prior work

Discussion

UTC is often used since UTC is unique around the world. The use of UTC is especially desirable if systems are spanning multiple time-zones or devices move from one time-zone to another. In addition when UTC is used there are fewer configuration issues. Existing protocols, configuration-files and user interfaces and (peripheral) devices (e. g. realtime-clocks) often utilize broken down times. Implementing and testing timegm() over and over again or alternatively locating  a implementation and verifying the code and its licence over and over again is a waste of development-time. Temporarily changing the timezone and using mktime() is bad, since it introduces a race-condition. It has a low implementation burden once you have the source of mktime(). Thus timegm() shall be defined by the C-standard.

Proposed wording

The changes given here are relative to N2596 [4].

After

7.27.2.3 The mktime function

...

add

7.27.2.4 The timegm function

Synopsis

        #include <time.h>
        time_t timegm(struct tm *timeptr);

Description
 The timegm function converts the broken-down time, expressed as UTC time, in the structure pointed to by timeptr into a calendar time value with the same encoding as that of the values returned by the time function. The original values of the tm_wday and tm_yday components of the structure are ignored, and the original values of the other components are not restricted to the ranges indicated above. On successful completion, the values of the tm_wday and tm_yday components of the structure are set appropriately, and the other components are set to represent the specified calendar time, but with their values forced to the ranges indicated above; the final value of tm_mday
is not set until tm_mon and tm_year are determined.

Returns

The mktime function returns the specified calendar time encoded as a value of type time_t. If the calendar time cannot be represented, the function returns the value (time_t)(−1).

Alternative wording (less repetitive):

Description
The timegm function is identical to mktime except that it always takes the input values to be Coordinated Universal Time (UTC) regardless of any local time zone setting.

The sentence above is from the glibc manual [5] with minor tweaks only. Since it is a single sentence, it is assumed the partial reuse is covered by fair use.

and

In B.26 Date and time <time.h>

after

time_t mktime(struct tm *timeptr);

insert:

time_t timegm(struct tm *timeptr);


Additional Questions:

Do we want to change the signatures to

time_t mktime(const struct tm *timeptr)
and
time_t gmtime(const struct tm *timeptr) ?

This might bring us in conflict with POSIX.

Acknowledgements

I want to thank Thomas Kemmer and Reinhard Kopka for helpful comments.

References

[1] N2337 2019/02/03 Stoughton, Proposal To Add Extended Month Name Formats to strftime()

[2] N2417 2019/09/08 Gustedt, Modernize time.h functions v.2x

[3] N2459 2019/11/18 Gustedt, Add an interface to query resolution of time bases v3

[4] N2596 2020/12/12 Meneide, C2x Working Draft

[5] Sandra Loosemore et alt., The GNU C Library Reference Manual