👻
.NET CoreでWindowsとLinuxでTimeZoneのIDが異なる
問題
TimeZoneInfo.FindSystemTimeZoneById(String) メソッド でタイムゾーンを取得する際にLinuxで実行するとエラーになる。
テスト用のサンプルコード
// UTC時間を取得
var utcNow = DateTime.UtcNow;
// JSTのタイムゾーンを取得
var jstTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
// UTCからJSTに変更
var jstNow = TimeZoneInfo.ConvertTimeFromUtc(utcNow, jstTimeZoneInfo);
Console.WriteLine("utcNow : " + utcNow.ToString());
Console.WriteLine("jstNow : " + jstNow.ToString());
Windowsで実行
utcNow : 12/02/2023 14:10:06
jstNow : 12/02/2023 23:10:06
Linuxで実行
System.TimeZoneNotFoundException: The time zone ID 'Tokyo Standard Time' was not found on the local computer.
原因
プラットフォームでタイムゾーンのID値が異なる。
Cross-platform Time Zones with .NET Coreの記事によると下記のようにプラットフォームで指定する値が異なるとの事。
Windows
Linux
解決方法
記事によると下記のライブラリを利用する事で指定の差異を吸収できる。
Linuxではtzdata
のライブラリがインストールされている必要がある。
自身の利用シーンでは、UTCとJSTの変換くらいだったので、JSTのタイムゾーンを取得する下記のコードにしました。
プラットフォームによっては一度で取得できずコストが増えるので、ライブラリを使うのがベストプラクティスかもしれません。
public static class Utils
{
/// <summary>
/// JSTのタイムゾーン情報を取得
/// </summary>
public static TimeZoneInfo TZ_JST = GetTimeZone("Asia/Tokyo", "Tokyo Standard Time");
public static TimeZoneInfo GetTimeZone(params string[] names)
{
foreach (var name in names)
{
try { return TimeZoneInfo.FindSystemTimeZoneById(name); }
catch (TimeZoneNotFoundException) { }
}
throw new TimeZoneNotFoundException();
}
}
Discussion