例えば 2020-03-23T12:00:00.000Z
というUTCでのISO8601形式の文字列をパースしたうえで、指定したタイムゾーンでの時間に変換したいとします。2020-03-23T12:00:00.000Z
であれば、日本標準時(UTC+9)で2020年3月23日21時です。これは次のようなコードで処理できます。
var tokyoStandardTime = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time"); var dateString = "2020-03-23T12:00:00.000Z"; var convertedDate = TimeZoneInfo.ConvertTime(DateTimeOffset.Parse(dateString), tokyoStandardTime)
.NET Coreの場合、タイムゾーンの情報を含んだ特定の日時はDateTimeOffset
構造体を使うのがよいでしょう。
手元の環境(Windows 10およびmcr.microsoft.com/dotnet/core/sdk のLinuxコンテナ)では、Parse
メソッドやTryParse
メソッドでISO8601形式が処理できました。厳密に扱いたい場合はフォーマット文字列を指定するのがよいかもしれません。与えた文字列はUTCでの日時を表現しているので、この時点でDateTimeOffset
オブジェクトではUTCである情報がセットされています。これを異なるタイムゾーンでの同じ日時に変換するためにはTimeZoneInfo.ConvertTime
メソッドを使います。もしくは、TimeZoneInfo
オブジェクトの生成を経由せずにConvertTimeBySystemTimeZoneId
メソッドも利用できます。
TimeZoneのID指定についてはWindowsとLinux環境で異なるので昨日の記事も参考にしてください。
ちなみに次のようなコードは、環境により実行時例外になります。いくつか試したところ、WindowsやWSLのUbuntuでは動くのですが、mcr.microsoft.com/dotnet/core/sdk のLinuxコンテナではエラーになりました。
var tokyoStandardTime = TimeZoneInfo.FindSystemTimeZoneById("Asia/Tokyo"); var dateString = "2020-03-23T12:00:00.000Z"; var convertedDate = new DateTimeOffset(DateTime.Parse(dateString), tokyoStandardTime.BaseUtcOffset);
Exception has occurred: CLR/System.ArgumentException 型 'System.ArgumentException' のハンドルされていない例外が System.Private.CoreLib.dll で発生しました: 'The UTC Offset of the local dateTime parameter does not match the offset argument.'
素直にドキュメントでも使われているConvertTime
メソッドを使うのが無難なようです。