Share via


Panduan: Menyimpan zona waktu ke sumber daya yang disematkan

Aplikasi yang sadar zona waktu sering memerlukan keberadaan zona waktu tertentu. Namun, karena ketersediaan objek individual TimeZoneInfo tergantung pada informasi yang disimpan di registri sistem lokal, bahkan zona waktu yang tersedia secara khusus mungkin tidak ada. Selain itu, informasi tentang zona waktu kustom yang dibuat instans dengan menggunakan CreateCustomTimeZone metode ini tidak disimpan dengan informasi zona waktu lain di registri. Untuk memastikan bahwa zona waktu ini tersedia saat diperlukan, Anda dapat menyimpannya dengan menserialisasikannya, dan kemudian memulihkannya dengan mendeserialisasikannya.

Biasanya, menserialisasikan TimeZoneInfo objek terjadi selain dari aplikasi yang sadar zona waktu. Bergantung pada penyimpanan data yang digunakan untuk menyimpan TimeZoneInfo objek yang diserialisasikan, data zona waktu dapat diserialisasikan sebagai bagian dari rutinitas pengaturan atau penginstalan (misalnya, ketika data disimpan dalam kunci aplikasi registri), atau sebagai bagian dari rutinitas utilitas yang berjalan sebelum aplikasi akhir dikompilasi (misalnya, ketika data serial disimpan dalam file sumber daya XML .NET (.resx)).

Selain file sumber daya yang dikompilasi dengan aplikasi, beberapa penyimpanan data lainnya dapat digunakan untuk informasi zona waktu. Manfaatnya meliputi:

  • Registri. Perhatikan bahwa aplikasi harus menggunakan subkey kunci aplikasinya sendiri untuk menyimpan data zona waktu kustom daripada menggunakan subkunjuk HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones.

  • File konfigurasi.

  • File sistem lainnya.

Untuk menyimpan zona waktu dengan menserialisasikannya ke file .resx

  1. Ambil zona waktu yang ada atau buat zona waktu baru.

    Untuk mengambil zona waktu yang ada, lihat Cara: Mengakses objek UTC dan zona waktu lokal yang telah ditentukan sebelumnya dan Cara: Membuat instans objek TimeZoneInfo.

    Untuk membuat zona waktu baru, panggil salah satu kelebihan beban CreateCustomTimeZone metode. Untuk informasi selengkapnya, lihat Cara: Membuat zona waktu tanpa aturan penyesuaian dan Cara: Membuat zona waktu dengan aturan penyesuaian.

  2. Panggil ToSerializedString metode untuk membuat string yang berisi data zona waktu.

  3. Buat instans StreamWriter objek dengan memberikan nama dan secara opsional jalur file .resx ke StreamWriter konstruktor kelas.

  4. Buat instans ResXResourceWriter objek dengan meneruskan StreamWriter objek ke ResXResourceWriter konstruktor kelas.

  5. Teruskan string berseri zona waktu ke ResXResourceWriter.AddResource metode.

  6. Panggil ResXResourceWriter.Generate metode.

  7. Panggil ResXResourceWriter.Close metode.

  8. Tutup StreamWriter objek dengan memanggil metodenyaClose.

  9. Tambahkan file .resx yang dihasilkan ke proyek Visual Studio aplikasi.

  10. Menggunakan jendela Properti di Visual Studio, pastikan bahwa properti Tindakan Buat file .resx diatur ke Sumber Daya Tersemat.

Contoh

Contoh berikut menserialisasikan TimeZoneInfo objek yang mewakili Waktu Standar Pusat dan TimeZoneInfo objek yang mewakili Stasiun Palmer, waktu Antartika ke file sumber daya XML .NET yang diberi nama SerializedTimeZones.resx. Waktu Standar Pusat biasanya didefinisikan dalam registri; Stasiun Palmer, Antartika adalah zona waktu kustom.

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

Contoh ini menserialisasikan TimeZoneInfo objek sehingga tersedia dalam file sumber pada waktu kompilasi.

Karena ResXResourceWriter.Generate metode menambahkan informasi header yang lengkap ke file sumber .NET XML, metode tidak dapat digunakan untuk menambahkan sumber daya ke file yang ada. Contoh menangani ini dengan memeriksa file SerializedTimeZones.resx dan, jika ada, menyimpan semua sumber dayanya selain dua zona waktu berseri ke Dictionary<TKey,TValue> objek generik. File yang ada kemudian dihapus dan sumber daya yang ada ditambahkan ke file SerializedTimeZones.resx baru. Data zona waktu yang diserialisasikan juga ditambahkan ke file ini.

Bidang kunci (atau Nama) sumber daya tidak boleh berisi spasi yang disematkan. Metode Replace(String, String) ini dipanggil untuk menghapus semua spasi yang disematkan di pengidentifikasi zona waktu sebelum ditetapkan ke file sumber daya.

Mengompilasi kode

Contoh ini membutuhkan:

  • Bahwa referensi ke System.Windows.Forms.dll dan System.Core.dll ditambahkan ke proyek.

  • Bahwa namespace layanan berikut diimpor:

    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
    

Lihat juga