.NET Coreのタイムゾーン識別ID問題について

前提となる開発環境

開発機 / IDE / Testing Framework

Windows 10、VisualStudio 2019 、xUnit、TestHostも利用

ローカルデバッグ環境

Docker(WSL に Ubuntuをインストールして運用)

Dev,Prod環境

Linux(Ubuntu)

備考

チーム開発をしていて、自分はWindows機だけれど、チームメンバーにはMac機の方もいらっしゃる

.NET CoreでTimeZoneInfo取得しようと思ったら、タイムゾーンを識別するためのIdが、WindowsLinuxで異なる問題

TimeZoneInfoを取得したいだけの人生だったので、安易に

var hoge = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time"));

って書いてしまいがちなのですが、これだと、Windowsでしか動かないコードでした。(Linux環境だとTimeZoneNotFoundExceptionで例外が発生する。)

Linuxだと、

var hoge = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Asia/Tokyo"));

と書くのが正しいらしく、「あ、環境によって識別Id違うんですね。」というお話でした。 そして、この辺、どういうアプローチが正道なのかなと、調べてみると、↓のWebページが出てきました。

devblogs.microsoft.com

要約すると、TimeZoneConverterを利用しましょうということが書いてあります(雑)

TimeZoneConverterを使おう

github.com

TZConvert.GetTimeZoneInfo を利用することで、この識別ID問題を解決してくれます。

なので、どちらのIDを指定しても動作するようになりました。

こんな感じ

var hoge = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TZConvert.GetTimeZoneInfo("Tokyo Standard Time"));

var hoge = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TZConvert.GetTimeZoneInfo("Asia/Tokyo"));

.NET Core / C#マルチプラットフォームになったからこそ気にしなけばならないことがあると感じる

昔はWindowsでしか動かさなかったので、このへんの識別IDもWindows用だけ使えばよかったんですが、.NET Coreになって様々な環境で駆動出来るようになったことで気にしなければならないことがあるんだなあと感じました。

移植容易性に係るお話でもあるので、意識していきたいのと、やっぱりWindows機だと、Linux機で動くかわからないので、ローカルデバッグ環境はDockerで良かったと感じてみたりしました。