LoginSignup
0
0

More than 1 year has passed since last update.

tz databaseのタイムゾーン名からWindowsのタイムゾーン名を検索するには

Last updated at Posted at 2022-09-13

結論から言うと ICUが提供するucal_getWindowsTimeZoneIDを用いれば良い。ただし注意点として、tzdatabseのタイムゾーン名とWindowsが独自に持つタイムゾーン名は全射ではないので、やむにやまれず利用するくらいで。

#include <iostream>
#include <string>
#include <string_view>
#include <optional>
#include <icu.h>
std::pair<std::optional<std::u16string>, std::optional<UErrorCode>> getWindowsTimeZoneID(std::u16string_view inna_tz_name)
{
    UErrorCode _{};
    const auto ret = ucal_getWindowsTimeZoneID(inna_tz_name.data(), inna_tz_name.size(), nullptr, -1, &_);
    std::u16string buf;
    buf.resize(ret);
    UErrorCode ec{};
    if (const auto ret2 = ucal_getWindowsTimeZoneID(inna_tz_name.data(), inna_tz_name.size(), buf.data(), buf.size() + 1, &ec); U_FAILURE(ec) || ret2 == 0) {
        return { std::nullopt, ec };
    }
    return { buf, std::nullopt };
}
int main()
{
    std::wcout.imbue(std::locale());
    for (auto&& name : { u"America/Los_Angeles", u"Asia/Tokyo"}) {
        auto&& [val, stat] = getWindowsTimeZoneID(name);
        if (val) {
            std::wcout << reinterpret_cast<const wchar_t*>(val->c_str()) << std::endl;
        }
        if (stat) {
            std::cerr << u_errorName(*stat) << std::endl;
        }
    }
}

以下の2つのライブラリとリンクが必要である。

  • icuuc.lib
  • icuin.lib

https://qiita.com/x768/items/ba4059986bea178c5133

Windowsのタイムゾーン名とtz databaseのタイムゾーン名の変換は、以下の表を使うとよいが、一対一の対応になっていないことに注意。

こうすると表を自分で持たなくてもなんとかなる。

注意点

ucal_getWindowsTimeZoneIDで最後の引数に渡しているエラーコード変数へのポインタについて注意しなければならない。どういうわけかこの関数はエラーコードをセットする前に中身を読み取っている様子があるのだ。

  1. 1回めの呼び出し時に油断してnullptrを渡すともれなくヌルポするからnullptrを渡してはいけない
  2. 初期化されているエラーコード変数へのポインタである必要がある。エラーコードをセットする前に中身を読み取っているということは、未初期化で渡すとUBになるということである
  3. 1回目と2回目で渡すエラーコード変数へのポインタは別のものでなければならない。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0