Saatleri saat dilimleri arasında dönüştürme

Zaman dilimleri arasındaki farkları işlemek için tarih ve saatlerle birlikte çalışarak tüm uygulamalar için giderek daha fazla önemli hale gelir. Bir uygulama, her saatin, yapıdan kullanılabilen zaman olan yerel saat içinde ifade edilebilir olduğunu varsaymaz DateTime . Örneğin, Birleşik Devletler Doğu bölümünde geçerli zamanı görüntüleyen bir Web sayfası Doğu Asya 'daki bir müşteriye karşı güvenilirlik vermez. Bu konuda, saatlerin bir saat diliminden diğerine nasıl dönüştürüleceği ve DateTimeOffset sınırlı saat dilimi tanıma olan değerlerin nasıl dönüştürüleceği açıklanmaktadır.

Eşgüdümlü Evrensel saate dönüştürme

Eşgüdümlü Evrensel Saat (UTC), yüksek duyarlıklı, atomik bir süre standardıdır. Dünyanın saat dilimleri UTC 'den pozitif veya negatif uzaklık olarak ifade edilir. Bu nedenle UTC, bir tür saat dilimi boş veya saat dilimi nötr saati sağlar. Tarih ve saatin bilgisayarlar arasında taşınabilirliği önemli olduğunda UTC zamanının kullanılması önerilir. (Ayrıntılar ve Tarih ve saatleri kullanan diğer en iyi uygulamalar için bkz. .NET Framework tarih saat kullanarak en iyi yöntemleri kodlama.) Bağımsız bir saat dilimini UTC 'ye dönüştürmek, zaman karşılaştırmaları kolaylaştırır.

Not

Ayrıca, bir DateTimeOffset yapının zaman içinde tek bir noktayı göstermek için bir yapıyı seri hale getirebilirsiniz. DateTimeOffsetNesneler bir tarih ve saat DEĞERINI UTC 'deki uzaklığa göre depolarsa, UTC ile ilişki içinde her zaman belirli bir noktayı temsil eder.

bir saati UTC 'ye dönüştürmenin en kolay yolu static ( Shared Visual Basic) metodunu çağırmanız TimeZoneInfo.ConvertTimeToUtc(DateTime) . Yöntemi tarafından gerçekleştirilen tam dönüştürme, dateTime Kind Aşağıdaki tabloda gösterildiği gibi parametrenin özelliğinin değerine bağlıdır.

DateTime.Kind Dönüştürme
DateTimeKind.Local Yerel saati UTC 'ye dönüştürür.
DateTimeKind.Unspecified dateTimeParametrenin yerel saat olduğunu varsayar ve yerel saatı UTC 'ye dönüştürür.
DateTimeKind.Utc dateTimeParametreyi değiştirilmemiş olarak döndürür.

Aşağıdaki kod geçerli yerel saati UTC 'ye dönüştürür ve sonucu konsola görüntüler.

DateTime dateNow = DateTime.Now;
Console.WriteLine("The date and time are {0} UTC.",
                   TimeZoneInfo.ConvertTimeToUtc(dateNow));
Dim dateNow As Date = Date.Now
Console.WriteLine("The date and time are {0} UTC.", _
                  TimeZoneInfo.ConvertTimeToUtc(dateNow))

Tarih ve saat değeri yerel saati veya UTC 'yi temsil etmez, ToUniversalTime Yöntem muhtemelen hatalı bir sonuç döndürür. Ancak, TimeZoneInfo.ConvertTimeToUtc belirli bir saat diliminden tarih ve saati dönüştürmek için yöntemini kullanabilirsiniz. (Hedef saat dilimini temsil eden bir nesneyi alma hakkında daha fazla bilgi için TimeZoneInfo , bkz. yerel bir sistemde tanımlanan saat dilimlerini bulma.) Aşağıdaki kod, TimeZoneInfo.ConvertTimeToUtc Doğu Standart SAATINI UTC 'ye dönüştürmek için yöntemini kullanır.

DateTime easternTime = new DateTime(2007, 01, 02, 12, 16, 00);
string easternZoneId = "Eastern Standard Time";
try
{
   TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
   Console.WriteLine("The date and time are {0} UTC.",
                     TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone));
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("Unable to find the {0} zone in the registry.",
                     easternZoneId);
}
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the {0} zone has been corrupted.",
                     easternZoneId);
}
Dim easternTime As New Date(2007, 01, 02, 12, 16, 00)
Dim easternZoneId As String = "Eastern Standard Time"
Try
    Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId)
    Console.WriteLine("The date and time are {0} UTC.", _
                      TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone))
Catch e As TimeZoneNotFoundException
    Console.WriteLine("Unable to find the {0} zone in the registry.", _
                      easternZoneId)
Catch e As InvalidTimeZoneException
    Console.WriteLine("Registry data on the {0} zone has been corrupted.", _
                      easternZoneId)
End Try

Bu yöntemin, ArgumentException DateTime nesnenin Kind özelliği ve saat dilimi yanlış olursa bir oluşturur. KindÖzellik, DateTimeKind.Local ancak TimeZoneInfo nesne yerel saat dilimini temsil etmediği ya da Kind özellik ise DateTimeKind.Utc ancak TimeZoneInfo nesne eşit değilse TimeZoneInfo.Utc bir uyumsuzluk oluşur.

Bu yöntemlerin hepsi DateTime değerleri parametre olarak alır ve bir değer döndürür DateTime . DateTimeOffsetDeğerler için, DateTimeOffset yapının ToUniversalTime geçerli örneğin TARIH ve saatini UTC 'ye dönüştüren bir örnek yöntemi vardır. Aşağıdaki örnek, ToUniversalTime yerel bir saati ve diğer birkaç saati Eşgüdümlü Evrensel Saat (UTC) olarak dönüştürmek için yöntemini çağırır.

DateTimeOffset localTime, otherTime, universalTime;

// Define local time in local time zone
localTime = new DateTimeOffset(new DateTime(2007, 6, 15, 12, 0, 0));
Console.WriteLine("Local time: {0}", localTime);
Console.WriteLine();

// Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero);
Console.WriteLine("Other time: {0}", otherTime);
Console.WriteLine("{0} = {1}: {2}",
                  localTime, otherTime,
                  localTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}",
                  localTime, otherTime,
                  localTime.EqualsExact(otherTime));
Console.WriteLine();

// Convert other time to UTC
universalTime = localTime.ToUniversalTime();
Console.WriteLine("Universal time: {0}", universalTime);
Console.WriteLine("{0} = {1}: {2}",
                  otherTime, universalTime,
                  universalTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}",
                  otherTime, universalTime,
                  universalTime.EqualsExact(otherTime));
Console.WriteLine();
// The example produces the following output to the console:
//    Local time: 6/15/2007 12:00:00 PM -07:00
//
//    Other time: 6/15/2007 7:00:00 PM +00:00
//    6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
//    6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
//
//    Universal time: 6/15/2007 7:00:00 PM +00:00
//    6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
//    6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True
Dim localTime, otherTime, universalTime As DateTimeOffset

' Define local time in local time zone
localTime = New DateTimeOffset(#6/15/2007 12:00:00PM#)
Console.WriteLine("Local time: {0}", localTime)
Console.WriteLine()

' Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero)
Console.WriteLine("Other time: {0}", otherTime)
Console.WriteLine("{0} = {1}: {2}", _
                  localTime, otherTime, _
                  localTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _
                  localTime, otherTime, _
                  localTime.EqualsExact(otherTime))
Console.WriteLine()

' Convert other time to UTC
universalTime = localTime.ToUniversalTime()
Console.WriteLine("Universal time: {0}", universalTime)
Console.WriteLine("{0} = {1}: {2}", _
                  otherTime, universalTime, _
                  universalTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _
                  otherTime, universalTime, _
                  universalTime.EqualsExact(otherTime))
Console.WriteLine()
' The example produces the following output to the console:
'    Local time: 6/15/2007 12:00:00 PM -07:00
'    
'    Other time: 6/15/2007 7:00:00 PM +00:00
'    6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
'    6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
'    
'    Universal time: 6/15/2007 7:00:00 PM +00:00
'    6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
'    6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True   

UTC 'yi belirlenen saat dilimine dönüştürme

UTC 'yi yerel saate dönüştürmek için, aşağıdaki "UTC 'den yerel saate dönüştürme" bölümüne bakın. UTC 'yi belirleyeceğiniz herhangi bir zaman diliminde saate dönüştürmek için ConvertTimeFromUtc yöntemini çağırın. Yöntemi iki parametre alır:

  • Dönüştürülecek UTC. Bu DateTime Kind , özelliği veya olarak ayarlanmış bir değer olmalıdır Unspecified Utc .

  • UTC 'nin dönüştürüleceği saat dilimi.

Aşağıdaki kod UTC 'yi orta standart saate dönüştürür.

DateTime timeUtc = DateTime.UtcNow;
try
{
   TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
   DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
   Console.WriteLine("The date and time are {0} {1}.",
                     cstTime,
                     cstZone.IsDaylightSavingTime(cstTime) ?
                             cstZone.DaylightName : cstZone.StandardName);
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("The registry does not define the Central Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the Central Standard Time zone has been corrupted.");
}
Dim timeUtc As Date = Date.UtcNow
Try
    Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
    Dim cstTime As Date = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone)
    Console.WriteLine("The date and time are {0} {1}.", _
                      cstTime, _
                      IIf(cstZone.IsDaylightSavingTime(cstTime), _
                          cstZone.DaylightName, cstZone.StandardName))
Catch e As TimeZoneNotFoundException
    Console.WriteLine("The registry does not define the Central Standard Time zone.")
Catch e As InvalidTimeZoneException
    Console.WriteLine("Registry data on the Central Standard Time zone has been corrupted.")
End Try

UTC 'yi yerel saate dönüştürme

UTC 'yi yerel saate dönüştürmek için ToLocalTime dönüştürmek istediğiniz nesnenin yöntemini çağırın DateTime . Yönteminin tam davranışı Kind , aşağıdaki tabloda gösterildiği gibi nesnenin özelliğinin değerine bağlıdır.

DateTime.Kind Dönüştürme
DateTimeKind.Local DateTimeDeğeri değiştirilmemiş olarak döndürür.
DateTimeKind.Unspecified DateTimeDEĞERIN UTC olduğunu varsayar ve UTC 'yi yerel saate dönüştürür.
DateTimeKind.Utc DateTimeDeğeri yerel saate dönüştürür.

Not

TimeZone.ToLocalTimeYöntemi yöntemiyle aynı şekilde davranır DateTime.ToLocalTime . Dönüştürülecek tarih ve saat değeri olan tek bir parametre alır.

ayrıca, static ( Shared Visual Basic) metodunu kullanarak belirlenen saat diliminizdeki süreyi yerel saate dönüştürebilirsiniz TimeZoneInfo.ConvertTime . Bu teknik, sonraki bölümde ele alınmıştır.

İki saat dilimi arasında dönüştürme

sınıfının aşağıdaki iki static ( Shared Visual Basic) yöntemlerinden birini kullanarak iki saat dilimi arasında dönüştürme yapabilirsiniz TimeZoneInfo :

  • ConvertTime

    Bu yöntemin parametreleri, dönüştürülecek tarih ve saat değeri, TimeZoneInfo Tarih ve saat değerinin saat dilimini temsil eden bir nesne ve TimeZoneInfo Tarih ve saat değerini dönüştürmek için saat dilimini temsil eden bir nesnedir.

  • ConvertTimeBySystemTimeZoneId

    Bu yöntemin parametreleri, dönüştürülecek tarih ve saat değeri, tarih ve saat değerinin saat diliminin tanımlayıcısı ve Tarih ve saat değerinin olarak dönüştürülecek saat diliminin tanımlayıcısıdır.

Her iki yöntem de, Kind dönüştürülecek tarih ve saat değerinin ve TimeZoneInfo saat dilimini temsil eden nesne ya da saat dilimi tanımlayıcısının bir diğerine karşılık geldiğini gerektirir. Aksi takdirde, bir oluşturulur ArgumentException . Örneğin, Kind Tarih ve saat değerinin özelliği ise DateTimeKind.Local , TimeZoneInfo yöntemine parametre olarak geçirilen nesne değerine eşit değilse bir özel durum oluşturulur TimeZoneInfo.Local . Yöntemine parametre olarak geçirilen tanımlayıcı değerine eşit değilse de bir özel durum oluşturulur TimeZoneInfo.Local.Id .

Aşağıdaki örnek, ConvertTime Haian standart saatinden yerel saate dönüştürmek için yöntemini kullanır.

DateTime hwTime = new DateTime(2007, 02, 01, 08, 00, 00);
try
{
   TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
   Console.WriteLine("{0} {1} is {2} local time.",
           hwTime,
           hwZone.IsDaylightSavingTime(hwTime) ? hwZone.DaylightName : hwZone.StandardName,
           TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local));
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the Hawaiian Standard Time zone has been corrupted.");
}
Dim hwTime As Date = #2/01/2007 8:00:00 AM#
Try
    Dim hwZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time")
    Console.WriteLine("{0} {1} is {2} local time.", _
                      hwTime, _
                      IIf(hwZone.IsDaylightSavingTime(hwTime), hwZone.DaylightName, hwZone.StandardName), _
                      TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local))
Catch e As TimeZoneNotFoundException
    Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.")
Catch e As InvalidTimeZoneException
    Console.WriteLine("Registry data on the Hawaiian Standard Time zone has been corrupted.")
End Try

DateTimeOffset değerlerini dönüştürme

Nesneler tarafından temsil edilen tarih ve saat değerleri, DateTimeOffset nesne, oluşturulduğu sırada saat dilimiyle ilişkili olmadığından tam zaman dilimi farkında değildir. Ancak çoğu durumda, bir uygulamanın bir tarih ve saati belirli saat dilimlerindeki zaman yerine UTC 'den iki farklı uzaklığa göre dönüştürmesi gerekir. Bu dönüştürmeyi gerçekleştirmek için geçerli örnek ToOffset yöntemini çağırabilirsiniz. Metodun tek parametresi, yöntemin döndürülecek yeni tarih ve saat değerinin bir denkleştirilir.

Örneğin, bir Web sayfası için Kullanıcı isteğinin tarih ve saati biliniyorsa ve aa/gg/yyyy HH: mm: ss zzzz biçiminde bir dize olarak serileştirildiğinde, aşağıdaki ReturnTimeOnServer Yöntem bu tarih ve saat değerini Web sunucusundaki tarih ve saate dönüştürür.

public DateTimeOffset ReturnTimeOnServer(string clientString)
{
   string format = @"M/d/yyyy H:m:s zzz";
   TimeSpan serverOffset = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now);

   try
   {
      DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture);
      DateTimeOffset serverTime = clientTime.ToOffset(serverOffset);
      return serverTime;
   }
   catch (FormatException)
   {
      return DateTimeOffset.MinValue;
   }
}
Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
    Dim format As String = "M/d/yyyy H:m:s zzz"
    Dim serverOffset As TimeSpan = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now)

    Try
        Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
        Dim serverTime As DateTimeOffset = clientTime.ToOffset(serverOffset)
        Return serverTime
    Catch e As FormatException
        Return DateTimeOffset.MinValue
    End Try
End Function

Yöntem UTC 'den beş saat dilimde tarih ve saati bir kez geçir9/1/2007 5:32:07 -05:00 Tiyse, ABD Pasifik standart saat diliminde bulunan bir sunucu için 9/1/2007 3:32:07 ÖÖ-07:00 döndürür.

TimeZoneInfoSınıfı, TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) zaman dilimi dönüştürmelerini değerlerle gerçekleştiren yönteminin bir aşırı yüklemesini de içerir ToOffset(TimeSpan) . Metodun parametreleri bir DateTimeOffset değerdir ve zaman dilimine bir başvurudur ve bu da zamanın dönüştürülecek olan bir başvurudur. Yöntem çağrısı bir değer döndürür DateTimeOffset . Örneğin, ReturnTimeOnServer önceki örnekteki yöntemi yöntemi çağırmak için aşağıdaki şekilde yeniden yazılabilir ConvertTime(DateTimeOffset, TimeZoneInfo) .

public DateTimeOffset ReturnTimeOnServer(string clientString)
{
   string format = @"M/d/yyyy H:m:s zzz";

   try
   {
      DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format,
                                  CultureInfo.InvariantCulture);
      DateTimeOffset serverTime = TimeZoneInfo.ConvertTime(clientTime,
                                  TimeZoneInfo.Local);
      return serverTime;
   }
   catch (FormatException)
   {
      return DateTimeOffset.MinValue;
   }
}
Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
    Dim format As String = "M/d/yyyy H:m:s zzz"

    Try
        Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
        Dim serverTime As DateTimeOffset = TimeZoneInfo.ConvertTime(clientTime, TimeZoneInfo.Local)
        Return serverTime
    Catch e As FormatException
        Return DateTimeOffset.MinValue
    End Try
End Function

Ayrıca bkz.