Hacker News new | ask | show | jobs
by rstuart4133 521 days ago
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.
3 comments

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.
AIX has gmtime [0], too. Since at least 7.1.

[0] https://www.ibm.com/docs/en/aix/7.1?topic=c-ctime-localtime-...

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

> mktime() parses the time string

No, mktime() doesn't parse a string. Parsing the string is done by strptime(). mktime() takes the output of strptime(), which is a C structure or the equivalent in Python - a named tuple with the same fields.

> the time string lacks any information on time zones

Not necessarily. Time strings often contain a time zone. The string you happen to be parsing doesn't contain a time zone you could always append one. If it did have a time zone you could always change it to UTC. So this isn't the problem either.

The root cause of the issue is the "struct tm" that strptime() outputs didn't have field for the time zone so if the string has one, it is lost. mktime() needs that missing piece of information. It solves that problem by assuming the missing time zone is local time.

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

It does, but timegm() is not a POSIX function so isn't available on most platforms. gmtime() is a POSIX function and is available everywhere. It doesn't convert a "struct tm", but it does allow you to solve the core problem the article labours over, which is finding out what time zone offset mktime() used. With that piece of information it's trivial to convert to UTC, as the above code demonstrates in 2 lines.

> also it's about C

The python "time" module is a very thin wrapper around the POSIX libc functions and structures. There is a one to one correspondence, mostly with the same names. Consequently any experienced C programmer will be able translate the above python to C. I chose Python because it expresses the same algorithm much more concisely.

It is easier in Python:

    >>> from email.utils import parsedate_tz, mktime_tz
    >>> mktime_tz(parsedate_tz("Fri, 17 Jan 2025 06:07:07"))
    1737094027
It converts rfc 2822 time into POSIX timestamp ([mean solar] seconds since epoch--elapsed SI seconds not counting leap seconds).