Aracılığıyla paylaş


Saat dilimlerini kaydetme ve geri yükleme

sınıfı, TimeZoneInfo önceden tanımlanmış saat dilimi verilerini almak için kayıt defterine dayanır. Ancak kayıt defteri dinamik bir yapıdır. Ayrıca, kayıt defterinin içerdiği saat dilimi bilgileri, işletim sistemi tarafından öncelikle geçerli yıla ilişkin zaman ayarlamalarını ve dönüştürmeleri işlemek için kullanılır. Bunun, doğru saat dilimi verilerini kullanan uygulamalar için iki önemli etkisi vardır:

  • Bir uygulamanın gerektirdiği bir saat dilimi kayıt defterinde tanımlanmayabilir veya yeniden adlandırılmış veya kayıt defterinden kaldırılmış olabilir.

  • Kayıt defterinde tanımlanan bir saat diliminde, geçmiş saat dilimi dönüştürmeleri için gerekli olan belirli ayarlama kuralları hakkında bilgi eksik olabilir.

sınıfı, TimeZoneInfo saat dilimi verilerini seri hale getirme (kaydetme) ve seri durumdan çıkarma (geri yükleme) desteği aracılığıyla bu sınırlamaları giderir.

Saat dilimi serileştirme ve seri durumdan çıkarma

Saat dilimi verilerini seri hale getirerek ve seri durumdan çıkararak bir saat dilimini kaydetmek ve geri yüklemek için yalnızca iki yöntem çağrısı gerekir:

  • Bu nesnenin yöntemini çağırarak bir TimeZoneInfo nesneyi ToSerializedString seri hale getirebilirsiniz. yöntemi parametre almaz ve saat dilimi bilgilerini içeren bir dize döndürür.

  • Bu dizeyi (Shared Visual Basic'te) TimeZoneInfo.FromSerializedString yöntemine geçirerek serileştirilmiş bir dizeden bir nesnenin seri durumdan static çıkarabilirsinizTimeZoneInfo.

Serileştirme ve seri durumdan çıkarma senaryoları

Bir nesneyi bir TimeZoneInfo dizeye kaydetme (veya seri hale getirme) ve daha sonra kullanmak üzere geri yükleme (veya seri durumdan çıkarma) özelliği hem yardımcı programı hem de sınıfın esnekliğini TimeZoneInfo artırır. Bu bölümde serileştirme ve seri durumdan çıkarmanın en yararlı olduğu bazı durumlar incelenir.

Bir uygulamada saat dilimi verilerini seri hale getirme ve seri durumdan çıkarma

Seri hale getirilmiş bir saat dilimi gerektiğinde bir dizeden geri yüklenebilir. Kayıt defterinden alınan saat dilimi belirli bir tarih aralığındaki bir tarih ve saati doğru şekilde dönüştüremezse, uygulama bunu yapabilir. Örneğin, Windows XP kayıt defterindeki saat dilimi verileri tek bir ayarlama kuralını desteklerken, Windows Vista kayıt defterinde tanımlanan saat dilimleri genellikle iki ayarlama kuralı hakkında bilgi sağlar. Bu, geçmiş zaman dönüştürmelerinin yanlış olabileceği anlamına gelir. Saat dilimi verilerini seri hale getirme ve seri durumdan çıkarma bu sınırlamayı işleyebilir.

Aşağıdaki örnekte, Birleşik Devletler yaz saati kullanılmadan önce, 1883 ile 1917 arasındaki ABD Doğu Standart Saat dilimini temsil etmek için ayarlama kuralları olmayan özel TimeZoneInfo bir sınıf tanımlanmıştır. Özel saat dilimi, genel kapsama sahip bir değişkende seri hale getirilir. Saat dilimi dönüştürme yöntemi, ConvertUtcTimedönüştürülmek üzere Eşgüdümlü Evrensel Saat (UTC) saatine geçirilir. Tarih ve saat 1917 veya daha önceki bir tarihte gerçekleşirse, özel Doğu Standart Saat dilimi serileştirilmiş bir dizeden geri yüklenir ve kayıt defterinden alınan saat diliminin yerini alır.

using System;

public class TimeZoneSerialization
{
   static string serializedEst;

   public static void Main()
   {
      // Retrieve Eastern Standard Time zone from registry
      try
      {
         TimeZoneSerialization tzs = new TimeZoneSerialization();
         TimeZoneInfo est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
         // Create custom Eastern Time Zone for historical (pre-1918) conversions
         CreateTimeZone();
         // Call conversion function with one current and one pre-1918 date and time
         Console.WriteLine(ConvertUtcTime(DateTime.UtcNow, est));
         Console.WriteLine(ConvertUtcTime(new DateTime(1900, 11, 15, 9, 32, 00, DateTimeKind.Utc), est));
      }
      catch (TimeZoneNotFoundException)
      {
         Console.WriteLine("The Eastern Standard Time zone is not in the registry.");
      }
      catch (InvalidTimeZoneException)
      {
         Console.WriteLine("Data on the Eastern Standard Time Zone in the registry is corrupted.");
      }
   }

   private static void CreateTimeZone()
   {
      // Create a simple Eastern Standard time zone
      // without adjustment rules for 1883-1918
      TimeZoneInfo earlyEstZone = TimeZoneInfo.CreateCustomTimeZone("Eastern Standard Time",
                                      new TimeSpan(-5, 0, 0),
                                      " (GMT-05:00) Eastern Time (United States)",
                                      "Eastern Standard Time");
      serializedEst = earlyEstZone.ToSerializedString();
   }

   private static DateTime ConvertUtcTime(DateTime utcDate, TimeZoneInfo tz)
   {
      // Use time zone object from registry
      if (utcDate.Year > 1917)
      {
         return TimeZoneInfo.ConvertTimeFromUtc(utcDate, tz);
      }
      // Handle dates before introduction of DST
      else
      {
         // Restore serialized time zone object
         tz = TimeZoneInfo.FromSerializedString(serializedEst);
         return TimeZoneInfo.ConvertTimeFromUtc(utcDate, tz);
      }
   }
}
Module TimeZoneSerialization
    Dim serializedEst As String

    Public Sub Main()
        ' Retrieve Eastern Standard Time zone from registry
        Try
            Dim est As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")
            ' Create custom Eastern Time Zone for historical (pre-1918) conversions
            CreateTimeZone()
            ' Call conversion function with one current and one pre-1918 date and time
            Console.WriteLine(ConvertUtcTime(Date.UtcNow, est))
            Console.WriteLine(ConvertUtcTime(New Date(1900, 11, 15, 9, 32, 00, DateTimeKind.Utc), est))
        Catch e As TimeZoneNotFoundException
            Console.WriteLine("The Eastern Standard Time zone is not in the registry.")
        Catch e As InvalidTimeZoneException
            Console.WriteLine("Data on the Eastern Standard Time Zone in the registry is corrupted.")
        End Try
    End Sub

    Private Sub CreateTimeZone()
        ' Create a simple Eastern Standard time zone 
        ' without adjustment rules for 1883-1918
        Dim earlyEstZone As TimeZoneInfo = TimeZoneInfo.CreateCustomTimeZone("Eastern Standard Time", _
                                        New TimeSpan(-5, 0, 0), _
                                        " (GMT-05:00) Eastern Time (United States)", _
                                        "Eastern Standard Time")
        serializedEst = earlyEstZone.ToSerializedString()
    End Sub

    Private Function ConvertUtcTime(utcDate As Date, tz As TimeZoneInfo) As Date
        ' Use time zone object from registry 
        If Year(utcDate) > 1917 Then
            Return TimeZoneInfo.ConvertTimeFromUtc(utcDate, tz)
            ' Handle dates before introduction of DST
        Else
            ' Restore serialized time zone object
            tz = TimeZoneInfo.FromSerializedString(serializedEst)
            Return TimeZoneInfo.ConvertTimeFromUtc(utcDate, tz)
        End If
    End Function
End Module

Saat dilimi özel durumlarını işleme

Kayıt defteri dinamik bir yapı olduğundan, içeriği yanlışlıkla veya kasıtlı bir değişikliğe tabidir. Bu, kayıt defterinde tanımlanması gereken ve bir uygulamanın başarıyla yürütülmesi için gereken bir saat diliminin eksik olabileceği anlamına gelir. Saat dilimi serileştirme ve seri durumdan çıkarma desteği olmadan, uygulamayı sonlandırarak sonucu TimeZoneNotFoundException işlemek dışında çok az seçeneğiniz vardır. Ancak, saat dilimi serileştirme ve seri durumdan çıkarma kullanarak, gerekli saat dilimini serileştirilmiş bir dizeden geri yükleyerek beklenmeyen TimeZoneNotFoundException bir işlemi işleyebilirsiniz ve uygulama çalışmaya devam eder.

Aşağıdaki örnek, özel bir Merkezi Standart Saat dilimi oluşturur ve serileştirir. Ardından kayıt defterinden Merkezi Standart Saat dilimini almaya çalışır. Alma işlemi bir TimeZoneNotFoundException veya InvalidTimeZoneExceptionoluşturursa, özel durum işleyicisi saat dilimini seri durumdan çıkartır.

using System;
using System.Collections.Generic;

public class TimeZoneApplication
{
   // Define collection of custom time zones
   private Dictionary<string, string> customTimeZones = new Dictionary<string, string>();
   private TimeZoneInfo cst;

   public TimeZoneApplication()
   {
      // Create custom Central Standard Time
      //
      // Declare necessary TimeZoneInfo.AdjustmentRule objects for time zone
      TimeZoneInfo customTimeZone;
      TimeSpan delta = new TimeSpan(1, 0, 0);
      TimeZoneInfo.AdjustmentRule adjustment;
      List<TimeZoneInfo.AdjustmentRule> adjustmentList = new List<TimeZoneInfo.AdjustmentRule>();
      // Declare transition time variables to hold transition time information
      TimeZoneInfo.TransitionTime transitionRuleStart, transitionRuleEnd;

      // Define end rule (for 1976-2006)
      transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 10, 5, DayOfWeek.Sunday);
      // Define rule (1976-1986)
      transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 05, DayOfWeek.Sunday);
      adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1976, 1, 1), new DateTime(1986, 12, 31), delta, transitionRuleStart, transitionRuleEnd);
      adjustmentList.Add(adjustment);
      // Define rule (1987-2006)
      transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 01, DayOfWeek.Sunday);
      adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1987, 1, 1), new DateTime(2006, 12, 31), delta, transitionRuleStart, transitionRuleEnd);
      adjustmentList.Add(adjustment);
      // Define rule (2007- )
      transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 03, 02, DayOfWeek.Sunday);
      transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 11, 01, DayOfWeek.Sunday);
      adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(2007, 01, 01), DateTime.MaxValue.Date, delta, transitionRuleStart, transitionRuleEnd);
      adjustmentList.Add(adjustment);

      // Create custom U.S. Central Standard Time zone
      customTimeZone = TimeZoneInfo.CreateCustomTimeZone("Central Standard Time",
                      new TimeSpan(-6, 0, 0),
                      "(GMT-06:00) Central Time (US Only)", "Central Standard Time",
                      "Central Daylight Time", adjustmentList.ToArray());
      // Add time zone to collection
      customTimeZones.Add(customTimeZone.Id, customTimeZone.ToSerializedString());

      // Create any other required time zones
   }

   public static void Main()
   {
      TimeZoneApplication tza = new TimeZoneApplication();
      tza.AppEntryPoint();
   }

   private void AppEntryPoint()
   {
      try
      {
         cst = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
      }
      catch (TimeZoneNotFoundException)
      {
         if (customTimeZones.ContainsKey("Central Standard Time"))
            HandleTimeZoneException("Central Standard Time");
      }
      catch (InvalidTimeZoneException)
      {
         if (customTimeZones.ContainsKey("Central Standard Time"))
            HandleTimeZoneException("Central Standard Time");
      }
      if (cst == null)
      {
         Console.WriteLine("Unable to load Central Standard Time zone.");
         return;
      }
      DateTime currentTime = DateTime.Now;
      Console.WriteLine("The current {0} time is {1}.",
                        TimeZoneInfo.Local.IsDaylightSavingTime(currentTime) ?
                            TimeZoneInfo.Local.StandardName :
                            TimeZoneInfo.Local.DaylightName,
                        currentTime.ToString("f"));
      Console.WriteLine("The current {0} time is {1}.",
                        cst.IsDaylightSavingTime(currentTime) ?
                            cst.StandardName :
                            cst.DaylightName,
                        TimeZoneInfo.ConvertTime(currentTime, TimeZoneInfo.Local, cst).ToString("f"));
   }

   private void HandleTimeZoneException(string timeZoneName)
   {
      string tzString = customTimeZones[timeZoneName];
      cst = TimeZoneInfo.FromSerializedString(tzString);
   }
}
Imports System.Collections.Generic

Public Class TimeZoneApplication
    ' Define collection of custom time zones
    Private customTimeZones As New Dictionary(Of String, String)
    Private cst As TimeZoneInfo

    Public Sub New()
        ' Define custom Central Standard Time
        '
        ' Declare necessary TimeZoneInfo.AdjustmentRule objects for time zone
        Dim customTimeZone As TimeZoneInfo
        Dim delta As New TimeSpan(1, 0, 0)
        Dim adjustment As TimeZoneInfo.AdjustmentRule
        Dim adjustmentList As New List(Of TimeZoneInfo.AdjustmentRule)
        ' Declare transition time variables to hold transition time information
        Dim transitionRuleStart, transitionRuleEnd As TimeZoneInfo.TransitionTime

        ' Define end rule (for 1976-2006)
        transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#02:00:00AM#, 10, 5, DayOfWeek.Sunday)
        ' Define rule (1976-1986)
        transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 04, 05, DayOfWeek.Sunday)
        adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1976#, #12/31/1986#, delta, transitionRuleStart, transitionRuleEnd)
        adjustmentList.Add(adjustment)
        ' Define rule (1987-2006)  
        transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 04, 01, DayOfWeek.Sunday)
        adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/1987#, #12/31/2006#, delta, transitionRuleStart, transitionRuleEnd)
        adjustmentList.Add(adjustment)
        ' Define rule (2007- )  
        transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 03, 02, DayOfWeek.Sunday)
        transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#2:00:00AM#, 11, 01, DayOfWeek.Sunday)
        adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#01/01/2007#, Date.MaxValue.Date, delta, transitionRuleStart, transitionRuleEnd)
        adjustmentList.Add(adjustment)
        ' Create custom time zone
        customTimeZone = TimeZoneInfo.CreateCustomTimeZone("Central Standard Time", _
                        New TimeSpan(-6, 0, 0), _
                        "(GMT-06:00) Central Time (US Only)", "Central Standard Time", _
                        "Central Daylight Time", adjustmentList.ToArray())
        ' Add time zone to collection
        customTimeZones.Add(customTimeZone.Id, customTimeZone.ToSerializedString())

        ' Create any other required time zones     
    End Sub

    Public Shared Sub Main()
        Dim tza As New TimeZoneApplication()
        tza.AppEntryPoint()
    End Sub

    Private Sub AppEntryPoint()
        Try
            cst = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
        Catch e As TimeZoneNotFoundException
            If customTimeZones.ContainsKey("Central Standard Time")
                HandleTimeZoneException("Central Standard Time")
            End If
        Catch e As InvalidTimeZoneException
            If customTimeZones.ContainsKey("Central Standard Time")
                HandleTimeZoneException("Central Standard Time")
            End If
        End Try
        If cst Is Nothing Then
            Console.WriteLine("Unable to load Central Standard Time zone.")
            Return
        End If
        Dim currentTime As Date = Date.Now
        Console.WriteLine("The current {0} time is {1}.", _
                          IIf(TimeZoneInfo.Local.IsDaylightSavingTime(currentTime), _
                              TimeZoneInfo.Local.StandardName, _
                              TimeZoneInfo.Local.DaylightName), _
                          currentTime.ToString("f"))
        Console.WriteLine("The current {0} time is {1}.", _
                          IIf(cst.IsDaylightSavingTime(currentTime), _
                              cst.StandardName, _
                              cst.DaylightName), _
                          TimeZoneInfo.ConvertTime(currentTime, TimeZoneInfo.Local, cst).ToString("f"))
    End Sub

    Private Sub HandleTimeZoneException(timeZoneName As String)
        Dim tzString As String = customTimeZones.Item(timeZoneName)
        cst = TimeZoneInfo.FromSerializedString(tzString)
    End Sub
End Class

Serileştirilmiş bir dizeyi depolama ve gerektiğinde geri yükleme

Önceki örnekler saat dilimi bilgilerini bir dize değişkenine depolamış ve gerektiğinde geri yüklemiş. Ancak, serileştirilmiş saat dilimi bilgilerini içeren dizenin kendisi dış dosya, uygulamaya eklenmiş bir kaynak dosyası veya kayıt defteri gibi bir depolama ortamında depolanabilir. (Özel saat dilimleri hakkındaki bilgilerin, sistemin kayıt defterindeki saat dilimi anahtarlarından ayrı olarak depolanması gerektiğini unutmayın.)

Serileştirilmiş bir saat dilimi dizesini bu şekilde depolamak, saat dilimi oluşturma yordamını uygulamanın kendisinden de ayırır. Örneğin, bir saat dilimi oluşturma yordamı, bir uygulamanın kullanabileceği geçmiş saat dilimi bilgilerini içeren bir veri dosyası yürütebilir ve oluşturabilir. Daha sonra veri dosyası uygulamayla yüklenebilir ve açılabilir ve uygulama gerektirdiğinde bir veya daha fazla saat dilimi seri durumdan çıkarılabilir.

Serileştirilmiş saat dilimi verilerini depolamak için ekli kaynak kullanan bir örnek için bkz . Nasıl yapılır: Katıştırılmış kaynağa saat dilimlerini kaydetme ve Nasıl yapılır: Katıştırılmış bir kaynaktan saat dilimlerini geri yükleme.

Ayrıca bkz.