Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Je stále důležitější pro každou aplikaci, která pracuje s daty a časy, aby zvládla rozdíly mezi časovými pásmy. Aplikace již nemůže předpokládat, že všechny časy mohou být vyjádřeny v místním čase, což je čas dostupný ze DateTime struktury. Například webová stránka, která zobrazuje aktuální čas ve východní části Spojených států, nebude mít důvěru pro zákazníka ve východní Asii. Tento článek vysvětluje, jak převést časy z jednoho časového pásma na jiné a převést DateTimeOffset hodnoty, které mají omezené povědomí o časovém pásmu.
Převod na koordinovaný univerzální čas
Koordinovaný univerzální čas (UTC) je standard s vysokou přesností a atomovým časem. Časová pásma světa jsou vyjádřena jako kladné nebo záporné posuny od UTC. UTC proto poskytuje čas nezávislý na časových zónách nebo časově neutrální. Použití standardu UTC se doporučuje, pokud je důležitá přenositelnost data a času mezi počítači. Podrobnosti a další osvědčené postupy při používání kalendářních dat a časů najdete v tématu Kódování osvědčených postupů pomocí dateTime v rozhraní .NET Framework. Převod jednotlivých časových pásem na UTC usnadňuje porovnání času.
Poznámka:
Můžete také serializovat DateTimeOffset strukturu tak, aby představovala jeden bod v čase jednoznačně. Vzhledem k tomu, že DateTimeOffset objekty ukládají hodnotu data a času spolu s posunem od času UTC, vždy představují konkrétní bod v čase vzhledem k času UTC.
Nejjednodušší způsob, jak převést čas na UTC, je volání static metody (Sharedv jazyce Visual Basic). TimeZoneInfo.ConvertTimeToUtc(DateTime) Přesný převod provedený metodou závisí na hodnotě dateTime vlastnosti parametru Kind , jak ukazuje následující tabulka:
DateTime.Kind |
Přeměna |
|---|---|
DateTimeKind.Local |
Převede místní čas na UTC. |
DateTimeKind.Unspecified |
Předpokládá, že dateTime parametr je místní čas a převede místní čas na UTC. |
DateTimeKind.Utc |
dateTime Vrátí parametr beze změny. |
Následující kód převede aktuální místní čas na UTC a zobrazí výsledek do konzoly:
DateTime dateNow = DateTime.Now;
Console.WriteLine($"The date and time are {TimeZoneInfo.ConvertTimeToUtc(dateNow)} UTC.");
Dim dateNow As Date = Date.Now
Console.WriteLine("The date and time are {0} UTC.", _
TimeZoneInfo.ConvertTimeToUtc(dateNow))
Pokud hodnota data a času nepředstavuje místní čas nebo UTC, ToUniversalTime metoda pravděpodobně vrátí chybný výsledek. Pomocí metody však můžete TimeZoneInfo.ConvertTimeToUtc převést datum a čas ze zadaného časového pásma. Podrobnosti o načtení objektu TimeZoneInfo , který představuje cílové časové pásmo, naleznete v tématu Vyhledání časových pásem definovaných v místním systému. Následující kód používá metodu k převodu východního standardního TimeZoneInfo.ConvertTimeToUtc času na UTC:
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 {TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone)} UTC.");
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine($"Unable to find the {easternZoneId} zone in the registry.");
}
catch (InvalidTimeZoneException)
{
Console.WriteLine($"Registry data on the {easternZoneId} zone has been corrupted.");
}
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
Metoda TimeZoneInfo.ConvertTimeToUtc vyvolá výjimku ArgumentException, pokud vlastnost DateTime objektu Kind a časové pásmo nejsou v souladu. Neshoda nastane, pokud je vlastnost KindDateTimeKind.Local ale TimeZoneInfo objekt nepředstavuje místní časové pásmo, nebo pokud je vlastnost KindDateTimeKind.Utc ale TimeZoneInfo objekt se nerovná TimeZoneInfo.Utc.
Všechny tyto metody přebírají DateTime hodnoty jako parametry a vracejí DateTime hodnotu. Pro DateTimeOffset hodnoty DateTimeOffset má struktura metodu ToUniversalTime instance, která převede datum a čas aktuální instance na UTC. Následující příklad volá metodu ToUniversalTime pro převod místního času a několika dalších časů na UTC:
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: {localTime}");
Console.WriteLine();
// Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero);
Console.WriteLine($"Other time: {otherTime}");
Console.WriteLine($"{localTime} = {otherTime}: {localTime.Equals(otherTime)}");
Console.WriteLine($"{localTime} exactly equals {otherTime}: {localTime.EqualsExact(otherTime)}");
Console.WriteLine();
// Convert other time to UTC
universalTime = localTime.ToUniversalTime();
Console.WriteLine($"Universal time: {universalTime}");
Console.WriteLine($"{otherTime} = {universalTime}: {universalTime.Equals(otherTime)}");
Console.WriteLine($"{otherTime} exactly equals {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
Převod UTC na určené časové pásmo
Pokud chcete převést UTC na místní čas, přečtěte si část Převod UTC na místní čas , která následuje. Pokud chcete převést utc na čas v libovolném časovém pásmu, které určíte, zavolejte metodu ConvertTimeFromUtc . Metoda má dva parametry:
UTC, který chcete převést. Musí to být DateTime hodnota, jejíž Kind vlastnost je nastavena na
UnspecifiedneboUtc.Časové pásmo, na které se má čas UTC převést.
Následující kód převede UTC na standardní čas (UTC):
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
Převod času UTC na místní čas
Chcete-li převést UTC na místní čas, zavolejte ToLocalTime metodu objektu DateTime , jehož čas chcete převést. Přesné chování metody závisí na hodnotě vlastnosti objektu Kind , jak ukazuje následující tabulka:
DateTime.Kind |
Přeměna |
|---|---|
DateTimeKind.Local |
DateTime Vrátí hodnotu beze změny. |
DateTimeKind.Unspecified |
Předpokládá, že DateTime hodnota je UTC a převede UTC na místní čas. |
DateTimeKind.Utc |
DateTime Převede hodnotu na místní čas. |
Poznámka:
Metoda TimeZone.ToLocalTime se chová stejně jako DateTime.ToLocalTime metoda. Vyžaduje jediný parametr, kterým je hodnota data a času k převedení.
Pomocí metody (staticv jazyce Visual Basic) Shared můžete také převést čas v libovolném určeném časovém pásmu na místní čas TimeZoneInfo.ConvertTime . Tato technika je popsána v další části.
Převod mezi dvěma časovými pásmy
Mezi libovolnými dvěma časovými pásmy můžete převádět pomocí některé z následujících dvou metod static třídy Shared (TimeZoneInfo v jazyce Visual Basic):
-
Parametry této metody jsou hodnota data a času, která se má převést,
TimeZoneInfoobjekt, který představuje časové pásmo hodnoty data a času, aTimeZoneInfoobjekt, který představuje časové pásmo pro převod hodnoty data a času na. -
Parametry této metody jsou hodnota data a času, která se má převést, identifikátor časového pásma hodnoty data a času a identifikátor časového pásma pro převod hodnoty data a času na.
Obě metody vyžadují, aby vlastnost hodnoty data a času, která má být převedena, a identifikátor objektu nebo časového pásma, který představuje jeho časové pásmo, vzájemně odpovídaly. V opačném případě se vyvolá ArgumentException. Pokud je například vlastnost hodnoty data a času Kind, je vyvolána výjimka, pokud objekt DateTimeKind.Local předán jako parametr metodě není roven TimeZoneInfo. Výjimka se vyvolá také v případě, že identifikátor předaný jako parametr metodě není rovna TimeZoneInfo.Local.Id.
Následující příklad používá metodu ConvertTime pro převod z havajského standardního času na místní čas:
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
Převod hodnot DateTimeOffset
Hodnoty data a času reprezentované DateTimeOffset objekty nejsou plně uzpůsobené časovému pásmu, protože objekt je oddělený od časového pásma v okamžiku své instantace. V mnoha případech ale aplikace potřebuje jednoduše převést datum a čas na základě dvou různých posunů oproti času UTC, nikoli podle času v konkrétních časových pásmech. Abyste mohli provést tento převod, můžete zavolat metodu ToOffset aktuální instance. Jediný parametr metody je posun hodnoty nového data a času, kterou metoda vrátí.
Pokud je například známo datum a čas požadavku uživatele na webovou stránku a je serializován jako řetězec ve formátu MM/dd/rrrr hh:mm:ss zzzz, následující ReturnTimeOnServer metoda převede tuto hodnotu data a času na datum a čas na webovém serveru:
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
Pokud metoda předá řetězec "9/1/2007 5:32:07 -05:00", který označuje datum a čas v časovém pásmu o pět hodin dříve než UTC, vrátí "9/1/2007 3:32:07 AM -07:00" pro server umístěný v tichooceánském standardním časovém pásmu.
Třída TimeZoneInfo také obsahuje přetížení TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) metody, která provádí převody časových pásem s ToOffset(TimeSpan) hodnotami. Parametry metody jsou DateTimeOffset hodnota a odkaz na časové pásmo, na které se má čas převést. Volání metody vrátí DateTimeOffset hodnotu. Například metodu ReturnTimeOnServer v předchozím příkladu lze přepsat následujícím způsobem, aby volala metodu 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