Saatleri saat dilimleri arasında dönüştürme
Tarih ve saatlerle çalışan tüm uygulamaların saat dilimleri arasındaki farkları işlemesi giderek daha önemli hale geliyor. Bir uygulama artık tüm zamanların yerel saatle ifade edilebildiğini varsayabilir. Bu, yapıdan DateTime kullanılabilir zamandır. Örneğin, Birleşik Devletler doğu kısmında geçerli saati görüntüleyen bir web sayfası, Doğu Asya'daki bir müşteriye güvenilirlik eksikliği gösterir. Bu makalede, zamanların bir saat diliminden diğerine nasıl dönüştürüldüğü ve sınırlı saat dilimi farkındalığı olan değerlerin nasıl dönüştürüldüğü DateTimeOffset açıklanır.
Eşgüdümlü Evrensel Saate Dönüştürme
Eşgüdümlü Evrensel Saat (UTC), yüksek duyarlıklı, atomik saat standardıdır. Dünyanın saat dilimleri UTC'den pozitif veya negatif uzaklık olarak ifade edilir. Bu nedenle UTC bir saat dilimi serbest veya saat dilimi nötr saat sağlar. Bilgisayarlar arasında bir tarih ve saatin taşınabilirliği önemli olduğunda UTC kullanılması önerilir. Tarih ve saatleri kullanan ayrıntılar ve diğer en iyi yöntemler için bkz . .NET Framework'te DateTime kullanarak en iyi yöntemleri kodlama. Tek tek saat dilimlerini UTC'ye dönüştürmek, zaman karşılaştırmalarını kolaylaştırır.
Not
Ayrıca, zaman içinde tek bir noktayı kesin bir şekilde temsil etmek için bir DateTimeOffset yapıyı seri hale getirebilirsiniz. DateTimeOffset Nesneler utc'den uzaklığıyla birlikte bir tarih ve saat değeri depoladığından, her zaman UTC ile ilgili olarak belirli bir noktayı temsil eder.
Saati UTC'ye dönüştürmenin en kolay yolu (Shared
Visual Basic'te) TimeZoneInfo.ConvertTimeToUtc(DateTime) yöntemini çağırmaktır static
. Yöntemi tarafından gerçekleştirilen tam dönüştürme, aşağıdaki tabloda gösterildiği gibi parametrenin dateTime
Kind ö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 |
parametresinin dateTime yerel saat olduğunu varsayar ve yerel saati UTC'ye dönüştürür. |
DateTimeKind.Utc |
Parametresini dateTime değiştirmeden 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 {TimeZoneInfo.ConvertTimeToUtc(dateNow)} UTC.");
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 etmiyorsa, ToUniversalTime yöntem büyük olasılıkla hatalı bir sonuç döndürür. Ancak, belirtilen bir saat diliminden tarih ve saati dönüştürmek için yöntemini kullanabilirsiniz TimeZoneInfo.ConvertTimeToUtc . Hedef saat dilimini temsil eden bir TimeZoneInfo nesneyi alma hakkında ayrıntılı bilgi için bkz . Yerel sistemde tanımlanan saat dilimlerini bulma. Aşağıdaki kod, Doğu Standart Saati'ni TimeZoneInfo.ConvertTimeToUtc 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 {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
TimeZoneInfo.ConvertTimeToUtc yöntemiArgumentException, nesnenin DateTimeKind özelliğiyle saat diliminin eşleşmemiş olup olmadığını oluşturur. Özelliğin olması ancak nesnenin yerel saat dilimini temsil etmemesi veya özelliğin DateTimeKind.UtcTimeZoneInfoKind eşit olmaması TimeZoneInfo.Utcdurumunda bir uyuşmazlık oluşur.TimeZoneInfoDateTimeKind.LocalKind
Bu yöntemlerin tümü değerleri parametre olarak alır DateTime ve bir DateTime değer döndürür. Değerler için DateTimeOffset yapı, DateTimeOffset geçerli örneğin tarih ve saatini UTC'ye dönüştüren bir ToUniversalTime örnek yöntemine sahiptir. Aşağıdaki örnek, yerel saati ve birkaç kez daha UTC'ye dönüştürmek için yöntemini çağırır ToUniversalTime :
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'yi yerel saate dönüştürme bölümüne bakın. UTC'yi belirlediğiniz herhangi bir saat dilimindeki saate dönüştürmek için yöntemini çağırın ConvertTimeFromUtc . yöntemi iki parametre alır:
Dönüştürülecek UTC. Bu, özelliği veya
Utc
olarak ayarlanmışUnspecified
bir DateTime değer Kind olmalıdır.UTC'yi dönüştürülecek saat dilimi.
Aşağıdaki kod UTC'yi Merkezi Standart Saat'e 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, saatini dönüştürmek istediğiniz nesnenin DateTime yöntemini çağırınToLocalTime. Yönteminin tam davranışı, aşağıdaki tabloda gösterildiği gibi nesnenin Kind özelliğinin değerine bağlıdır:
DateTime.Kind |
Dönüştürme |
---|---|
DateTimeKind.Local |
DateTime Değeri değiştirmeden döndürür. |
DateTimeKind.Unspecified |
Değerin DateTime UTC olduğunu varsayar ve UTC'yi yerel saate dönüştürür. |
DateTimeKind.Utc |
DateTime Değeri yerel saate dönüştürür. |
Not
yöntemi yöntemiyle TimeZone.ToLocalTimeDateTime.ToLocalTime
aynı şekilde davranır. Dönüştürmek için tarih ve saat değeri olan tek bir parametre gerekir.
Ayrıca, (Shared
Visual Basic'te) TimeZoneInfo.ConvertTime yöntemini kullanarak static
belirlenen herhangi bir saat dilimindeki saati yerel saate dönüştürebilirsiniz. Bu teknik sonraki bölümde açıklanmıştır.
herhangi iki saat dilimi arasında dönüştürme
sınıfının aşağıdaki iki yöntemden birini (Shared
Visual Basic'te) TimeZoneInfo kullanarak herhangi bir iki static
saat dilimi arasında dönüştürme yapabilirsiniz:
-
Bu yöntemin parametreleri dönüştürülecek tarih ve saat değeri,
TimeZoneInfo
tarih ve saat değerinin saat dilimini temsil eden birTimeZoneInfo
nesne ve tarih ve saat değerinin dönüştürüldüğü saat dilimini temsil eden nesnedir. -
Bu yöntemin parametreleri dönüştürülecek tarih ve saat değeri, tarih ve saat değerinin saat dilimi tanımlayıcısı ve tarih ve saat değerinin dönüştürülecek saat dilimi tanımlayıcısıdır.
Her iki yöntem de dönüştürülecek Kind tarih ve saat değerinin özelliğinin ve TimeZoneInfo saat dilimini temsil eden nesnenin veya saat dilimi tanımlayıcısının birbirine karşılık geldiğini gerektirir. Aksi takdirde, bir ArgumentException oluşturulur. Örneğin, tarih ve saat değerinin özelliği ise Kind
DateTimeKind.Local
, yöntemine parametre olarak geçirilen nesne değerine eşit TimeZoneInfo.Local
değilse TimeZoneInfo
bir özel durum oluşturulur. Yöntemine parametre olarak geçirilen tanımlayıcı ile eşit TimeZoneInfo.Local.Id
değilse bir özel durum da oluşturulur.
Aşağıdaki örnek, Hawaii Standart Saati'nden yerel saate dönüştürmek için yöntemini kullanır ConvertTime :
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 DateTimeOffset temsil edilen tarih ve saat değerleri tam olarak saat dilimine duyarlı değildir çünkü nesne örneği oluşturulduğu sırada saat dilimiyle ilişkilendirilmez. Ancak çoğu durumda, bir uygulamanın belirli saat dilimlerindeki saat yerine UTC'den iki farklı uzaklık temelinde bir tarih ve saati dönüştürmesi yeterlidir. Bu dönüştürmeyi gerçekleştirmek için geçerli örneğin ToOffset yöntemini çağırabilirsiniz. Yöntemin tek parametresi, yöntemin döndüreceği yeni tarih ve saat değerinin uzaklığıdır.
Örneğin, bir web sayfası için kullanıcı isteğinin tarih ve saati biliniyorsa ve AA/gg/yy hh:mm:ss zzzz biçiminde bir dize olarak seri hale getiriliyorsa, 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 önceki bir saat dilimindeki tarih ve saati temsil eden "1/9/2007 5:32:07 -05:00" dizesini geçirirse, ABD Pasifik Standart Saat diliminde bulunan bir sunucu için "1/9/2007 3:32:07 -07:00" değerini döndürür.
sınıfıTimeZoneInfo, saat dilimi dönüştürmelerini değerlerle ToOffset(TimeSpan) gerçekleştiren yönteminin aşırı yüklemesini TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) de içerir. Yöntemin parametreleri bir DateTimeOffset değerdir ve saatin dönüştürüldüğü saat dilimine başvurudur. Yöntem çağrısı bir DateTimeOffset değer döndürür. Örneğin, ReturnTimeOnServer
önceki örnekteki yöntem, yöntemini çağırmak ConvertTime(DateTimeOffset, TimeZoneInfo) için aşağıdaki gibi yeniden yazılabilir.
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