多くの場合、タイム ゾーン対応アプリケーションでは、特定のタイム ゾーンが存在する必要があります。 ただし、個々の TimeZoneInfo オブジェクトの可用性はローカル システムのレジストリに格納されている情報に依存するため、通常使用できるタイム ゾーンも存在しない可能性があります。 さらに、 CreateCustomTimeZone メソッドを使用してインスタンス化されたカスタム タイム ゾーンに関する情報は、レジストリ内の他のタイム ゾーン情報と共に格納されません。 これらのタイム ゾーンが必要なときに使用できるようにするには、それらをシリアル化して保存し、後で逆シリアル化して復元します。
通常、 TimeZoneInfo オブジェクトのシリアル化は、タイム ゾーン対応アプリケーションとは別に行われます。 シリアル化された TimeZoneInfo オブジェクトを保持するために使用されるデータ ストアによっては、タイム ゾーン データがセットアップまたはインストール ルーチンの一部としてシリアル化される場合があります (たとえば、データがレジストリのアプリケーション キーに格納されている場合など)、または最終的なアプリケーションがコンパイルされる前に実行されるユーティリティ ルーチンの一部として (シリアル化されたデータが .NET XML リソース (.resx) ファイルに格納されている場合など)。
アプリケーションでコンパイルされたリソース ファイルに加えて、タイム ゾーン情報には他のいくつかのデータ ストアを使用できます。 これには以下が含まれます。
レジストリ。 アプリケーションでは、HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zonesのサブキーを使用するのではなく、独自のアプリケーション キーのサブキーを使用してカスタム タイム ゾーン データを格納する必要があることに注意してください。
構成ファイル。
その他のシステム ファイル。
タイム ゾーンを .resx ファイルにシリアル化して保存するには
既存のタイム ゾーンを取得するか、新しいタイム ゾーンを作成します。
既存のタイム ゾーンを取得するには、「 方法: 定義済みの UTC オブジェクトとローカル タイム ゾーン オブジェクトにアクセス する」および「 方法: TimeZoneInfo オブジェクトをインスタンス化する」を参照してください。
新しいタイム ゾーンを作成するには、 CreateCustomTimeZone メソッドのいずれかのオーバーロードを呼び出します。 詳細については、「 方法: 調整規則のないタイム ゾーンを作成する 」および 「方法: 調整規則を使用してタイム ゾーンを作成する」を参照してください。
ToSerializedString メソッドを呼び出して、タイム ゾーンのデータを含む文字列を作成します。
名前と必要に応じて .resx ファイルのパスをStreamWriter クラス コンストラクターに指定して、StreamWriter オブジェクトをインスタンス化します。
ResXResourceWriter クラス コンストラクターにStreamWriter オブジェクトを渡して、ResXResourceWriter オブジェクトをインスタンス化します。
タイム ゾーンのシリアル化された文字列を ResXResourceWriter.AddResource メソッドに渡します。
ResXResourceWriter.Generate メソッドを呼び出します。
ResXResourceWriter.Close メソッドを呼び出します。
Close メソッドを呼び出して、StreamWriter オブジェクトを閉じます。
生成された .resx ファイルをアプリケーションの Visual Studio プロジェクトに追加します。
Visual Studio の [プロパティ ] ウィンドウを使用して、.resx ファイルの ビルド アクション プロパティが 埋め込みリソースに設定されていることを確認します。
例
次の例では、中央標準時を表す TimeZoneInfo オブジェクトと、南極時間である Palmer Station を表す TimeZoneInfo オブジェクトを、SerializedTimeZones.resx という名前の .NET XML リソース ファイルにシリアル化します。 通常、中央標準時はレジストリで定義されます。南極のパーマー駅はカスタム タイム ゾーンです。
TimeZoneSerialization()
{
TextWriter writeStream;
Dictionary<string, string> resources = new Dictionary<string, string>();
// Determine if .resx file exists
if (File.Exists(resxName))
{
// Open reader
TextReader readStream = new StreamReader(resxName);
ResXResourceReader resReader = new ResXResourceReader(readStream);
foreach (DictionaryEntry item in resReader)
{
if (! (((string) item.Key) == "CentralStandardTime" ||
((string) item.Key) == "PalmerStandardTime" ))
resources.Add((string)item.Key, (string) item.Value);
}
readStream.Close();
// Delete file, since write method creates duplicate xml headers
File.Delete(resxName);
}
// Open stream to write to .resx file
try
{
writeStream = new StreamWriter(resxName, true);
}
catch (FileNotFoundException e)
{
// Handle failure to find file
Console.WriteLine($"{e.GetType().Name}: The file {resxName} could not be found.");
return;
}
// Get resource writer
ResXResourceWriter resWriter = new ResXResourceWriter(writeStream);
// Add resources from existing file
foreach (KeyValuePair<string, string> item in resources)
{
resWriter.AddResource(item.Key, item.Value);
}
// Serialize Central Standard Time
try
{
TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
resWriter.AddResource(cst.Id.Replace(" ", string.Empty), cst.ToSerializedString());
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("The Central Standard Time zone could not be found.");
}
// Create time zone for Palmer, Antarctica
//
// Define transition times to/from DST
TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0),
10, 2, DayOfWeek.Sunday);
TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0),
3, 2, DayOfWeek.Sunday);
// Define adjustment rule
TimeSpan delta = new TimeSpan(1, 0, 0);
TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1),
DateTime.MaxValue.Date, delta, startTransition, endTransition);
// Create array for adjustment rules
TimeZoneInfo.AdjustmentRule[] adjustments = {adjustment};
// Define other custom time zone arguments
string DisplayName = "(GMT-04:00) Antarctica/Palmer Time";
string standardName = "Palmer Standard Time";
string daylightName = "Palmer Daylight Time";
TimeSpan offset = new TimeSpan(-4, 0, 0);
TimeZoneInfo palmer = TimeZoneInfo.CreateCustomTimeZone(standardName, offset, DisplayName, standardName, daylightName, adjustments);
resWriter.AddResource(palmer.Id.Replace(" ", String.Empty), palmer.ToSerializedString());
// Save changes to .resx file
resWriter.Generate();
resWriter.Close();
writeStream.Close();
}
Private Sub SerializeTimeZones()
Dim writeStream As TextWriter
Dim resources As New Dictionary(Of String, String)
' Determine if .resx file exists
If File.Exists(resxName) Then
' Open reader
Dim readStream As TextReader = New StreamReader(resxName)
Dim resReader As New ResXResourceReader(readStream)
For Each item As DictionaryEntry In resReader
If Not (CStr(item.Key) = "CentralStandardTime" Or _
CStr(item.Key) = "PalmerStandardTime") Then
resources.Add(CStr(item.Key), CStr(item.Value))
End If
Next
readStream.Close()
' Delete file, since write method creates duplicate xml headers
File.Delete(resxName)
End If
' Open stream to write to .resx file
Try
writeStream = New StreamWriter(resxName, True)
Catch e As FileNotFoundException
' Handle failure to find file
Console.WriteLine("{0}: The file {1} could not be found.", e.GetType().Name, resxName)
Exit Sub
End Try
' Get resource writer
Dim resWriter As ResXResourceWriter = New ResXResourceWriter(writeStream)
' Add resources from existing file
For Each item As KeyValuePair(Of String, String) In resources
resWriter.AddResource(item.Key, item.Value)
Next
' Serialize Central Standard Time
Try
Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
resWriter.AddResource(cst.Id.Replace(" ", String.Empty), cst.ToSerializedString())
Catch
Console.WriteLine("The Central Standard Time zone could not be found.")
End Try
' Create time zone for Palmer, Antarctica
'
' Define transition times to/from DST
Dim startTransition As TimeZoneInfo.TransitionTime = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#4:00:00 AM#, 10, 2, DayOfWeek.Sunday)
Dim endTransition As TimeZoneInfo.TransitionTime = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#3:00:00 AM#, 3, 2, DayOfWeek.Sunday)
' Define adjustment rule
Dim delta As TimeSpan = New TimeSpan(1, 0, 0)
Dim adjustment As TimeZoneInfo.AdjustmentRule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#10/1/1999#, Date.MaxValue.Date, delta, startTransition, endTransition)
' Create array for adjustment rules
Dim adjustments() As TimeZoneInfo.AdjustmentRule = {adjustment}
' Define other custom time zone arguments
Dim DisplayName As String = "(GMT-04:00) Antarctica/Palmer Time"
Dim standardName As String = "Palmer Standard Time"
Dim daylightName As String = "Palmer Daylight Time"
Dim offset As TimeSpan = New TimeSpan(-4, 0, 0)
Dim palmer As TimeZoneInfo = TimeZoneInfo.CreateCustomTimeZone(standardName, offset, DisplayName, standardName, daylightName, adjustments)
resWriter.AddResource(palmer.Id.Replace(" ", String.Empty), palmer.ToSerializedString())
' Save changes to .resx file
resWriter.Generate()
resWriter.Close()
writeStream.Close()
End Sub
この例では、 TimeZoneInfo オブジェクトをシリアル化して、コンパイル時にリソース ファイルで使用できるようにします。
ResXResourceWriter.Generate メソッドは完全なヘッダー情報を .NET XML リソース ファイルに追加するため、既存のファイルにリソースを追加するために使用することはできません。 この例では、SerializedTimeZones.resx ファイルをチェックし、存在する場合は、シリアル化された 2 つのタイム ゾーン以外のすべてのリソースを汎用 Dictionary<TKey,TValue> オブジェクトに格納することで、これを処理します。 その後、既存のファイルが削除され、既存のリソースが新しい SerializedTimeZones.resx ファイルに追加されます。 シリアル化されたタイム ゾーン データもこのファイルに追加されます。
リソースのキー (または 名前) フィールドには、埋め込みスペースを含めることはできません。 Replace(String, String)メソッドは、リソース ファイルに割り当てられる前に、タイム ゾーン識別子内のすべての埋め込みスペースを削除するために呼び出されます。
コードのコンパイル
この例では、次のものが必要です。
System.Windows.Forms.dll と System.Core.dll への参照がプロジェクトに追加されます。
次の名前空間がインポートされていること。
using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Reflection; using System.Resources; using System.Windows.Forms;
Imports System.Globalization Imports System.IO Imports System.Reflection Imports System.Resources
こちらもご覧ください
.NET