Partilhar via


Como: Salvar time regiões para um recurso inserido

Um aplicativo com reconhecimento de fuso horário geralmente requer a presença de uma determinada zona de tempo.No entanto, como a disponibilidade dos objetos individuais TimeZoneInfo depende de informações armazenadas no registro do sistema local, até mesmo zonas de tempo que estão usualmente disponíveis podem se tornar ausentes.Além disso, as informações sobre zonas de tempo personalizadas, instanciadas usando-se o método CreateCustomTimeZone, não são armazenadas com outras informações de zona de tempo no registro.Para garantir que essas zonas de tempo estejam disponíveis quando elas são necessárias, você pode salvá-las as serializando, e, posteriormente, restaurando-as por desserialização.

Normalmente, serializar um objeto TimeZoneInfo ocorre à parte do aplicativo com reconhecimento de fuso horário.Dependendo do armazenamento de dados utilizado para armazenar objetos TimeZoneInfo serializados, os dados da zona de tempo podem ser serializados como parte de uma rotina de instalação (por exemplo, quando os dados são armazenados em uma chave de aplicativo do registro), ou como parte de uma rotina utilitária executada antes do aplicativo final ser compilado (por exemplo, quando os dados serializados são armazenados em um arquivo de recurso (.resx) .NET XML).

Adicionalmente ao arquivo de recurso que é compilado com o aplicativo, vários outros depósitos de dados podem ser usados para informações de zona de tempo.Eles incluem o seguinte:

  • O registro.Observe que um aplicativo deve usar as subchaves da sua própria chave de aplicativo para armazenar dados personalizados de zona de tempo, ao invés de utilizar as subchaves de HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones.

  • Arquivos de configuração

  • Outros arquivos de sistema.

Para salvar um zona de tempo serializando-a para um arquivo .resx

  1. Recupere uma zona de tempo existente ou crie uma nova zona de tempo.

    Para recuperar uma zona de tempo existente, consulte Como: Acessar o UTC predefinido e objetos time zona local e Como: Criar uma instância de um objeto TimeZoneInfo.

    Para criar uma nova zona de tempo, chame um das sobrecargas do método CreateCustomTimeZone.Para obter mais informações, consulte Como: Criar zonas time sem regras de ajuste e Como: Criar fusos horários com regras de ajuste.

  2. Chame o método ToSerializedString para criar uma sequência de caracteres que contém os dados da zona de tempo.

  3. Crie uma instância de um objeto StreamWriter através do fornecimento do nome e, opcionalmente, do caminho do arquivo .resx para o construtor da classe StreamWriter.

  4. Crie uma instância de um objeto ResXResourceWriter passando o objeto StreamWriter para o construtor da classe ResXResourceWriter.

  5. Passe a sequência de caracteres serializada da zona de tempo para o método ResXResourceWriter.AddResource.

  6. Chame o método ResXResourceWriter.Generate.

  7. Chame o método ResXResourceWriter.Close.

  8. Feche o objeto StreamWriter chamando o método Close.

  9. Adicione o arquivo .resx gerado ao projeto Visual Studio do aplicativo.

  10. Usando a janela Properties no Visual Studio, certifique-se de que a propriedade Build Action do arquivo .resx está definida como Embedded Resource.

Exemplo

O exemplo a seguir serializa um TimeZoneInfo objeto que representa a time padrão central e um TimeZoneInfo objeto que representa o Palmer Station, Antártida time para um arquivo de recurso .NET XML chamado SerializedTimeZones.resx. time padrão Central normalmente é definida no registro; Palmer Station, Antártida é um fuso horário personalizadas.

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
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();
}

Este exemplo serializa os objetos TimeZoneInfo para que eles fiquem disponíveis em um arquivo de recurso em tempo de compilação.

Pelo fato do método ResXResourceWriter.Generate adicionar informações de cabeçalho completo a um arquivo XML de recurso .NET, ele não pode ser usado para adicionar recursos a um arquivo existente.O exemplo lida com isso verificando a existência do arquivo SerializedTimeZones.resx e, se ele existir, armazenando todos seus recursos, diferentes das duas zonas de tempo serializadas, em um objeto Dictionary<TKey, TValue> genérico.O arquivo existente é, então, excluído e os recursos existentes são adicionados a um novo arquivo SerializedTimeZones.resx.Os dados serializado zona de tempo também são adicionados a esse arquivo.

Os campos chave (ou Nome) de recursos não devem conter espaços incorporados.O método Replace(String, String) é chamado para remover todos os espaços incorporados em identificadores de zona de tempo antes que eles sejam atribuídos ao arquivo de recurso.

Compilando o código

Este exemplo requer:

  • Que uma referência a System.Windows.Forms.dll e System.Core.dll seja adicionada ao projeto.

  • Que os seguintes espaços de nome sejam importados:

    Imports System.Globalization
    Imports System.IO
    Imports System.Reflection
    Imports System.Resources
    
    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;
    

Consulte também

Tarefas

Como: restauração time zonas a partir de um recurso inserido

Conceitos

Visão geral do fuso horário

Outros recursos

Horários e Zonas de Tempo