Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Bár mind a DateTimeDateTimeOffset struktúrák olyan tagokat biztosítanak, amelyek az értékükön aritmetikai műveleteket végeznek, az aritmetikai műveletek eredményei nagyon eltérőek. Ez a cikk megvizsgálja ezeket a különbségeket, a dátum- és időadatok időzóna-tudatosságának fokával kapcsolja össze őket, és ismerteti, hogyan hajthat végre teljes időzóna-észlelési műveleteket dátum- és időadatok használatával.
Összehasonlítások és számtani műveletek DateTime-értékekkel
A DateTime.Kind tulajdonság lehetővé teszi, hogy egy DateTimeKind érték hozzá legyen rendelve a dátumhoz és az időhöz, hogy jelezze, hogy a helyi idő, az egyezményes világidő (UTC) vagy egy meghatározatlan időzóna időpontja. Ez a korlátozott időzóna-információ azonban figyelmen kívül lesz hagyva a dátum- és időritmetikai DateTimeKind értékek összehasonlításakor vagy végrehajtásakor. Az alábbi példa, amely összehasonlítja az aktuális helyi időt az aktuális UTC-időponttal, azt mutatja be, hogy a rendszer hogyan hagyja figyelmen kívül az időzóna adatait.
using System;
public enum TimeComparison2
{
EarlierThan = -1,
TheSameAs = 0,
LaterThan = 1
}
public class DateManipulation
{
public static void Main()
{
DateTime localTime = DateTime.Now;
DateTime utcTime = DateTime.UtcNow;
Console.WriteLine("Difference between {0} and {1} time: {2}:{3} hours",
localTime.Kind,
utcTime.Kind,
(localTime - utcTime).Hours,
(localTime - utcTime).Minutes);
Console.WriteLine("The {0} time is {1} the {2} time.",
localTime.Kind,
Enum.GetName(typeof(TimeComparison2), localTime.CompareTo(utcTime)),
utcTime.Kind);
}
}
// If run in the U.S. Pacific Standard Time zone, the example displays
// the following output to the console:
// Difference between Local and Utc time: -7:0 hours
// The Local time is EarlierThan the Utc time.
Public Enum TimeComparison As Integer
EarlierThan = -1
TheSameAs = 0
LaterThan = 1
End Enum
Module DateManipulation
Public Sub Main()
Dim localTime As Date = Date.Now
Dim utcTime As Date = Date.UtcNow
Console.WriteLine("Difference between {0} and {1} time: {2}:{3} hours", _
localTime.Kind.ToString(), _
utcTime.Kind.ToString(), _
(localTime - utcTime).Hours, _
(localTime - utcTime).Minutes)
Console.WriteLine("The {0} time is {1} the {2} time.", _
localTime.Kind.ToString(), _
[Enum].GetName(GetType(TimeComparison), localTime.CompareTo(utcTime)), _
utcTime.Kind.ToString())
' If run in the U.S. Pacific Standard Time zone, the example displays
' the following output to the console:
' Difference between Local and Utc time: -7:0 hours
' The Local time is EarlierThan the Utc time.
End Sub
End Module
A CompareTo(DateTime) módszer azt jelenti, hogy a helyi idő korábbi (vagy kisebb) az UTC-időnél, a kivonási művelet pedig azt jelzi, hogy az Egyesült Államok csendes-óceáni standard időzónájában lévő rendszer UTC és a helyi idő közötti különbség hét óra. Mivel azonban ez a két érték egy adott időpont különböző ábrázolását adja meg, ebben az esetben egyértelmű, hogy az időintervallum teljes mértékben a helyi időzóna UTC-től való eltolódásának köszönhető.
Általánosságban elmondható, hogy a DateTime.Kind tulajdonság nem befolyásolja az összehasonlítási és aritmetikai módszerek által Kind visszaadott eredményeket (ahogy azt két azonos időpont összehasonlítása jelzi), bár ez befolyásolhatja az eredmények értelmezését. Például:
Bármely olyan aritmetikai művelet eredménye, amelyet két dátum- és időértéken hajtottak végre, amelyek DateTime.Kind tulajdonságai megegyeznek DateTimeKind , a két érték közötti tényleges időintervallumot tükrözik. Hasonlóképpen, két ilyen dátum- és időérték összehasonlítása pontosan tükrözi az időpontok közötti kapcsolatot.
Bármely olyan aritmetikai vagy összehasonlító művelet eredménye, amelyet két dátum- és időértéken hajtottak végre, amelyek DateTime.Kind tulajdonságai azonosak DateTimeKind vagy két dátum- és időértéken különböző DateTime.Kind tulajdonságértékekkel, a két érték óraidejének különbségét tükrözik.
A helyi dátum- és időértékeken végzett aritmetikai vagy összehasonlító műveletek nem veszik figyelembe, hogy egy adott érték nem egyértelmű vagy érvénytelen-e, és nem veszik figyelembe a helyi időzóna nyári időszámításra vagy nyári időszámításra való áttéréséből eredő kiigazítási szabályok hatását sem.
Minden olyan művelet, amely összehasonlítja vagy kiszámítja az UTC és a helyi idő közötti különbséget, az eredményben a helyi időzóna UTC-től való eltolásával egyenlő időintervallumot tartalmaz.
Minden olyan művelet, amely összehasonlítja vagy kiszámítja a meghatározatlan idő és az UTC vagy a helyi idő közötti különbséget, az egyszerű óraidőt tükrözi. Az időzóna eltéréseit nem veszi figyelembe, és az eredmény nem tükrözi az időzóna-kiigazítási szabályok alkalmazását.
Minden olyan művelet, amely összehasonlítja vagy kiszámítja a két meghatározatlan időpont közötti különbséget, tartalmazhat egy ismeretlen időközt, amely két különböző időzónában lévő idő különbségét tükrözi.
Az időzóna-különbségek számos esetben nem befolyásolják a dátum- és időszámításokat (néhány ilyen forgatókönyv megvitatásához lásd: A DateTime, a DateTimeOffset, a TimeSpan és a TimeZoneInfo közötti választás), vagy ahol a dátum- és időadatok kontextusa határozza meg az összehasonlítási vagy aritmetikai műveletek jelentését.
Összehasonlítások és aritmetikai műveletek DateTimeOffset értékekkel
Az DateTimeOffset érték nem csak dátumot és időt tartalmaz, hanem olyan eltolást is, amely egyértelműen meghatározza ezt a dátumot és időt az UTC-hez viszonyítva. Ez az eltolás lehetővé teszi, hogy az egyenlőséget másként definiáljuk, mint a DateTime értékekre vonatkozóan. Míg az DateTime értékek egyenlők, ha azonos dátum- és időértékekkel rendelkeznek, az értékek egyenlők, DateTimeOffset ha mindkettő ugyanarra az időpontra hivatkozik. Ha összehasonlításban és a legtöbb olyan aritmetikai műveletben használják, amely meghatározza a két dátum és időpont közötti intervallumot, az DateTimeOffset érték pontosabb és kevésbé szükséges értelmezésre. Az alábbi példa, amely egyenértékű az előző példával, amely összehasonlítja a DateTimeOffset helyi és az UTC-értékeket DateTimeOffset , ezt a viselkedésbeli különbséget szemlélteti.
using System;
public enum TimeComparison
{
EarlierThan = -1,
TheSameAs = 0,
LaterThan = 1
}
public class DateTimeOffsetManipulation
{
public static void Main()
{
DateTimeOffset localTime = DateTimeOffset.Now;
DateTimeOffset utcTime = DateTimeOffset.UtcNow;
Console.WriteLine($"Difference between local time and UTC: {(localTime - utcTime).Hours}:{(localTime - utcTime).Minutes:D2} hours");
Console.WriteLine($"The local time is {Enum.GetName(typeof(TimeComparison), localTime.CompareTo(utcTime))} UTC.");
}
}
// Regardless of the local time zone, the example displays
// the following output to the console:
// Difference between local time and UTC: 0:00 hours.
// The local time is TheSameAs UTC.
Public Enum TimeComparison As Integer
EarlierThan = -1
TheSameAs = 0
LaterThan = 1
End Enum
Module DateTimeOffsetManipulation
Public Sub Main()
Dim localTime As DateTimeOffset = DateTimeOffset.Now
Dim utcTime As DateTimeOffset = DateTimeOffset.UtcNow
Console.WriteLine("Difference between local time and UTC: {0}:{1:D2} hours.", _
(localTime - utcTime).Hours, _
(localTime - utcTime).Minutes)
Console.WriteLine("The local time is {0} UTC.", _
[Enum].GetName(GetType(TimeComparison), localTime.CompareTo(utcTime)))
End Sub
End Module
' Regardless of the local time zone, the example displays
' the following output to the console:
' Difference between local time and UTC: 0:00 hours.
' The local time is TheSameAs UTC.
' Console.WriteLine(e.GetType().Name)
Ebben a példában a CompareTo metódus azt jelzi, hogy az aktuális helyi idő és az aktuális UTC idő egyenlő, az értékek kivonása CompareTo(DateTimeOffset) pedig azt jelzi, hogy a két időpont közötti különbség .TimeSpan.Zero
Az értékek dátum- és időszámítási műveletekben való DateTimeOffset használatának fő korlátozása az, hogy bár a DateTimeOffset értékeknek van némi időzóna-ismeretük, nem teljesen ismerik az időzónákat. Bár az DateTimeOffset érték eltolása az időzóna UTC-től való eltolódását tükrözi, amikor egy DateTimeOffset változó először értéket kap, azután függetlenedik az időzónától. Mivel már nincs közvetlenül hozzárendelve egy azonosítható időponthoz, a dátum- és időintervallumok összeadása és kivonása nem veszi figyelembe az időzóna beállítási szabályait.
A szemléltetés érdekében az amerikai központi téli időzónában a nyári időszámításra való áttérés 2008. március 9-én hajnali 2:00-kor történik. Ezt szem előtt tartva, ha egy közép-szabványos időpontot, 2008. március 9-én 1:30-kor, két és fél órával későbbre időzítünk, akkor az eredmény 2008. március 9-én 5:00-kor lesz. Az alábbi példa azonban azt mutatja, hogy az összeadás eredménye 2008. március 9-én 4:00 óra. Ennek a műveletnek az eredménye nem a megfelelő időpontot jelöli, bár nem abban az időzónában, amelyben érdeklődünk (vagyis nem rendelkezik a várt időzóna-eltolással).
using System;
public class IntervalArithmetic
{
public static void Main()
{
DateTime generalTime = new DateTime(2008, 3, 9, 1, 30, 0);
const string tzName = "Central Standard Time";
TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);
// Instantiate DateTimeOffset value to have correct CST offset
try
{
DateTimeOffset centralTime1 = new DateTimeOffset(generalTime,
TimeZoneInfo.FindSystemTimeZoneById(tzName).GetUtcOffset(generalTime));
// Add two and a half hours
DateTimeOffset centralTime2 = centralTime1.Add(twoAndAHalfHours);
// Display result
Console.WriteLine($"{centralTime1} + {twoAndAHalfHours.ToString()} hours = {centralTime2}");
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("Unable to retrieve Central Standard Time zone information.");
}
}
}
// The example displays the following output to the console:
// 3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 4:00:00 AM -06:00
Module IntervalArithmetic
Public Sub Main()
Dim generalTime As Date = #03/09/2008 1:30AM#
Const tzName As String = "Central Standard Time"
Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)
' Instantiate DateTimeOffset value to have correct CST offset
Try
Dim centralTime1 As New DateTimeOffset(generalTime, _
TimeZoneInfo.FindSystemTimeZoneById(tzName).GetUtcOffset(generalTime))
' Add two and a half hours
Dim centralTime2 As DateTimeOffset = centralTime1.Add(twoAndAHalfHours)
' Display result
Console.WriteLine("{0} + {1} hours = {2}", centralTime1, _
twoAndAHalfHours.ToString(), _
centralTime2)
Catch e As TimeZoneNotFoundException
Console.WriteLine("Unable to retrieve Central Standard Time zone information.")
End Try
End Sub
End Module
' The example displays the following output to the console:
' 3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 4:00:00 AM -06:00
Időzónákban lévő időkkel rendelkező aritmetikai műveletek
Az TimeZoneInfo osztály olyan konverziós módszereket tartalmaz, amelyek automatikusan módosítják az időzónából a másikba való konvertáláskor a módosításokat. Ezek a konverziós módszerek a következők:
A ConvertTime és ConvertTimeBySystemTimeZoneId metódusok, amelyek az időt bármely két időzóna között alakítják át.
Azok ConvertTimeFromUtc a módszerek és ConvertTimeToUtc metódusok, amelyek egy adott időzónában lévő időt UTC-vé alakítják át, vagy az UTC-t egy adott időzónában lévő időpontra konvertálják.
További részletekért lásd: Időzónák közötti időátalakítás.
Az TimeZoneInfo osztály nem biztosít olyan metódusokat, amelyek automatikusan alkalmaznak korrekciós szabályokat a dátum- és időritkítás végrehajtásakor. A beállítási szabályokat azonban úgy alkalmazhatja, hogy az időzónában lévő időt UTC-vé alakítja, végrehajtja az aritmetikai műveletet, majd utc-ről visszatér az időzónában lévő időpontra. További részletekért lásd: Időzónák használata dátum- és időritkításban.
A következő kód például hasonló az előző kódhoz, amely 2008. március 9-én két és fél órát adott hozzá 2:00-ra. Mivel azonban a középsztenderdidőt UTC-re alakítja át, mielőtt dátum- és időszámítást végez, majd az UTC-ből származó eredményt visszaalakítja a központi téli időszámításra, az eredményül kapott idő tükrözi a központi standard időzóna nyári időszámításra való áttérését.
using System;
public class TimeZoneAwareArithmetic
{
public static void Main()
{
const string tzName = "Central Standard Time";
DateTime generalTime = new DateTime(2008, 3, 9, 1, 30, 0);
TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById(tzName);
TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);
// Instantiate DateTimeOffset value to have correct CST offset
try
{
DateTimeOffset centralTime1 = new DateTimeOffset(generalTime,
cst.GetUtcOffset(generalTime));
// Add two and a half hours
DateTimeOffset utcTime = centralTime1.ToUniversalTime();
utcTime += twoAndAHalfHours;
DateTimeOffset centralTime2 = TimeZoneInfo.ConvertTime(utcTime, cst);
// Display result
Console.WriteLine($"{centralTime1} + {twoAndAHalfHours.ToString()} hours = {centralTime2}");
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("Unable to retrieve Central Standard Time zone information.");
}
}
}
// The example displays the following output to the console:
// 3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 5:00:00 AM -05:00
Module TimeZoneAwareArithmetic
Public Sub Main()
Const tzName As String = "Central Standard Time"
Dim generalTime As Date = #03/09/2008 1:30AM#
Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tzName)
Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)
' Instantiate DateTimeOffset value to have correct CST offset
Try
Dim centralTime1 As New DateTimeOffset(generalTime, _
cst.GetUtcOffset(generalTime))
' Add two and a half hours
Dim utcTime As DateTimeOffset = centralTime1.ToUniversalTime()
utcTime += twoAndAHalfHours
Dim centralTime2 As DateTimeOffset = TimeZoneInfo.ConvertTime(utcTime, cst)
' Display result
Console.WriteLine("{0} + {1} hours = {2}", centralTime1, _
twoAndAHalfHours.ToString(), _
centralTime2)
Catch e As TimeZoneNotFoundException
Console.WriteLine("Unable to retrieve Central Standard Time zone information.")
End Try
End Sub
End Module
' The example displays the following output to the console:
' 3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 5:00:00 AM -05:00