方法: 埋め込みリソースにタイム ゾーンを保存するHow to: Save time zones to an embedded resource

タイムゾーンに対応するアプリケーションでは、多くの場合、特定のタイムゾーンが存在する必要があります。A time zone-aware application often requires the presence of a particular time zone. ただし、個々のオブジェクトの可用性は、 TimeZoneInfo ローカルシステムのレジストリに格納されている情報によって異なるため、通常使用可能なタイムゾーンも存在しない可能性があります。However, because the availability of individual TimeZoneInfo objects depends on information stored in the local system's registry, even customarily available time zones may be absent. また、メソッドを使用してインスタンス化されたカスタムタイムゾーンに関する情報 CreateCustomTimeZone は、他のタイムゾーン情報と共にレジストリに格納されるわけではありません。In addition, information about custom time zones instantiated by using the CreateCustomTimeZone method is not stored with other time zone information in the registry. これらのタイムゾーンが必要なときに確実に使用できるようにするには、それらをシリアル化して保存し、後でそれらを逆シリアル化して復元します。To ensure that these time zones are available when they are needed, you can save them by serializing them, and later restore them by deserializing them.

通常、オブジェクトのシリアル化は、 TimeZoneInfo タイムゾーン対応アプリケーションとは別に行われます。Typically, serializing a TimeZoneInfo object occurs apart from the time zone-aware application. シリアル化されたオブジェクトを保持するために使用するデータストアに応じて TimeZoneInfo 、タイムゾーンデータは、セットアップまたはインストールルーチンの一部としてシリアル化できます (たとえば、データがレジストリのアプリケーションキーに格納されている場合)。または、最終的なアプリケーションをコンパイルする前に実行されるユーティリティルーチンの一部としてシリアル化されます (たとえば、シリアル化されたデータが .NET XML リソース (.resx) ファイルDepending on the data store used to hold serialized TimeZoneInfo objects, time zone data may be serialized as part of a setup or installation routine (for example, when the data is stored in an application key of the registry), or as part of a utility routine that runs before the final application is compiled (for example, when the serialized data is stored in a .NET XML resource (.resx) file).

アプリケーションと共にコンパイルされるリソースファイルに加えて、他のいくつかのデータストアをタイムゾーン情報に使用できます。In addition to a resource file that is compiled with the application, several other data stores can be used for time zone information. 次に例を示します。These include the following:

  • レジストリ。The registry. アプリケーションでは、独自のアプリケーションキーのサブキーを使用して、HKEY_LOCAL_MACHINE \SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones のサブキーを使用するのではなく、カスタムタイムゾーンデータを格納する必要があることに注意してください。Note that an application should use the subkeys of its own application key to store custom time zone data rather than using the subkeys of HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones.

  • 構成ファイル。Configuration files.

  • その他のシステムファイル。Other system files.

.Resx ファイルにシリアル化してタイムゾーンを保存するにはTo save a time zone by serializing it to a .resx file

  1. 既存のタイムゾーンを取得するか、新しいタイムゾーンを作成します。Retrieve an existing time zone or create a new time zone.

    既存のタイムゾーンを取得する方法については、「方法: 定義済みの UTC オブジェクトおよびローカルタイムゾーンオブジェクトにアクセスする」および「方法: TimeZoneInfo オブジェクトをインスタンス化する」を参照してください。To retrieve an existing time zone, see How to: Access the predefined UTC and local time zone objects and How to: Instantiate a TimeZoneInfo object.

    新しいタイムゾーンを作成するには、メソッドのいずれかのオーバーロードを呼び出し CreateCustomTimeZone ます。To create a new time zone, call one of the overloads of the CreateCustomTimeZone method. 詳細については、「方法: 調整規則のないタイムゾーンを作成する」および「方法: 調整規則を使用してタイムゾーンを作成する」を参照してください。For more information, see How to: Create time zones without adjustment rules and How to: Create time zones with adjustment rules.

  2. メソッドを呼び出し ToSerializedString て、タイムゾーンのデータを含む文字列を作成します。Call the ToSerializedString method to create a string that contains the time zone's data.

  3. StreamWriter名前を指定し、必要に応じてクラスコンストラクターに .resx ファイルのパスを指定して、オブジェクトをインスタンス化 StreamWriter します。Instantiate a StreamWriter object by providing the name and optionally the path of the .resx file to the StreamWriter class constructor.

  4. オブジェクトを ResXResourceWriter クラスコンストラクターに渡すことによって、オブジェクトをインスタンス化 StreamWriter ResXResourceWriter します。Instantiate a ResXResourceWriter object by passing the StreamWriter object to the ResXResourceWriter class constructor.

  5. タイムゾーンのシリアル化された文字列をメソッドに渡し ResXResourceWriter.AddResource ます。Pass the time zone's serialized string to the ResXResourceWriter.AddResource method.

  6. ResXResourceWriter.Generate メソッドを呼び出します。Call the ResXResourceWriter.Generate method.

  7. ResXResourceWriter.Close メソッドを呼び出します。Call the ResXResourceWriter.Close method.

  8. StreamWriterメソッドを呼び出して、オブジェクトを閉じ Close ます。Close the StreamWriter object by calling its Close method.

  9. 生成された .resx ファイルをアプリケーションの Visual Studio プロジェクトに追加します。Add the generated .resx file to the application's Visual Studio project.

  10. Visual Studio の [プロパティ] ウィンドウを使用して、.resx ファイルの [ビルドアクション] プロパティが [埋め込みリソース] に設定されていることを確認します。Using the Properties window in Visual Studio, make sure that the .resx file's Build Action property is set to Embedded Resource.

Example

次の例では、中部標準時を表すオブジェクトをシリアル化し、 TimeZoneInfo TimeZoneInfo SerializedTimeZones という名前の .net XML リソースファイルの南極 Time を表すオブジェクトをシリアル化します。The following example serializes a TimeZoneInfo object that represents Central Standard Time and a TimeZoneInfo object that represents the Palmer Station, Antarctica time to a .NET XML resource file that is named SerializedTimeZones.resx. 通常、中部標準時はレジストリで定義されています。パーマーステーション、南極はカスタムタイムゾーンです。Central Standard Time is typically defined in the registry; Palmer Station, Antarctica is a custom time zone.

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("{0}: The file {1} could not be found.", e.GetType().Name, resxName);
      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 は、コンパイル時にリソースファイルで使用できるようにオブジェクトをシリアル化します。This example serializes TimeZoneInfo objects so that they are available in a resource file at compile time.

メソッドは、 ResXResourceWriter.Generate 完全なヘッダー情報を .NET XML リソースファイルに追加するため、既存のファイルにリソースを追加するために使用することはできません。Because the ResXResourceWriter.Generate method adds complete header information to a .NET XML resource file, it cannot be used to add resources to an existing file. この例では、SerializedTimeZones ファイルを確認し、存在する場合は、2つのシリアル化されたタイムゾーン以外のすべてのリソースを汎用オブジェクトに格納することで、この処理を行い Dictionary<TKey,TValue> ます。The example handles this by checking for the SerializedTimeZones.resx file and, if it exists, storing all of its resources other than the two serialized time zones to a generic Dictionary<TKey,TValue> object. その後、既存のファイルが削除され、既存のリソースが新しい SerializedTimeZones ファイルに追加されます。The existing file is then deleted and the existing resources are added to a new SerializedTimeZones.resx file. シリアル化されたタイムゾーンデータもこのファイルに追加されます。The serialized time zone data is also added to this file.

リソースのキー (または名前) フィールドには、空白を埋め込むことはできません。The key (or Name) fields of resources should not contain embedded spaces. Replace(String, String)メソッドは、リソースファイルに割り当てられる前に、タイムゾーン識別子内のすべての埋め込みスペースを削除するために呼び出されます。The Replace(String, String) method is called to remove all embedded spaces in the time zone identifiers before they are assigned to the resource file.

コードのコンパイルCompiling the code

この例で必要な要素は次のとおりです。This example requires:

  • このプロジェクトには、System. .dll と system.servicemodel への参照を追加する必要があります。That a reference to System.Windows.Forms.dll and System.Core.dll be added to the project.

  • 次の名前空間がインポートされます。That the following namespaces be imported:

    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
    

関連項目See also