DateTime, DateOnly, DateTimeOffset, TimeSpan, TimeOnly ve TimeZoneInfo arasında seçim yapma

.NET uygulamaları tarih ve saat bilgilerini çeşitli yollarla kullanabilir. Tarih ve saat bilgilerinin daha yaygın kullanım alanları şunlardır:

  • Zaman bilgilerinin önemli olmaması için yalnızca tarihi yansıtmak.
  • Tarih bilgilerinin önemli olmaması için yalnızca bir saati yansıtmak.
  • Belirli bir saat ve yere bağlı olmayan soyut bir tarih ve saati yansıtmak için (örneğin, uluslararası bir zincirdeki çoğu mağaza hafta içi 09:00'da açıktır).
  • Tarih ve saat bilgilerini .NET dışındaki kaynaklardan almak için, genellikle tarih ve saat bilgilerinin basit bir veri türünde depolandığı yerdir.
  • Zaman içinde tek bir noktayı benzersiz ve net bir şekilde tanımlamak için. Bazı uygulamalar, bir tarih ve saatin yalnızca konak sisteminde belirsiz olmasını gerektirir. Diğer uygulamalar bunun sistemler arasında belirsiz olmasını gerektirir (başka bir deyişle, bir sistemde seri hale getirilmiş bir tarih anlamlı bir şekilde seri durumdan çıkarılabilir ve dünyanın herhangi bir yerinde başka bir sistemde kullanılabilir).
  • birden çok ilgili zamanı (istek sahibinin yerel saati ve bir web isteği için sunucunun alınma saati gibi) korumak için.
  • Tarih ve saat aritmetiği gerçekleştirmek için, büyük olasılıkla tek bir zaman noktasını benzersiz ve kesin olarak tanımlayan bir sonuçla.

.NET, tarih ve TimeZoneInfo saatlerle çalışan uygulamalar oluşturmak için kullanılabilen , TimeSpanDateOnlyDateTimeOffset, , , TimeOnly, ve türlerini içerirDateTime.

Not

İşlevselliği neredeyse tamamen sınıfına dahil edildiğinden TimeZoneInfo bu makale açıklanmadıTimeZone. Mümkün olduğunda sınıfı yerine sınıfını TimeZone kullanınTimeZoneInfo.

DateTimeOffset yapısı

Yapı DateTimeOffset , bir tarih ve saat değerini temsil eder ve bu değerin UTC'den ne kadar farklı olduğunu gösteren bir uzaklık ile birlikte. Bu nedenle, değer her zaman zaman tek bir noktayı kesin olarak tanımlar.

türü, DateTimeOffset türün tüm işlevlerini DateTime ve saat dilimi farkındalığını içerir. Bu, aşağıdaki uygulamalar için uygun hale getirir:

  • Zaman içinde tek bir noktayı benzersiz ve net bir şekilde tanımlayın. Tür DateTimeOffset , "now" anlamını kesin olarak tanımlamak, işlem sürelerini günlüğe kaydetmek, sistem veya uygulama olaylarının zamanlarını günlüğe kaydetmek ve dosya oluşturma ve değiştirme sürelerini kaydetmek için kullanılabilir.
  • Genel tarih ve saat aritmetiğini gerçekleştirin.
  • Bu süreler iki ayrı değer veya bir yapının iki üyesi olarak depolandığı sürece, birden çok ilgili zamanı koruyun.

Not

Değerler için DateTimeOffset bu kullanımlar, değerler için DateTime kullanılanlardan çok daha yaygındır. Sonuç olarak, uygulama geliştirme için varsayılan tarih ve saat türü olarak düşünün DateTimeOffset .

Bir DateTimeOffset değer belirli bir saat dilimine bağlı değildir, ancak çeşitli saat dilimlerinden kaynaklanabilir. Aşağıdaki örnek, bir dizi değerin DateTimeOffset (yerel Pasifik Standart Saati dahil) ait olabileceği saat dilimlerini listeler.

using System;
using System.Collections.ObjectModel;

public class TimeOffsets
{
   public static void Main()
   {
      DateTime thisDate = new DateTime(2007, 3, 10, 0, 0, 0);
      DateTime dstDate = new DateTime(2007, 6, 10, 0, 0, 0);
      DateTimeOffset thisTime;

      thisTime = new DateTimeOffset(dstDate, new TimeSpan(-7, 0, 0));
      ShowPossibleTimeZones(thisTime);

      thisTime = new DateTimeOffset(thisDate, new TimeSpan(-6, 0, 0));
      ShowPossibleTimeZones(thisTime);

      thisTime = new DateTimeOffset(thisDate, new TimeSpan(+1, 0, 0));
      ShowPossibleTimeZones(thisTime);
   }

   private static void ShowPossibleTimeZones(DateTimeOffset offsetTime)
   {
      TimeSpan offset = offsetTime.Offset;
      ReadOnlyCollection<TimeZoneInfo> timeZones;

      Console.WriteLine("{0} could belong to the following time zones:",
                        offsetTime.ToString());
      // Get all time zones defined on local system
      timeZones = TimeZoneInfo.GetSystemTimeZones();
      // Iterate time zones
      foreach (TimeZoneInfo timeZone in timeZones)
      {
         // Compare offset with offset for that date in that time zone
         if (timeZone.GetUtcOffset(offsetTime.DateTime).Equals(offset))
            Console.WriteLine("   {0}", timeZone.DisplayName);
      }
      Console.WriteLine();
   }
}
// This example displays the following output to the console:
//       6/10/2007 12:00:00 AM -07:00 could belong to the following time zones:
//          (GMT-07:00) Arizona
//          (GMT-08:00) Pacific Time (US & Canada)
//          (GMT-08:00) Tijuana, Baja California
//
//       3/10/2007 12:00:00 AM -06:00 could belong to the following time zones:
//          (GMT-06:00) Central America
//          (GMT-06:00) Central Time (US & Canada)
//          (GMT-06:00) Guadalajara, Mexico City, Monterrey - New
//          (GMT-06:00) Guadalajara, Mexico City, Monterrey - Old
//          (GMT-06:00) Saskatchewan
//
//       3/10/2007 12:00:00 AM +01:00 could belong to the following time zones:
//          (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
//          (GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague
//          (GMT+01:00) Brussels, Copenhagen, Madrid, Paris
//          (GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb
//          (GMT+01:00) West Central Africa
Imports System.Collections.ObjectModel

Module TimeOffsets
    Public Sub Main()
        Dim thisTime As DateTimeOffset

        thisTime = New DateTimeOffset(#06/10/2007#, New TimeSpan(-7, 0, 0))
        ShowPossibleTimeZones(thisTime)

        thisTime = New DateTimeOffset(#03/10/2007#, New TimeSpan(-6, 0, 0))
        ShowPossibleTimeZones(thisTime)

        thisTime = New DateTimeOffset(#03/10/2007#, New TimeSpan(+1, 0, 0))
        ShowPossibleTimeZones(thisTime)
    End Sub

    Private Sub ShowPossibleTimeZones(offsetTime As DateTimeOffset)
        Dim offset As TimeSpan = offsetTime.Offset
        Dim timeZones As ReadOnlyCollection(Of TimeZoneInfo)

        Console.WriteLine("{0} could belong to the following time zones:", _
                          offsetTime.ToString())
        ' Get all time zones defined on local system
        timeZones = TimeZoneInfo.GetSystemTimeZones()
        ' Iterate time zones
        For Each timeZone As TimeZoneInfo In timeZones
            ' Compare offset with offset for that date in that time zone
            If timeZone.GetUtcOffset(offsetTime.DateTime).Equals(offset) Then
                Console.WriteLine("   {0}", timeZone.DisplayName)
            End If
        Next
        Console.WriteLine()
    End Sub
End Module
' This example displays the following output to the console:
'       6/10/2007 12:00:00 AM -07:00 could belong to the following time zones:
'          (GMT-07:00) Arizona
'          (GMT-08:00) Pacific Time (US & Canada)
'          (GMT-08:00) Tijuana, Baja California
'       
'       3/10/2007 12:00:00 AM -06:00 could belong to the following time zones:
'          (GMT-06:00) Central America
'          (GMT-06:00) Central Time (US & Canada)
'          (GMT-06:00) Guadalajara, Mexico City, Monterrey - New
'          (GMT-06:00) Guadalajara, Mexico City, Monterrey - Old
'          (GMT-06:00) Saskatchewan
'       
'       3/10/2007 12:00:00 AM +01:00 could belong to the following time zones:
'          (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
'          (GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague
'          (GMT+01:00) Brussels, Copenhagen, Madrid, Paris
'          (GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb
'          (GMT+01:00) West Central Africa

Çıktı, bu örnekteki her tarih ve saat değerinin en az üç farklı saat dilimine ait olabileceğini gösterir. DateTimeOffset 10.06.2007 değeri, tarih ve saat değeri gün ışığından yararlanma saatini temsil ederse UTC'den uzaklığının, kaynak saat diliminin temel UTC uzaklığı veya görünen adında bulunan UTC'den uzaklık durumuna bile karşılık gelmez. Tek DateTimeOffset bir değer saat dilimiyle sıkı bir şekilde birleştiğinden, bir saat diliminin gün ışığından yararlanma saatine geçişini yansıtamaz. Bir değeri işlemek DateTimeOffset için tarih ve saat aritmetiği kullanıldığında bu sorun olabilir. Tarih ve saat aritmetiğinin saat diliminin ayarlama kurallarını dikkate alarak nasıl gerçekleştirildiğinin tartışılması için bkz . Tarih ve saatlerle aritmetik işlemler gerçekleştirme.

DateTime yapısı

Değer DateTime , belirli bir tarih ve saati tanımlar. Bu tarih ve saatin ait olduğu saat dilimi hakkında sınırlı bilgi sağlayan bir Kind özellik içerir. DateTimeKind özelliği tarafından Kind döndürülen değer, değerin DateTime yerel saati (DateTimeKind.Local), Eşgüdümlü Evrensel Saati (UTC) (DateTimeKind.Utc ) veya belirtilmemiş bir saati (DateTimeKind.Unspecified) temsil edip etmediğini gösterir.

Yapı DateTime , aşağıdaki özelliklerden birine veya daha fazlasına sahip uygulamalar için uygundur:

  • Soyut tarihler ve saatlerle çalışma.
  • Saat dilimi bilgilerinin eksik olduğu tarih ve saatlerle çalışma.
  • Yalnızca UTC tarih ve saatleriyle çalışın.
  • Tarih ve saat aritmetiği gerçekleştirin, ancak genel sonuçlarla ilgilenir. Örneğin, belirli bir tarih ve saate altı ay ekleyen bir ekleme işleminde, sonucun yaz saati için ayarlanıp ayarlanmadığı genellikle önemli değildir.

Belirli DateTime bir değer UTC değerini temsil etmediği sürece, bu tarih ve saat değeri genellikle belirsiz veya taşınabilirliği sınırlıdır. Örneğin, bir DateTime değer yerel saati temsil ediyorsa, bu yerel saat dilimi içinde taşınabilir (yani, değer aynı saat dilimindeki başka bir sistemde seri durumdan çıkarılırsa, bu değer yine de belirli bir zaman noktasını kesin olarak tanımlar). Yerel saat dilimi dışında, bu DateTime değer birden çok yoruma sahip olabilir. Değerin Kind özelliği ise DateTimeKind.Unspecified, daha da az taşınabilirdir: artık aynı saat dilimi içinde ve hatta ilk seri hale getirildiği sistemde bile belirsizdir. Yalnızca bir DateTime değer UTC'yi temsil ederse bu değer, değerin kullanıldığı sistem veya saat diliminden bağımsız olarak zaman içinde tek bir noktayı kesin olarak tanımlar.

Önemli

Verileri kaydederken veya paylaşırken DateTime UTC kullanın ve değerinin DateTimeKind özelliğini olarak DateTimeKind.Utcayarlayın.

DateOnly yapısı

Yapı DateOnly , saat olmadan belirli bir tarihi temsil eder. Saat bileşeni olmadığından, günün başından sonuna kadar olan bir tarihi temsil eder. Bu yapı doğum tarihi, yıl dönümü tarihi, tatil veya işle ilgili tarih gibi belirli tarihleri depolamak için idealdir.

Zaman bileşenini yoksayarak kullanabilirsiniz DateTime ancak üzerinden DateTimekullanmanın DateOnly birkaç avantajı vardır:

  • Bir DateTime saat dilimine göre uzaklığı varsa, yapı önceki veya sonraki güne yuvarlanabilir. DateOnly saat dilimine göre kaydırılamaz ve her zaman ayarlanan tarihi temsil eder.
  • Bir DateTime yapıyı seri hale getirme, verilerin amacını gizleyebilecek zaman bileşenini içerir. Ayrıca, DateOnly daha az veriyi seri hale getirir.
  • Kod SQL Server gibi bir veritabanıyla etkileşime geçtiğinde, tüm tarihler genellikle saat içermeyen veri türü olarak date depolanır. DateOnly veritabanı türüyle daha iyi eşleşir.

hakkında DateOnlydaha fazla bilgi için bkz . DateOnly ve TimeOnly yapılarını kullanma.

Önemli

DateOnly .NET Framework'te kullanılamaz.

TimeSpan yapısı

Yapı TimeSpan bir zaman aralığını temsil eder. İki tipik kullanım şekli şunlardır:

  • İki tarih ve saat değeri arasındaki zaman aralığını Düşünceler. Örneğin, bir değeri başka bir DateTime değerden çıkarmak bir TimeSpan değer döndürür.
  • Geçen süreyi ölçme. Örneğin, özelliği geçen Stopwatch.Elapsed süreyi ölçmeye başlayan yöntemlerden birine Stopwatch çağrıldığından bu yana geçen zaman aralığını yansıtan bir TimeSpan değer döndürür.

Bir TimeSpan değer, belirli bir DateTime güne başvurmadan bir zamanı yansıttığında değerin yerine de kullanılabilir. Bu kullanım, tarihe DateTime.TimeOfDay başvurmadan saati temsil eden bir TimeSpan değer döndüren ve DateTimeOffset.TimeOfDay özelliklerine benzer. Örneğin, yapı bir mağazanın TimeSpan günlük açılış veya kapanış saatini yansıtmak için veya herhangi bir normal olayın gerçekleştiği zamanı göstermek için kullanılabilir.

Aşağıdaki örnek, depo açma ve kapatma saatlerine yönelik nesnelerin yanı sıra deponun saat dilimini temsil eden bir nesne içeren bir TimeZoneInfo yapıyı TimeSpan tanımlarStoreInfo. Yapı ayrıca, IsOpenNowIsOpenAtdeponun yerel saat diliminde olduğu varsayılan kullanıcı tarafından belirtilen bir zamanda açık olup olmadığını gösteren ve olmak üzere iki yöntem içerir.

using System;

public struct StoreInfo
{
   public String store;
   public TimeZoneInfo tz;
   public TimeSpan open;
   public TimeSpan close;

   public bool IsOpenNow()
   {
      return IsOpenAt(DateTime.Now.TimeOfDay);
   }

   public bool IsOpenAt(TimeSpan time)
   {
      TimeZoneInfo local = TimeZoneInfo.Local;
      TimeSpan offset = TimeZoneInfo.Local.BaseUtcOffset;

      // Is the store in the same time zone?
      if (tz.Equals(local)) {
         return time >= open & time <= close;
      }
      else {
         TimeSpan delta = TimeSpan.Zero;
         TimeSpan storeDelta = TimeSpan.Zero;

         // Is it daylight saving time in either time zone?
         if (local.IsDaylightSavingTime(DateTime.Now.Date + time))
            delta = local.GetAdjustmentRules()[local.GetAdjustmentRules().Length - 1].DaylightDelta;

         if (tz.IsDaylightSavingTime(TimeZoneInfo.ConvertTime(DateTime.Now.Date + time, local, tz)))
            storeDelta = tz.GetAdjustmentRules()[tz.GetAdjustmentRules().Length - 1].DaylightDelta;

         TimeSpan comparisonTime = time + (offset - tz.BaseUtcOffset).Negate() + (delta - storeDelta).Negate();
         return comparisonTime >= open & comparisonTime <= close;
      }
   }
}
Public Structure StoreInfo
    Dim store As String
    Dim tz As TimeZoneInfo
    Dim open As TimeSpan
    Dim close As TimeSpan

    Public Function IsOpenNow() As Boolean
        Return IsOpenAt(Date.Now.TimeOfDay)
    End Function

    Public Function IsOpenAt(time As TimeSpan) As Boolean
        Dim local As TimeZoneInfo = TimeZoneInfo.Local
        Dim offset As TimeSpan = TimeZoneInfo.Local.BaseUtcOffset

        ' Is the store in the same time zone?
        If tz.Equals(local) Then
            Return time >= open AndAlso time <= close
        Else
            Dim delta As TimeSpan = TimeSpan.Zero
            Dim storeDelta As TimeSpan = TimeSpan.Zero

            ' Is it daylight saving time in either time zone?
            If local.IsDaylightSavingTime(Date.Now.Date + time) Then
                delta = local.GetAdjustmentRules(local.GetAdjustmentRules().Length - 1).DaylightDelta
            End If
            If tz.IsDaylightSavingTime(TimeZoneInfo.ConvertTime(Date.Now.Date + time, local, tz))
                storeDelta = tz.GetAdjustmentRules(tz.GetAdjustmentRules().Length - 1).DaylightDelta
            End If
            Dim comparisonTime As TimeSpan = time + (offset - tz.BaseUtcOffset).Negate() + (delta - storeDelta).Negate
            Return (comparisonTime >= open AndAlso comparisonTime <= close)
        End If
    End Function
End Structure

Daha StoreInfo sonra yapı istemci kodu tarafından aşağıdaki gibi kullanılabilir.

public class Example
{
   public static void Main()
   {
      // Instantiate a StoreInfo object.
      var store103 = new StoreInfo();
      store103.store = "Store #103";
      store103.tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
      // Store opens at 8:00.
      store103.open = new TimeSpan(8, 0, 0);
      // Store closes at 9:30.
      store103.close = new TimeSpan(21, 30, 0);

      Console.WriteLine("Store is open now at {0}: {1}",
                        DateTime.Now.TimeOfDay, store103.IsOpenNow());
      TimeSpan[] times = { new TimeSpan(8, 0, 0), new TimeSpan(21, 0, 0),
                           new TimeSpan(4, 59, 0), new TimeSpan(18, 31, 0) };
      foreach (var time in times)
         Console.WriteLine("Store is open at {0}: {1}",
                           time, store103.IsOpenAt(time));
   }
}
// The example displays the following output:
//       Store is open now at 15:29:01.6129911: True
//       Store is open at 08:00:00: True
//       Store is open at 21:00:00: False
//       Store is open at 04:59:00: False
//       Store is open at 18:31:00: False
Module Example
    Public Sub Main()
        ' Instantiate a StoreInfo object.
        Dim store103 As New StoreInfo()
        store103.store = "Store #103"
        store103.tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")
        ' Store opens at 8:00.
        store103.open = new TimeSpan(8, 0, 0)
        ' Store closes at 9:30.
        store103.close = new TimeSpan(21, 30, 0)

        Console.WriteLine("Store is open now at {0}: {1}",
                          Date.Now.TimeOfDay, store103.IsOpenNow())
        Dim times() As TimeSpan = {New TimeSpan(8, 0, 0),
                                    New TimeSpan(21, 0, 0),
                                    New TimeSpan(4, 59, 0),
                                    New TimeSpan(18, 31, 0)}
        For Each time In times
            Console.WriteLine("Store is open at {0}: {1}",
                              time, store103.IsOpenAt(time))
        Next
    End Sub
End Module
' The example displays the following output:
'       Store is open now at 15:29:01.6129911: True
'       Store is open at 08:00:00: True
'       Store is open at 21:00:00: False
'       Store is open at 04:59:00: False
'       Store is open at 18:31:00: False

TimeOnly yapısı

Yapı, TimeOnly günlük çalar saat veya her gün öğle yemeği yediğiniz saat gibi bir günün saatini temsil eder. TimeOnly, günün belirli bir saati olan 00:00:00.00000000 - 23:59:59.99999999 aralığıyla sınırlıdır.

TimeOnly Tür kullanılmadan önce, programcılar genellikle belirli bir saati temsil etmek için türü veya TimeSpan türü kullanırDateTime. Ancak, tarihsiz bir saatin simülasyonunu yapmak için bu yapıların kullanılması bazı sorunları ortaya çıkararak TimeOnly şunları çözebilir:

  • TimeSpan kronometre ile ölçülen süre gibi geçen süreyi temsil eder. Üst aralık 29.000 yıldan fazladır ve değeri, zamanda geriye doğru hareket ettiğini göstermek için negatif olabilir. Negatif TimeSpan , günün belirli bir saatini göstermez.
  • Günün saati olarak kullanılırsa TimeSpan , 24 saatlik günün dışındaki bir değere yönlendirilebileceği riski vardır. TimeOnly bu riske sahip değildir. Örneğin, bir çalışanın vardiyası 18:00'de başlıyorsa ve 8 saat sürüyorsa, yapıya TimeOnly 8 saat eklendiğinde saat 2:00'ye yuvarlanır.
  • Günün bir saati için kullanmak DateTime için rastgele bir tarihin saatle ilişkilendirilmesi ve daha sonra göz ardı edilmesi gerekir. Tarih olarak (0001-01-01) seçmek DateTime.MinValue yaygın bir uygulamadır, ancak saat değeri çıkarılırsa DateTime bir OutOfRange özel durum oluşabilir. TimeOnly 24 saatlik zaman çerçevesi boyunca zaman ileri ve geri doğru ilerlerken bu sorun olmaz.
  • Bir DateTime yapıyı seri hale getirme, verilerin amacını gizleyebilecek tarih bileşenini içerir. Ayrıca, TimeOnly daha az veriyi seri hale getirir.

hakkında TimeOnlydaha fazla bilgi için bkz . DateOnly ve TimeOnly yapılarını kullanma.

Önemli

TimeOnly .NET Framework'te kullanılamaz.

TimeZoneInfo sınıfı

TimeZoneInfo sınıfı, Dünya'nın saat dilimlerinden herhangi birini temsil eder ve bir saat dilimindeki herhangi bir tarih ve saatin başka bir saat dilimindeki eşdeğerine dönüştürülmesi sağlar. sınıfı TimeZoneInfo , tarih ve saatlerle çalışmayı mümkün kılar, böylece herhangi bir tarih ve saat değeri zaman içinde tek bir noktayı kesin olarak tanımlar. Sınıfı TimeZoneInfo da genişletilebilir. Windows sistemleri için sağlanan ve kayıt defterinde tanımlanan saat dilimi bilgilerine bağlı olsa da, özel saat dilimlerinin oluşturulmasını destekler. Ayrıca saat dilimi bilgilerinin seri hale getirilmesini ve seri durumdan çıkarılması da desteklenir.

Bazı durumlarda, sınıfından TimeZoneInfo tam olarak yararlanmak için daha fazla geliştirme çalışması gerekebilir. Tarih ve saat değerleri ait oldukları saat dilimleriyle sıkı bir şekilde birleştirilmemişse, daha fazla çalışma yapılması gerekir. Uygulamanız bir tarih ve saati ilişkili saat dilimine bağlamak için bir mekanizma sağlamadığı sürece, belirli bir tarih ve saat değerinin saat dilimiyle ilişkilendirilmesi kolaydır. Bu bilgileri bağlamanın bir yöntemi, hem tarih ve saat değerini hem de ilişkili saat dilimi nesnesini içeren bir sınıf veya yapı tanımlamaktır.

.NET'teki saat dilimi desteğinden yararlanmak için, tarih ve saat nesnesinin örneği oluşturulurken tarih ve saat değerinin ait olduğu saat dilimini bilmeniz gerekir. Saat dilimi genellikle, özellikle web veya ağ uygulamalarında bilinmez.

Ayrıca bkz.