다음을 통해 공유


방법: 포함된 리소스에 표준 시간대 저장

표준 시간대 인식 애플리케이션에는 종종 특정 표준 시간대가 있어야 합니다. 그러나 개별 TimeZoneInfo 개체의 가용성은 로컬 시스템의 레지스트리에 저장된 정보에 따라 달라지므로 일반적으로 사용 가능한 표준 시간대도 없을 수 있습니다. 또한 CreateCustomTimeZone 메서드를 사용하여 인스턴스화된 사용자 지정 표준 시간대에 대한 정보는 레지스트리의 다른 표준 시간대 정보와 함께 저장되지 않습니다. 필요할 때 이러한 표준 시간대를 사용할 수 있도록 하려면 표준 시간대를 직렬화하여 저장하고 나중에 역직렬화하여 복원할 수 있습니다.

일반적으로 TimeZoneInfo 개체 직렬화는 표준 시간대 인식 애플리케이션과는 별도로 발생합니다. 직렬화된 TimeZoneInfo 개체를 저장하는 데 사용되는 데이터 저장소에 따라 표준 시간대 데이터는 설치 또는 설치 루틴(예: 데이터가 레지스트리의 애플리케이션 키에 저장되는 경우)의 일부로 직렬화되거나 최종 애플리케이션이 컴파일되기 전에 실행되는 유틸리티 루틴의 일부로 직렬화될 수 있습니다(예: 직렬화된 데이터가 .NET XML 리소스(.resx) 파일에 저장되면 입니다.

애플리케이션으로 컴파일되는 리소스 파일 외에도 표준 시간대 정보에 다른 여러 데이터 저장소를 사용할 수 있습니다. 여기에는 다음이 포함되었습니다.

  • 레지스트리입니다. 애플리케이션은 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones하위 키를 사용하는 대신 자체 애플리케이션 키의 하위 키를 사용하여 사용자 지정 표준 시간대 데이터를 저장해야 합니다.

  • 구성 파일.

  • 다른 시스템 파일.

표준 시간대를 .resx 파일로 직렬화하여 저장하려면

  1. 기존 표준 시간대를 검색하거나 새 표준 시간대를 만듭니다.

    기존 표준 시간대를 검색하려면 방법: 미리 정의된 UTC 및 현지 표준 시간대 개체 액세스 및 방법: TimeZoneInfo 개체인스턴스화를 참조하세요.

    새 표준 시간대를 만들려면 CreateCustomTimeZone 메서드의 오버로드 중 하나를 호출합니다. 자세한 내용은 방법: 조정 규칙 없이 표준 시간대 만들기 및 방법: 조정 규칙표준 시간대 만들기를 참조하세요.

  2. ToSerializedString 메서드를 호출하여 표준 시간대의 데이터가 포함된 문자열을 만듭니다.

  3. 이름 및 선택적으로 .resx 파일의 경로를 StreamWriter 클래스 생성자에 제공하여 StreamWriter 개체를 인스턴스화합니다.

  4. StreamWriter 개체를 ResXResourceWriter 클래스 생성자에 전달하여 ResXResourceWriter 개체를 인스턴스화합니다.

  5. 표준 시간대의 직렬화된 문자열을 ResXResourceWriter.AddResource 메서드에 전달합니다.

  6. ResXResourceWriter.Generate 메서드를 호출합니다.

  7. ResXResourceWriter.Close 메서드를 호출합니다.

  8. Close 메서드를 호출하여 StreamWriter 개체를 닫습니다.

  9. 생성된 .resx 파일을 애플리케이션의 Visual Studio 프로젝트에 추가합니다.

  10. Visual Studio의 속성 창을 사용하여 .resx 파일의 빌드 작업 속성이 포함된 리소스로 설정되었는지 확인하세요.

예시

다음은 Central Standard Time을 나타내는 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 파일이 존재하는 경우 두 개의 직렬화된 표준 시간대 이외의 모든 리소스를 제네릭 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
    

참고하십시오