Live data from Hacker News

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

berthub.eu

51–60 of 106 posts

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

#51

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…

And the answer is to use `gmtime()`, which AIX doesn't have and which Windows calls something else, but, whatever, if you need to support AIX you can use an open source library.

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

#52

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.

timegm was finally standardized by C23, and POSIX-2024 mentions it in the FUTURE DIRECTIONS section of mktime. I don't know precisely what happened with POSIX. I think timegm got lost in the shuffle and by the time Austin Group attention turned back to it, it made more sense to let C23 pick it up first so there were no accidental conflicts in specification.[1]

[1] POSIX-2024 incorporates C17, not C23, but in practice the typical POSIX environment going forward will likely be targeting POSIX-2024 + C23, or just POSIX-2024 + extensions; and hopefully neither POSIX nor C will wait as long between standard updates as previously.

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

#53
post #19

Earlier quoted context omitted.

UTC would be marked as +Z Without any marking, it could be anything

No '+'. Noon UTC is "12:00Z".

One factor complicates things a bit: this is one way to encode that the timezone is UTC, but +00:00 is also commonly used for example.

RFC 3339 is nice for this reason. Always UTC and terminated with a Z.

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

#54

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…

"Mon, 20 Jan 2025 06:07:07 GMT" I thought the default output of date(1), with TZ unset, is something like Mon Jan 20 06:07:07 UTC 2025 That's the busybox default anyway

Well, `Mon Jan 20 06:07:07 UTC 2025` does not match `fmt` in the code. My input matches the format string exactly, which is why it works.

You could use `"%a %b %d %H:%M:%S %Z %Y"` for `fmt` (which is indeed the default for `date`) and it would work with yours.

Both results in the same timestamp.

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

#55
post #44

Earlier quoted context omitted.

Starting from timestamp A, how do I find the Unix timestamp B corresponding to exactly 6 months in the future from timestamp B?

Adding or subtracting "months" is inherently difficult because months don't have set lengths, varying from 28 through 31 days. Thus adding one month to May 31 is weird: should that be June 30 or July 1 or some other date? Try not to have to do this sort of thing. You might have to though, and then you'll have to figure out what adding months means for your app.

Welcome to Business Logic. This is where I'd really like pushback to result in things that aren't edgecases.

However you also run into day to day business issues like:

* What if it's now a Holiday and things are closed?

* What if it's some commonly busy time like winter break? (Not quite a single holiday)

* What if a disaster of somekind (even just a burst waterpipe) halts operations in an unplanned way?

Usually flexability needs to be built in. It can be fine to 'target' +3 months, but specify it as something like +3m(-0d:+2w) (so, add '3 months' ignoring the day of month, clamp dom to a valid value, allow 0 days before or 14 days after),

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

#56
post #30

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.

Indeed. The article should be retitled "C still useless in 2025, including time handling".

It would be incorrect, but it's already incorrect as what they're doing isn't really a struggle, so I guess the net result is neutral?

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

#57
post #5
post #3

Earlier quoted context omitted.

UTC is a timezone, though. Or am I misunderstanding what you're saying?

That is fine as long as the input / output is always in UTC... but at the end of the day you often want to communicate that timepoint to a human user (e.g. an appointment time, the time at which some event happened, etc.), which is when our stupid monkey brains expect the ascii string you are showing us to actually make sense in our specific locale (including all of the warts each of those particular timezones have,…

That's a localization task, not timekeeping task.

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

#58
post #19

Earlier quoted context omitted.

No '+'. Noon UTC is "12:00Z".

One factor complicates things a bit: this is one way to encode that the timezone is UTC, but +00:00 is also commonly used for example. RFC 3339 is nice for this reason. Always UTC and terminated with a Z.

RFC 3339 isn't always UTC and doesn't mandate Z, in only removes some extra flexibility of ISO 8601, like comma separator or short syntax.

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

#59

The first rule of thumb is to never use functions from glibc (gmtime, localtime, mktime, etc) because half of them are non-thread-safe, and another half use a global mutex, and they are unreasonably slow. The second rule of thumb is to never use functions from C++, because iostreams are slow, and a stringstream can lead to a silent data loss if an exception is thrown during memory allocation. ClickHouse has the "pars…

I came to make the thread safe comment. Got bit by that myself formatting is8601, would get wrong output... Sometimes.

I won't believe anyone who tells me that handling time in c/c++ isn't perilous.

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

#60
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]

It's where people went for programming information before ChatGPT and even before StackOverflow.
Post reply on HN