Posix timezone string to Olson string

603 Views Asked by At

We have an embedded Linux system where the user needs to be able to permanently set the system's timezone by supplying a POSIX string (e.g. WEuropeStandardTime-1DaylightTime,M3.5.0,M10.5.0/3).

The user interacts with the system over a webservice we develop so we have complete control of the implementation. I'm looking for a C/C++ solution.

I've been looking at timedatectl -set-timezone, but it only accepts Olson timezone descriptions, not POSIX timezone strings. I was thinking I could parse the tzdata to find a match for the POSIZ timezone string, but before starting down that path I'd like to know if there is a better way or if there is already a library to do this conversion.

I've discounted setting the TZ environment variable as it is an override for the system date and time set by timedatectl and it feels like a bodge. Also, I'm not sure how I'd set it early enough that all software running from boot would see the same time.

1

There are 1 best solutions below

0
On

What you ask is not possible. There is much more information in the data represented behind an IANA (aka "Olson") time zone identifier than can fit in a POSIX time zone string. In particular a POSIX time zone string can only contain one single pair of transition rules. It provides no facilities for tracking how those rules have changed over time or how they might be scheduled to change in the future. It also doesn't provide for cases where the standard time offset has changed, or where there are more than one pair of transitions in a single year. You can read more about this in the section "POSIX style time zones" towards the bottom of the timezone tag wiki.

However, since you said the user interacts with the system over a web service, you might instead consider projecting a POSIX string. The user would pick an IANA time zone for the device (or you could look it up by location), and you'd store that. Then when communicating with the device, you'd generate a POSIX string to deliver for use on the device over a given period. You'd want to periodically update it, perhaps every time the device checks in or is updated (depending on your scenario).

I know of one commercial offering with this capability built-in: the Azure Maps Timezone API. In its responses, you'll see a PosixTz string. (This was added specifically for IoT scenarios.)

Alternatively, you could do this yourself in your own server-side code. The logic is a bit tricky, but it is indeed possible.

  • If your back end is .NET - you're in luck. My TimeZoneConverter.Posix library can do this for you. For example:

    string posix = PosixTimeZone.FromIanaTimeZoneName("Australia/Sydney");
    // Result: "AEST-10AEDT,M10.1.0,M4.1.0/3"
    
  • If your back end is JavaScript, there's some unsupported code in Moment-Timezone issue #314 that you can leverage or adapt.

  • If your back end is something else, I'm not aware of readily available solutions. However, you may be able to port the code in either of the above to your platform.