【.NET】TimeZoneInfo の DisplayName から TimeZoneInfo を生成する

# はじめに
この記事は .NET 6 のバージョンを使っています。

.NET の TimeZoneInfo クラスで GetSystemTimeZones() メソッドは、ローカルシステムで使用できるすべてのタイムゾーンのコレクションを並べ替えられた状態で返します。

以下のコードは取得したタイムゾーンの DisplayName を出力しています。

```cs
foreach (TimeZoneInfo timeZoneInfo in TimeZoneInfo.GetSystemTimeZones())
{
    Console.WriteLine(timeZoneInfo.DisplayName);
}
```

結果はこんな感じ
```
(UTC-12:00) 国際日付変更線 西側
(UTC-11:00) 協定世界時-11
(UTC-10:00) アリューシャン諸島
(UTC-10:00) ハワイ
(UTC-09:30) マルキーズ諸島
(UTC-09:00) アラスカ
(UTC-09:00) 協定世界時-09
(UTC-08:00) バハカリフォルニア
(UTC-08:00) 協定世界時-08
(UTC-08:00) 太平洋標準時 (米国およびカナダ)
(UTC-07:00) アリゾナ
(UTC-07:00) チワワ、ラパス、マサトラン
(UTC-07:00) ユーコン
(UTC-07:00) 山地標準時 (米国およびカナダ)
(UTC-06:00) イースター島
(UTC-06:00) グアダラハラ、メキシコシティ、モンテレー
(UTC-06:00) サスカチュワン
(UTC-06:00) 中央アメリカ
(UTC-06:00) 中部標準時 (米国およびカナダ)
(UTC-05:00) インディアナ東部
(UTC-05:00) タークス・カイコス諸島
(UTC-05:00) チェトゥマル
(UTC-05:00) ハイチ
(UTC-05:00) ハバナ
(UTC-05:00) ボゴタ、リマ、キト、リオ ブランコ
(UTC-05:00) 東部標準時 (米国およびカナダ)
(UTC-04:00) アスンシオン
(UTC-04:00) カラカス
(UTC-04:00) クイアバ
(UTC-04:00) サンティアゴ
(UTC-04:00) ジョージタウン、ラパス、マナウス、サンフアン
(UTC-04:00) 大西洋標準時 (カナダ)
(UTC-03:30) ニューファンドランド
(UTC-03:00) アラグァイナ
(UTC-03:00) カイエンヌ、フォルタレザ
(UTC-03:00) グリーンランド
(UTC-03:00) サルバドル
(UTC-03:00) サンピエール・ミクロン
(UTC-03:00) ブエノスアイレス
(UTC-03:00) ブラジリア
(UTC-03:00) プンタアレーナス
(UTC-03:00) モンテビデオ
(UTC-02:00) 中央大西洋 - 廃止
(UTC-02:00) 協定世界時-02
(UTC-01:00) アゾレス諸島
(UTC-01:00) カーボベルデ諸島
(UTC) 協定世界時
(UTC+00:00) サントメ
(UTC+00:00) ダブリン、エジンバラ、リスボン、ロンドン
(UTC+00:00) モンロビア、レイキャビク
(UTC+01:00) カサブランカ
(UTC+01:00) アムステルダム、ベルリン､ベルン、ローマ､ストックホルム､ウィーン
(UTC+01:00) サラエボ、スコピエ、ワルシャワ、ザグレブ
(UTC+01:00) ブリュッセル、コペンハーゲン、マドリード、パリ
(UTC+01:00) ベオグラード、ブラチスラバ、ブダペスト、リュブリャナ、プラハ
(UTC+01:00) 西中央アフリカ
(UTC+02:00) アテネ、ブカレスト
(UTC+02:00) アンマン
(UTC+02:00) ウィントフック
(UTC+02:00) エルサレム
(UTC+02:00) カイロ
(UTC+02:00) カリーニングラード
(UTC+02:00) ガザ、ヘブロン
(UTC+02:00) キシナウ
(UTC+02:00) ジュバ
(UTC+02:00) ダマスカス
(UTC+02:00) トリポリ
(UTC+02:00) ハラーレ、プレトリア
(UTC+02:00) ハルツーム
(UTC+02:00) ヘルシンキ、キエフ、リガ、ソフィア、タリン、ビリニュス
(UTC+02:00) ベイルート
(UTC+03:00) イスタンブール
(UTC+03:00) クウェート、リヤド
(UTC+03:00) ナイロビ
(UTC+03:00) バグダッド
(UTC+03:00) ミンスク
(UTC+03:00) モスクワ、サンクトペテルブルク
(UTC+03:00) ヴォルゴグラード
(UTC+03:30) テヘラン
(UTC+04:00) アストラハン、ウリヤノフスク
(UTC+04:00) アブダビ、マスカット
(UTC+04:00) イジェフスク、サマーラ
(UTC+04:00) エレバン
(UTC+04:00) サラトフ
(UTC+04:00) トビリシ
(UTC+04:00) バク
(UTC+04:00) ポート ルイス
(UTC+04:30) カブール
(UTC+05:00) アシハバード、タシケント
(UTC+05:00) イスラマバード、カラチ
(UTC+05:00) エカテリンブルク
(UTC+05:00) クズロルダ
(UTC+05:30) スリジャヤワルダナプラコッテ
(UTC+05:30) チェンナイ、コルカタ、ムンバイ、ニューデリー
(UTC+05:45) カトマンズ
(UTC+06:00) アスタナ
(UTC+06:00) オムスク
(UTC+06:00) ダッカ
(UTC+06:30) ヤンゴン (ラングーン)
(UTC+07:00) クラスノヤルスク
(UTC+07:00) トムスク
(UTC+07:00) ノボシビルスク
(UTC+07:00) バルナウル、ゴルノ・アルタイスク
(UTC+07:00) バンコク、ハノイ、ジャカルタ
(UTC+07:00) ホブド
(UTC+08:00) イルクーツク
(UTC+08:00) ウランバートル
(UTC+08:00) クアラルンプール、シンガポール
(UTC+08:00) パース
(UTC+08:00) 北京、重慶、香港特別行政区、ウルムチ
(UTC+08:00) 台北
(UTC+08:45) ユークラ
(UTC+09:00) ソウル
(UTC+09:00) チタ
(UTC+09:00) ヤクーツク
(UTC+09:00) 大阪、札幌、東京
(UTC+09:00) 平壌
(UTC+09:30) アデレード
(UTC+09:30) ダーウィン
(UTC+10:00) ウラジオストク
(UTC+10:00) キャンベラ、メルボルン、シドニー
(UTC+10:00) グアム、ポートモレスビー
(UTC+10:00) ブリズベン
(UTC+10:00) ホバート
(UTC+10:30) ロードハウ島
(UTC+11:00) サハリン
(UTC+11:00) ソロモン諸島、ニューカレドニア
(UTC+11:00) チョクルダフ
(UTC+11:00) ノーフォーク島
(UTC+11:00) ブーゲンビル島
(UTC+11:00) マガダン
(UTC+12:00) アナディリ、ペトロパブロフスク・カムチャツキー
(UTC+12:00) オークランド、ウェリントン
(UTC+12:00) フィジー
(UTC+12:00) ペトロパブロフスク-カムチャツキー - 廃止
(UTC+12:00) 協定世界時+12
(UTC+12:45) チャタム諸島
(UTC+13:00) サモア
(UTC+13:00) ヌクアロファ
(UTC+13:00) 協定世界時+13
(UTC+14:00) クリスマス島
```

# 問題
実際にアプリケーションでタイムゾーンを表示する場合はこちらの DisplayName を使って表示すると思います。
ユーザーがタイムゾーンを選択するとこちらの文字列が入力になるので、システム側ではこの文字列を使って TimeZoneInfo クラスを生成したいのですが、DisplayName から TimeZoneInfo クラスを生成するメソッドが用意されていません...。
Id から TimeZoneInfo クラスを生成するFindSystemTimeZoneById() メソッドはありました。

この記事では、この問題を解決するために DisplayName から TimeZoneInfo クラスを生成するメソッドを作成しましたので、紹介します。

# DisplayName から TimeZoneInfo クラスを生成するメソッド
以下のコードになります。
```cs
TimeZoneInfo GetTimeZoneInfoFrom(string displayName)
{
    TimeZoneInfo timeZoneInfo = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault(timeZone => timeZone.DisplayName == timeZoneInfoDisplayName) ?? TimeZoneInfo.Utc;
    return timeZoneInfo;
}
```

内容は最初に紹介した GetSystemTimeZones() メソッドを使ってローカルシステムで使用できるすべてのタイムゾーンのコレクションを取得後、.NET の Linq を使って全探索をし、各タイムゾーンの DisplayName と入力された displayName で最初に一致する TimeZoneInfo を返す仕組みになっています。もし見つからなければ、UTC の TimeZoneInfo を返します。

以上になります！ここまで読んでいただきありがとうございました。

# 参考
- TimeZoneInfo クラス

https://learn.microsoft.com/ja-jp/dotnet/api/system.timezoneinfo?view=net-6.0