Cara: Menggunakan zona waktu dalam aritmetika tanggal dan waktu
Biasanya, ketika Anda melakukan aritmatika tanggal dan waktu menggunakan nilai DateTime atau DateTimeOffset, hasilnya tidak mencerminkan aturan penyesuaian zona waktu apa pun. Ini berlaku bahkan ketika zona waktu nilai tanggal dan waktu dapat diidentifikasi dengan jelas (misalnya, ketika properti Kind diatur ke Local). Topik ini menunjukkan cara melakukan operasi aritmatika pada nilai tanggal dan waktu yang termasuk dalam zona waktu tertentu. Hasil operasi aritmatika akan mencerminkan aturan penyesuaian zona waktu.
Untuk menerapkan aturan penyesuaian ke aritmatika tanggal dan waktu
Terapkan beberapa metode untuk menggabungkan nilai tanggal dan waktu dengan zona waktu tempatnya. Misalnya, nyatakan struktur yang menyertakan nilai tanggal dan waktu serta zona waktunya. Contoh berikut menggunakan pendekatan ini untuk menautkan nilai DateTime dengan zona waktunya.
// Define a structure for DateTime values for internal use only internal struct TimeWithTimeZone { TimeZoneInfo TimeZone; DateTime Time; }
' Define a structure for DateTime values for internal use only Friend Structure TimeWithTimeZone Dim TimeZone As TimeZoneInfo Dim Time As Date End Structure
Konversikan waktu menjadi Waktu Universal Terkoordinasi (UTC) dengan memanggil metode ConvertTimeToUtc atau metode ConvertTime.
Lakukan operasi aritmatika pada waktu UTC.
Konversikan waktu dari UTC ke zona waktu terkait waktu asli dengan memanggil metode TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo).
Contoh
Contoh berikut menambahkan dua jam dan tiga puluh menit ke 9 Maret 2008, pada pukul 01.30 Waktu Standar Pusat. Transisi zona waktu ke waktu musim panas terjadi tiga puluh menit kemudian, pada pukul 02.00 pada tanggal 9 Maret 2008. Karena contoh mengikuti empat langkah yang tercantum di bagian sebelumnya, contoh tersebut melaporkan waktu yang dihasilkan dengan benar sebagai 05.00 pada 9 Maret 2008.
using System;
public struct TimeZoneTime
{
public TimeZoneInfo TimeZone;
public DateTime Time;
public TimeZoneTime(TimeZoneInfo tz, DateTime time)
{
if (tz == null)
throw new ArgumentNullException("The time zone cannot be a null reference.");
this.TimeZone = tz;
this.Time = time;
}
public TimeZoneTime AddTime(TimeSpan interval)
{
// Convert time to UTC
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(this.Time, this.TimeZone);
// Add time interval to time
utcTime = utcTime.Add(interval);
// Convert time back to time in time zone
return new TimeZoneTime(this.TimeZone, TimeZoneInfo.ConvertTime(utcTime,
TimeZoneInfo.Utc, this.TimeZone));
}
}
public class TimeArithmetic
{
public const string tzName = "Central Standard Time";
public static void Main()
{
try
{
TimeZoneTime cstTime1, cstTime2;
TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById(tzName);
DateTime time1 = new DateTime(2008, 3, 9, 1, 30, 0);
TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);
cstTime1 = new TimeZoneTime(cst, time1);
cstTime2 = cstTime1.AddTime(twoAndAHalfHours);
Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time,
twoAndAHalfHours.ToString(),
cstTime2.Time);
}
catch
{
Console.WriteLine("Unable to find {0}.", tzName);
}
}
}
Public Structure TimeZoneTime
Public TimeZone As TimeZoneInfo
Public Time As Date
Public Sub New(tz As TimeZoneInfo, time As Date)
If tz Is Nothing Then _
Throw New ArgumentNullException("The time zone cannot be a null reference.")
Me.TimeZone = tz
Me.Time = time
End Sub
Public Function AddTime(interval As TimeSpan) As TimeZoneTime
' Convert time to UTC
Dim utcTime As DateTime = TimeZoneInfo.ConvertTimeToUtc(Me.Time, _
Me.TimeZone)
' Add time interval to time
utcTime = utcTime.Add(interval)
' Convert time back to time in time zone
Return New TimeZoneTime(Me.TimeZone, TimeZoneInfo.ConvertTime(utcTime, _
TimeZoneInfo.Utc, Me.TimeZone))
End Function
End Structure
Module TimeArithmetic
Public Const tzName As String = "Central Standard Time"
Public Sub Main()
Try
Dim cstTime1, cstTime2 As TimeZoneTime
Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tzName)
Dim time1 As Date = #03/09/2008 1:30AM#
Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)
cstTime1 = New TimeZoneTime(cst, time1)
cstTime2 = cstTime1.AddTime(twoAndAHalfHours)
Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, _
twoAndAHalfHours.ToString(), _
cstTime2.Time)
Catch
Console.WriteLine("Unable to find {0}.", tzName)
End Try
End Sub
End Module
Nilai DateTime dan DateTimeOffset dipisahkan dari zona waktu mana pun tempat nilai tersebut mungkin berada. Untuk melakukan aritmatika tanggal dan waktu dengan cara yang secara otomatis menerapkan aturan penyesuaian zona waktu, zona waktu tempat nilai tanggal dan waktu berada harus segera diidentifikasi. Ini berarti bahwa tanggal dan waktu dan zona waktu terkait harus digabungkan dengan erat. Ada beberapa cara untuk melakukan ini, yang mencakup hal-hal berikut:
Asumsikan bahwa semua waktu yang digunakan dalam aplikasi termasuk dalam zona waktu tertentu. Meskipun sesuai dalam beberapa kasus, pendekatan ini menawarkan fleksibilitas terbatas dan mungkin portabilitas terbatas.
Tentukan jenis yang menggabungkan tanggal dan waktu dengan erat dengan zona waktu terkait dengan menyertakan keduanya sebagai bidang jenis. Pendekatan ini digunakan dalam contoh kode, yang menentukan struktur untuk menyimpan tanggal dan waktu dan zona waktu di dua bidang anggota.
Contoh ini menggambarkan cara melakukan operasi aritmatika pada nilai DateTime sehingga aturan penyesuaian zona waktu diterapkan pada hasilnya. Namun, nilai DateTimeOffset dapat digunakan dengan mudah. Contoh berikut menggambarkan bagaimana kode dalam contoh asli mungkin disesuaikan untuk menggunakan DateTimeOffset, dan bukan nilai DateTime.
using System;
public struct TimeZoneTime
{
public TimeZoneInfo TimeZone;
public DateTimeOffset Time;
public TimeZoneTime(TimeZoneInfo tz, DateTimeOffset time)
{
if (tz == null)
throw new ArgumentNullException("The time zone cannot be a null reference.");
this.TimeZone = tz;
this.Time = time;
}
public TimeZoneTime AddTime(TimeSpan interval)
{
// Convert time to UTC
DateTimeOffset utcTime = TimeZoneInfo.ConvertTime(this.Time, TimeZoneInfo.Utc);
// Add time interval to time
utcTime = utcTime.Add(interval);
// Convert time back to time in time zone
return new TimeZoneTime(this.TimeZone, TimeZoneInfo.ConvertTime(utcTime, this.TimeZone));
}
}
public class TimeArithmetic
{
public const string tzName = "Central Standard Time";
public static void Main()
{
try
{
TimeZoneTime cstTime1, cstTime2;
TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById(tzName);
DateTime time1 = new DateTime(2008, 3, 9, 1, 30, 0);
TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);
cstTime1 = new TimeZoneTime(cst,
new DateTimeOffset(time1, cst.GetUtcOffset(time1)));
cstTime2 = cstTime1.AddTime(twoAndAHalfHours);
Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time,
twoAndAHalfHours.ToString(),
cstTime2.Time);
}
catch
{
Console.WriteLine("Unable to find {0}.", tzName);
}
}
}
Public Structure TimeZoneTime
Public TimeZone As TimeZoneInfo
Public Time As DateTimeOffset
Public Sub New(tz As TimeZoneInfo, time As DateTimeOffset)
If tz Is Nothing Then _
Throw New ArgumentNullException("The time zone cannot be a null reference.")
Me.TimeZone = tz
Me.Time = time
End Sub
Public Function AddTime(interval As TimeSpan) As TimeZoneTime
' Convert time to UTC
Dim utcTime As DateTimeOffset = TimeZoneInfo.ConvertTime(Me.Time, TimeZoneInfo.Utc)
' Add time interval to time
utcTime = utcTime.Add(interval)
' Convert time back to time in time zone
Return New TimeZoneTime(Me.TimeZone, TimeZoneInfo.ConvertTime(utcTime, Me.TimeZone))
End Function
End Structure
Module TimeArithmetic
Public Const tzName As String = "Central Standard Time"
Public Sub Main()
Try
Dim cstTime1, cstTime2 As TimeZoneTime
Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tzName)
Dim time1 As Date = #03/09/2008 1:30AM#
Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)
cstTime1 = New TimeZoneTime(cst, _
New DateTimeOffset(time1, cst.GetUtcOffset(time1)))
cstTime2 = cstTime1.AddTime(twoAndAHalfHours)
Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, _
twoAndAHalfHours.ToString(), _
cstTime2.Time)
Catch
Console.WriteLine("Unable to find {0}.", tzName)
End Try
End Sub
End Module
Perhatikan bahwa jika penambahan ini hanya dilakukan pada nilai DateTimeOffset tanpa terlebih dahulu mengonversinya ke UTC, hasilnya mencerminkan titik waktu yang benar tetapi offset-nya tidak mencerminkan zona waktu yang ditentukan untuk waktu itu.
Mengompilasi kode
Contoh ini membutuhkan:
- Bahwa namespace layanan System diimpor dengan pernyataan
using
(diperlukan dalam kode C#).
Lihat juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk