Megosztás a következőn keresztül:


Válasszon a DateTime, a DateOnly, a DateTimeOffset, a TimeSpan, a TimeOnly és a TimeZoneInfo közül

A .NET-alkalmazások többféleképpen használhatják a dátum- és időadatokat. A dátum- és időadatok gyakoribb felhasználási módjai a következők:

  • Csak a dátumot tükrözze, hogy az időadatok ne legyenek fontosak.
  • Ha csak az időt szeretné tükrözni, hogy a dátumadatok ne legyenek fontosak.
  • Egy olyan absztrakt dátum és idő tükrözése, amely nem kötődik egy adott időponthoz és helyhez (például a legtöbb üzlet egy nemzetközi üzletláncban, amely hétköznap reggel 9:00-kor nyílik meg).
  • Dátum- és időadatok lekérése a .NET-en kívüli forrásokból, általában olyan helyekről, ahol a dátum- és időadatok egyszerű adattípusban vannak tárolva.
  • Egyetlen időpont egyedi és egyértelmű azonosítása. Egyes alkalmazások megkövetelik, hogy a dátum és az idő csak a gazdarendszeren legyen egyértelmű. Más alkalmazások esetében egyértelműnek kell lennie a rendszerek között (vagyis az egyik rendszeren szerializált dátumok értelmezhetően deszerializálhatók és használhatók a világ bármely pontján egy másik rendszeren).
  • Több kapcsolódó időpont (például a kérelmező helyi ideje és a kiszolgáló webes kéréshez való beérkezési ideje) megőrzése érdekében.
  • Dátum- és időritkítás végrehajtása, esetleg olyan eredménnyel, amely egyedileg és egyértelműen azonosít egy adott időpontot.

A .NET tartalmazza a DateTime, DateOnly, DateTimeOffset, TimeOnlyTimeSpan, és TimeZoneInfo típusokat, amelyek mindegyike használható dátumokkal és időpontokkal működő alkalmazások létrehozásához.

Feljegyzés

Ez a cikk nem tárgyalja TimeZone , mert a funkció szinte teljesen be van építve az TimeZoneInfo osztályba. Amikor csak lehetséges, használja az TimeZoneInfo osztályt az TimeZone osztály helyett.

A DateTimeOffset struktúra

A DateTimeOffset struktúra dátum- és időértéket jelöl, valamint egy eltolást, amely azt jelzi, hogy ez az érték mennyiben különbözik az UTC-től. Így az érték mindig egyértelműen azonosít egy adott időpontot.

A DateTimeOffset típus tartalmazza a típus összes funkcióját, valamint az DateTime időzóna-tudatosságot. Ez alkalmassá teszi az olyan alkalmazásokhoz, amelyek:

  • Egyedileg és egyértelműen azonosít egy időpontot. A DateTimeOffset típussal egyértelműen meghatározható a "now" jelentése, a tranzakciós idők naplózhatók, naplózhatók a rendszer- vagy alkalmazásesemények időpontjai, valamint rögzíthetők a fájllétrehozás és a módosítás időpontjai.
  • Végezze el az általános dátum- és időritkítást.
  • Őrizze meg a több kapcsolódó időpontot mindaddig, amíg ezek az idők két külön értékként vagy egy struktúra két tagjaként vannak tárolva.

Feljegyzés

Ezek az értékek használata DateTimeOffset sokkal gyakoribb, mint az értékeké DateTime . Ennek eredményeképpen vegye figyelembe DateTimeOffset az alkalmazásfejlesztés alapértelmezett dátum- és időtípusát.

Az DateTimeOffset érték nem egy adott időzónához van kötve, hanem különböző időzónákból származhat. Az alábbi példa felsorolja azokat az időzónákat, amelyekhez számos DateTimeOffset érték (beleértve a csendes-óceáni téli időt is) tartozhat.

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

A kimenet azt mutatja, hogy a példában szereplő dátum- és időértékek legalább három különböző időzónához tartozhatnak. A DateTimeOffset 2007.06.10-i érték azt mutatja, hogy ha egy dátum- és időérték nyári időszámítást jelent, akkor az UTC-ről való eltolása még csak nem is feltétlenül felel meg az eredeti időzóna alap UTC-eltolásának, vagy a megjelenített névben található UTC eltolásának. Mivel egyetlen DateTimeOffset érték nincs szorosan összekapcsolva az időzónával, nem tudja tükrözni az időzóna nyári időszámításra és nyári időről nyári időre való áttérését. Ez problémás lehet, ha a dátum- és időritkítás egy DateTimeOffset érték manipulálására szolgál. A dátum- és időritmetika időzóna-beállítási szabályainak figyelembevételével történő végrehajtásának módjáról az aritmetikai műveletek végrehajtása dátumokkal és időpontokkal című témakörben olvashat.

A DateTime-struktúra

Egy DateTime érték egy adott dátumot és időpontot határoz meg. Tartalmaz egy tulajdonságot Kind , amely korlátozott információt nyújt arról az időzónáról, amelyhez az adott dátum és idő tartozik. A DateTimeKind tulajdonság által Kind visszaadott érték azt jelzi, hogy az DateTime érték a helyi időt (DateTimeKind.Local), az egyezményes világidőt (UTC) vagyDateTimeKind.Utc a meghatározatlan időt (DateTimeKind.Unspecified) jelöli-e.

A DateTime szerkezet az alábbi jellemzők közül egy vagy több jellemzővel rendelkező alkalmazásokhoz alkalmas:

  • Absztrakt dátumok és időpontok használatával.
  • Olyan dátumokkal és időpontokkal dolgozhat, amelyekről hiányzik az időzóna információja.
  • Csak UTC-dátumokkal és időpontokkal dolgozhat.
  • Végezze el a dátum- és időritkítást, de az általános eredményekkel foglalkozik. Egy hat hónapot egy adott dátumhoz és időponthoz hozzáfűző műveletnél például gyakran nem fontos, hogy az eredmény a nyári időszámításhoz legyen-e igazítva.

Ha egy adott DateTime érték nem az UTC értéket jelöli, ez a dátum- és időérték gyakran nem egyértelmű vagy korlátozott a hordozhatóságában. Ha például egy DateTime érték a helyi időt jelöli, az a helyi időzónán belül hordozható (vagyis ha az érték deszerializálva van egy másik, ugyanabban az időzónában lévő rendszeren, akkor az érték továbbra is egyértelműen azonosítja az adott időpontot). A helyi időzónán kívül ez DateTime az érték több értelmezést is tartalmazhat. Ha az érték tulajdonsága Kind DateTimeKind.Unspecified, akkor még kevésbé hordozható: most már nem egyértelmű ugyanazon az időzónán belül, és valószínűleg ugyanazon a rendszeren is, ahol először szerializálták. Csak akkor, ha egy DateTime érték az UTC értéket jelöli, az az érték egyértelműen azonosít egy időpontot, függetlenül attól a rendszertől vagy időzónától, amelyben az értéket használják.

Fontos

Adatok mentésekor vagy megosztásakor DateTime használja az UTC értéket, és állítsa az DateTime érték tulajdonságát Kind a következőre DateTimeKind.Utc: .

A DateOnly struktúra

A DateOnly struktúra egy adott dátumot jelöl, idő nélkül. Mivel nincs időösszetevője, a nap elejétől a nap végéig egy dátumot jelöl. Ez a szerkezet ideális adott dátumok, például születési dátum, évfordulós dátum, ünnep vagy üzleti dátum tárolására.

Bár használhatja DateTime az időösszetevő figyelmen kívül hagyása során, a használatnak DateOnly DateTimevan néhány előnye:

  • A DateTime struktúra az előző vagy a következő napra kerülhet, ha egy időzóna eltolása történik. DateOnly nem lehet időzóna szerint eltűrni, és mindig a beállított dátumot jelöli.
  • A DateTime struktúra szerializálása magában foglalja az időösszetevőt, amely elhomályosíthatja az adatok szándékát. DateOnly Emellett kevesebb adatot szerializál.
  • Amikor a kód egy adatbázissal (például az SQL Serverrel) kommunikál, a rendszer általában a teljes dátumokat tárolja adattípusként date , ami nem tartalmaz időt. DateOnly jobban megfelel az adatbázis típusának.

További információDateOnly: How to use the DateOnly and TimeOnly structures.

Fontos

DateOnly.NET-keretrendszer nem érhető el.

A TimeSpan struktúra

A TimeSpan struktúra egy időintervallumot jelöl. Két jellemző felhasználási módja a következő:

  • Önkifejezés két dátum és időérték közötti időintervallumot. Ha például kivon egy értéket egy DateTime másikból, az egy TimeSpan értéket ad vissza.
  • Az eltelt idő mérése. A tulajdonság például egy TimeSpan olyan értéket ad vissza, Stopwatch.Elapsed amely azt az időintervallumot tükrözi, amely a hívás óta eltelt az egyik metódushoz, amely megkezdi az Stopwatch eltelt idő mérését.

Egy TimeSpan érték akkor is használható helyettesítő DateTime értékként, ha ez az érték egy adott napra való hivatkozás nélküli időt tükröz. Ez a használat hasonló a DateTime.TimeOfDay tulajdonságokhoz, DateTimeOffset.TimeOfDay és olyan értéket ad vissza, amely dátumra való hivatkozás nélkül adja vissza TimeSpan az időt. A struktúra használható például az TimeSpan áruház napi nyitvatartási vagy záró időpontjának tükrözésére, vagy arra, hogy a szokásos események mikor következnek be.

Az alábbi példa egy olyan struktúrát StoreInfo határoz meg, amely az áruház megnyitásának és zárási idejének objektumait, valamint az TimeZoneInfo áruház időzónáját képviselő objektumot tartalmazTimeSpan. A struktúra két metódust is tartalmaz, amelyek IsOpenAtazt jelzik, IsOpenNow hogy az áruház a felhasználó által megadott időpontban van-e nyitva, és a rendszer feltételezi, hogy a helyi időzónában van.

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

A StoreInfo struktúrát ezután az ügyfélkód az alábbihoz hasonlóan használhatja.

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: True
//       Store is open at 04:59:00: False
//       Store is open at 18:31:00: True
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

A TimeOnly struktúra

A TimeOnly struktúra egy napközbeni értéket jelöl, például egy napi ébresztőórát, vagy azt, hogy mikor ebédel minden nap. TimeOnlya 00:00:00.0000000 - 23:59:59.99999999 tartományra korlátozódik, amely egy adott napidő.

A típus bevezetése előtt a TimeOnly programozók általában a DateTime típust vagy a TimeSpan típust használták egy adott időpont megjelenítéséhez. Ha azonban ezeket a struktúrákat dátum nélküli idő szimulálására használja, problémákat okozhat, ami TimeOnly a következő megoldásokat oldja meg:

  • TimeSpan az eltelt időt jelöli, például egy stopperrel mért időt. A felső tartomány több mint 29 000 év, és értéke negatív lehet az időben való visszalépés jelzésére. A negatív TimeSpan érték nem jelzi a nap adott időpontját.
  • Ha TimeSpan napidőként használják, fennáll annak a kockázata, hogy a 24 órás napon kívüli értékre lehet manipulálni. TimeOnly nem áll fenn ez a kockázat. Ha például egy alkalmazott műszakja 18:00-kor kezdődik, és 8 órán át tart, 8 órát ad hozzá a TimeOnly struktúrához, és 2:00-ra vált.
  • A napokra való használathoz DateTime tetszőleges dátumot kell társítani az időhöz, majd később figyelmen kívül kell hagyni. Gyakori eljárás, hogy dátumként a (0001-01-01) értéket választja DateTime.MinValue , de ha az órákat kivonja az DateTime értékből, OutOfRange kivétel léphet fel. TimeOnly nincs ez a probléma, mivel az idő előre és hátragörget a 24 órás időkeret körül.
  • A DateTime struktúra szerializálása magában foglalja a dátum összetevőt, amely elhomályosíthatja az adatok szándékát. TimeOnly Emellett kevesebb adatot szerializál.

További információTimeOnly: How to use the DateOnly and TimeOnly structures.

Fontos

TimeOnly.NET-keretrendszer nem érhető el.

A TimeZoneInfo osztály

Az TimeZoneInfo osztály a Föld időzónáinak bármelyikét jelöli, és lehetővé teszi az egy időzónában lévő dátumok és időpontok átváltását egy másik időzónában lévő egyenértékűre. Az TimeZoneInfo osztály lehetővé teszi a dátumokkal és időpontokkal való munkát, hogy a dátum- és időértékek egyértelműen azonosíthassák az adott időpontot. Az TimeZoneInfo osztály bővíthető is. Bár a Windows-rendszerekhez megadott és a beállításjegyzékben meghatározott időzóna-információktól függ, támogatja az egyéni időzónák létrehozását. Támogatja az időzóna-információk szerializálását és deszerializálását is.

Bizonyos esetekben az osztály teljes kihasználása TimeZoneInfo további fejlesztési munkát igényelhet. Ha a dátum- és időértékek nincsenek szorosan összekapcsolva azokkal az időzónákkal, amelyekhez tartoznak, további munkára van szükség. Ha az alkalmazás nem biztosít valamilyen mechanizmust egy dátum és idő társításához a hozzá tartozó időzónával, könnyen előfordulhat, hogy egy adott dátum és idő érték el lesz különítve az időzónától. Az információk összekapcsolásának egyik módja egy olyan osztály vagy struktúra definiálása, amely tartalmazza a dátum- és időértéket, valamint a hozzá tartozó időzóna-objektumot.

A .NET időzóna-támogatásának kihasználásához ismernie kell azt az időzónát, amelyhez egy dátum- és időérték tartozik az adott dátum- és időobjektum példányosításakor. Az időzóna gyakran nem ismert, különösen webes vagy hálózati alkalmazásokban.

Lásd még