Live data from Hacker News

The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

berthub.eu

31–40 of 106 posts

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#31
For those skimmimg the problem is mktime() returns local time, and they want it in UTC. So you need to subtract the timezone used, but the timezone varies by date you feed mktime() and there is no easy way to determime it.

If you are happy for the time to perhaps be wrong around the hours timezone changes, this is an easy hack:

    import time
    def time_mktime_utc(_tuple):
        result = time.mktime(_tuple[:-1] + (0,))
        return result * 2 - time.mktime(time.gmtime(result))
If you are just using it for display this is usually fine as time zone changes are usually timed to happen when nobody is looking.

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#32

For those skimmimg the problem is mktime() returns local time, and they want it in UTC. So you need to subtract the timezone used, but the timezone varies by date you feed mktime() and there is no easy way to determime it. If you are happy for the time to perhaps be wrong around the hours timezone changes, this is an easy hack: import time def time_mktime_utc(_tuple): result = time.mktime(_tuple[:-1] + (0,)) return r…

That is not really the problem.

mktime() parses the time string which lacks any information on time zones

then the article uses timegm() to convert it to unixtime on the assumption that it was in UTC

also it's about C

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#33
post #18

Earlier quoted context omitted.

The core of the UNIX time is seconds since epoch, nothing else. 'Day' has no special place at all. There are calendars for converting to and from dates, including Western-style, but the days in those calendars vary in length because of daylight saving switches and leap seconds for example.

UNIX time ignores leap seconds, so every day is exactly 86400 seconds, and every year is either 365*86400 or 366*86400 seconds. This makes converting from yyyy-mm-dd to UNIX time quite easy, as you can just do `365*86400*(yyyy-1970) + leap_years*86400` to get to yyyy-01-01.

Well yes, in the sense that not all Unix epoch seconds are equally long...

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#34
post #14

Is it a struggle though? They needed to have a locale matching the language of the localised time string they wanted to parse, they needed to use strptime to parse the string, they needed to use timegm() to convert the result to seconds when seen as UTC. The man pages pretty much describe these things. The interface or these things could certainly be nicer, but most of the things they bring up as issues aren't even r…

What's a man page? [cit]

[dead]

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#35

Earlier quoted context omitted.

It is not. int main(void) { struct tm tm = {0}; const char *time_str = "Mon, 20 Jan 2025 06:07:07 GMT"; const char *fmt = "%a, %d %b %Y %H:%M:%S GMT"; // Parse the time string if (strptime(time_str, fmt, &tm) == NULL) { fprintf(stderr, "Error parsing time\n"); return 1; } // Convert to Unix timestamp (UTC) time_t timestamp = timegm(&tm); if (timestamp == -1) { fprintf(stderr, "Error converting to timestamp\n"); retur…

I can't find `timegm` neither in the C99 standard draft nor in POSIX.1-2024. The first sentence of your link reads: >The C/Unix time- and date-handling API is a confusing jungle full of the corpses of failed experiments and various other traps for the unwary, many of them resulting from design decisions that may have been defensible when the originals were written but appear at best puzzling today.

https://man7.org/linux/man-pages/man3/timegm.3.html

It's not posix, but it's pretty available

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#36

Earlier quoted context omitted.

It is not. int main(void) { struct tm tm = {0}; const char *time_str = "Mon, 20 Jan 2025 06:07:07 GMT"; const char *fmt = "%a, %d %b %Y %H:%M:%S GMT"; // Parse the time string if (strptime(time_str, fmt, &tm) == NULL) { fprintf(stderr, "Error parsing time\n"); return 1; } // Convert to Unix timestamp (UTC) time_t timestamp = timegm(&tm); if (timestamp == -1) { fprintf(stderr, "Error converting to timestamp\n"); retur…

I can't find `timegm` neither in the C99 standard draft nor in POSIX.1-2024. The first sentence of your link reads: >The C/Unix time- and date-handling API is a confusing jungle full of the corpses of failed experiments and various other traps for the unwary, many of them resulting from design decisions that may have been defensible when the originals were written but appear at best puzzling today.

Yeah, you're correct that `timegm` is neither part of the C99 standard nor officially specified in POSIX.1-2024 but it is widely supported in practice on many platforms, including glibc, musl, and BSD systems which makes it a pragmatic choice in environments where it is available. Additionally, it is easy to implement it in a portable way when unavailable.

So, while `timegm` is not standardized in C99 or POSIX, it is a practical solution in most real-world environments, and alternatives exist for portability, and thus: handling time in C is not inherently a struggle.

As for the link, it says "You may want to bite the bullet and use timegm(3), even though it’s nominally not portable.", but see what I wrote above.

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#38

Earlier quoted context omitted.

I can't find `timegm` neither in the C99 standard draft nor in POSIX.1-2024. The first sentence of your link reads: >The C/Unix time- and date-handling API is a confusing jungle full of the corpses of failed experiments and various other traps for the unwary, many of them resulting from design decisions that may have been defensible when the originals were written but appear at best puzzling today.

Yeah, you're correct that `timegm` is neither part of the C99 standard nor officially specified in POSIX.1-2024 but it is widely supported in practice on many platforms, including glibc, musl, and BSD systems which makes it a pragmatic choice in environments where it is available. Additionally, it is easy to implement it in a portable way when unavailable. So, while `timegm` is not standardized in C99 or POSIX, it is…

timegm() is even available on Haiku

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#39
post #9

[flagged]

Jeez, read the article. C++20 has such an elegant solution that it has him swooning.

Being truly luxurious, the tz library supports using not just your operating system’s time zone databases, which might lack crucial leap second detail, but can also source the IANA tzdb directly. This allows you to faithfully calculate the actual duration of a plane flight in 1978 that not only passed through a DST change, but also an actual leap second. I don’t swoon easily, but I’m swooning.

Re: The surprising struggle to get a Unix Epoch time from a UTC string in C or C++

#40

The headline doesn’t match the article. As it points out, C++20 has a very nice, and portable, time library. I quibble with the article here, though: in 2025, C++20 is widely available.

Damn, I didn't notice that C++20 added a whole bunch of new features to the std::chrono library! Nice!
Post reply on HN