Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows and IANA Olson IDs #771

Closed
computerquip opened this issue Jan 20, 2023 · 6 comments
Closed

Windows and IANA Olson IDs #771

computerquip opened this issue Jan 20, 2023 · 6 comments

Comments

@computerquip
Copy link

computerquip commented Jan 20, 2023

I've been trying to figure out how Windows is supposed to interoperate with Olson IDs (e.g. America/Chicago). If I have a configuration file with an Olson ID, how do I figure out the offset of that on Windows compared to system time?

That question led me to here. Basically, Microsoft started shipping a version of ICU that contains mappings from the Windows identifiers to Olson identifiers based on mappings from CLDR. An example of how this could work can be found here. I can then use this (tz) library to do the magic calculations.

Am I overthinking this? Would there be interest in supporting this to some extent for Windows?

@HowardHinnant
Copy link
Owner

If you have the latest MSVC tools, and can set it C++20, this is really easy, and you don't need this lib. And you probably don't even need the offset. You can just ask it to change local time to system time and vice-versa. It is all part of the std library in C++20:

#include <chrono>
#include <iostream>

int
main()
{
    auto now_utc = std::chrono::system_clock::now();
    std::cout << "system time is     " << now_utc << '\n';
    std::chrono::zoned_time zt{"America/Chicago", now_utc};
    std::cout << "Time in Chicago is " << zt << '\n';
}

Example output:

system time is     2023-01-21 01:13:09.687474
Time in Chicago is 2023-01-20 19:13:09.687474 CST

This library can be used if you can not yet move to C++20 (even on Windows). For example:

#include "date/tz.h"
using date::operator<<;

#include <chrono>
#include <iostream>

int
main()
{
    auto now_utc = std::chrono::system_clock::now();
    std::cout << "system time is     " << now_utc << '\n';
    date::zoned_time zt{"America/Chicago", now_utc};
    std::cout << "Time in Chicago is " << zt << '\n';
}

Things are in namespace date instead of namespace std::chrono.

@computerquip
Copy link
Author

computerquip commented Jan 21, 2023

I see, seems I was rather confused about some stuff. I was aware of zoned_time but I couldn't figure out how to make a datetime value such as 2015/12/06 12:00:00.000-America/Chicago convert to the timezone configured to the current system.

Turns out I can just use multiple zoned_time structures and current_zone.

Also, thanks for pointing out that this is available in C++20!

@HowardHinnant
Copy link
Owner

Sounds like you've got it figured out. Fwiw, here's how I would do it:

    zoned_time zt_chicago{"America/Chicago", local_days{2015_y/12/06} + 12h};
    zoned_time zt_local{current_zone(), zt_chicago};
    cout << zt_local << '\n';

which for me just output:

2015-12-06 13:00:00 EST

(I'm in America/New_York)

@computerquip
Copy link
Author

computerquip commented Jan 21, 2023

I'm going to apologize ahead of time for making such a spaghetti and meatballs issue.

So while trying to get this working on Windows, I was actually using the MinGW ecosystem. Unfortunately, neither libc++ or libstdc++ supports the timezone portion of std::chrono (and I don't see any pending patches at the moment). As a result, I'm switching between using std::chrono for MSVC/Windows and using date/tz for everything else. However, for MinGW, it's rather problematic since I can't rely on the system's tzdb meaning I'd have to download and maintain my own database in order to use it with date. If I could use std::chrono, I presumably would not need to do this. I'm writing an otherwise simple configuration parser library and I think this would be... a bit more than people who use the library would expect.

I actually looked at how STL does it, and they appear to once again rely on their ICU library in order to build the initial database meaning there's no need to connect to the internet to download/build a new database nor is there a need to keep the database up to date on the application side. Their ICU libraries are updated through system updates.

Basically, I'm wanting a USE_OS_TZDB for Windows. While I'm aware (especially for Apple apparently) that the system timezone information may be wrong, I'd much prefer that not be my responsibility as a library/application writer.

@computerquip computerquip reopened this Jan 21, 2023
@HowardHinnant
Copy link
Owner

I hear you. But that is realistically not going to happen. I don't have that much time, nor a Windows development environment. Perhaps you could take from the MSVC code that reads from ICU?

@computerquip
Copy link
Author

Welp, turns out Microsoft simply doesn't have a source for up-to-date timezone data, regardless of using the older Windows data or the libicu IANA data. Their version of libicu hasn't updated timezone data in 2 years and this reflects in their implementation of std::chrono which gives a version of 2021a. Fetching remote_version() also appears to give 2021a so I'd assume they're just returning the version in libicu. I've made an issue on their libicu repository but I'm not holding my breath.

For now, I'll go the route of embedding my own timezone information and add a footnote that it may be better to implement timezones using their own format. I'll close this for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants