DateTime, DateTimeOffset 및 TimeZoneInfo 중 선택
업데이트: 2007년 11월
날짜 및 시간 정보를 사용하는 .NET Framework 응용 프로그램은 매우 다양하며, 이러한 응용 프로그램에서 이 정보를 사용하는 방법도 여러 가지가 있습니다. 다음은 날짜 및 시간 정보의 일반적인 사용 방법입니다.
날짜만 표시(시간 정보가 중요하지 않은 경우)
시간만 표시(날짜 정보가 중요하지 않은 경우)
특정 시간과 장소에 얽매이지 않은 추상적인 날짜와 시간 표시. 예를 들어, 대부분의 다국적 체인점은 평일 오전 9:00에 영업을 시작합니다.
일반적으로 날짜 및 시간 정보가 단순 데이터 형식으로 저장되는 .NET Framework 외부의 소스에서 날짜 및 시간 정보 검색
특정 시간을 고유하고 명확하게 식별. 어떤 응용 프로그램은 호스트 시스템의 날짜와 시간만 명확하면 되지만 어떤 응용 프로그램은 모든 시스템의 날짜와 시간이 명확해야 합니다. 즉, 특정 시스템에 serialize된 날짜가 전 세계 도처에 있는 다른 시스템에 의미 있게 deserialize되고 사용될 수 있습니다.
여러 개의 관련 시간(예: 요청자의 현지 시간과 서버의 웹 요청 수신 시간) 유지
날짜 및 시간 연산 수행(특정 시간을 고유하고 명확하게 식별하는 결과도 사용될 수 있음)
.NET Framework에는 DateTime, DateTimeOffset 및 TimeZoneInfo 형식이 있습니다. 이러한 형식은 모두 날짜와 시간을 사용하여 작업하는 응용 프로그램을 빌드하는 데 사용될 수 있습니다.
참고: |
---|
이 항목에서는 네 번째 형식인 TimeZone에 대해서는 설명하지 않습니다. 그 이유는 이 형식의 기능이 거의 모두 TimeZoneInfo 클래스에 통합되었기 때문입니다. 가능하면 개발자는 TimeZone 클래스 대신 TimeZoneInfo 클래스를 사용해야 합니다. |
DateTime 구조체
DateTime 값은 특정 날짜와 시간을 정의합니다. .NET Framework 버전 2.0부터는 날짜와 시간이 속한 표준 시간대에 대한 제한된 정보를 제공하는 Kind 속성이 포함되어 있습니다. Kind 속성에서 반환하는 DateTimeKind 값은 DateTime 값이 현지 시간(DateTimeKind.Local), UTC(협정 세계시)(DateTimeKind.Utc) 또는 지정되지 않은 시간(DateTimeKind.Unspecified) 중 무엇을 나타내는지를 가리킵니다.
DateTime 구조체는 다음과 같은 작업을 수행하는 응용 프로그램에 적합합니다.
날짜만 사용하는 작업
시간만 사용하는 작업
추상적인 날짜와 시간을 사용하는 작업
SQL 데이터베이스와 같이 .NET Framework 외부의 소스에서 날짜 및 시간 정보 검색. 일반적으로 이러한 소스에는 날짜 및 시간 정보가 DateTime 구조체와 호환되는 간단한 형식으로 저장됩니다.
일반적인 결과를 고려한 날짜 및 시간 연산 수행. 예를 들어, 특정 날짜와 시간에 6개월을 더하는 더하기 연산에서 결과가 일광 절약 시간에 따라 조정되는지 여부는 대개 중요하지 않습니다.
특정 DateTime 값이 UTC를 나타내지 않을 경우 일반적으로 날짜 및 시간 값은 여러 시간대가 적용되는 환경에서 모호하거나 제한됩니다. 예를 들어 DateTime 값이 현지 시간을 나타낼 경우 해당 현지 표준 시간대에서는 여러 시스템 간에 문제가 발생하지 않습니다. 즉, 이 값이 같은 표준 시간대에 있는 다른 시스템에 deserialize될 경우 특정 시간을 계속 명확하게 나타냅니다. 다른 표준 시간대에서는 해당 DateTime 값이 여러 값으로 해석될 수 있습니다. 이 값의 Kind 속성이 DateTimeKind.Unspecified일 경우 표준 시간대에 따라 문제가 발생할 수 있습니다. 즉, 같은 표준 시간대 내에서뿐 아니라 심지어 최초로 serialize된 같은 시스템 내에서도 이 값이 특정 시간을 모호하게 식별합니다. DateTime 값은 UTC를 나타내는 경우에만 해당 값이 사용된 시스템이나 표준 시간대에 관계없이 특정 시간을 명확하게 식별합니다.
중요: |
---|
DateTime 데이터를 저장하거나 공유할 때는 UTC를 사용해야 하고 DateTime 값의 Kind 속성을 DateTimeKindUTC()로 설정해야 합니다. |
DateTimeOffset 구조체
DateTimeOffset 구조체는 날짜 및 시간 값과 함께 이 값이 UTC와 얼마나 차이가 나는지를 나타내는 오프셋을 나타냅니다. 따라서 이 값은 특정 시간을 항상 명확하게 식별합니다.
DateTimeOffset 형식은 DateTime 형식의 기능을 대부분 포함하고 있지만 응용 프로그램 개발에서 DateTime 형식을 대체하기 위한 것은 아닙니다. 이 형식은 다음과 같은 작업을 수행하는 응용 프로그램에 적합합니다.
특정 시간을 고유하고 명확하게 식별. DateTimeOffset 형식은 "현재"의 의미를 명확하게 정의하고, 트랜잭션 시간을 기록하고, 시스템 또는 응용 프로그램 이벤트의 시간을 기록하고, 파일 생성 및 수정 시간을 기록하는 데 사용할 수 있습니다.
일반적인 날짜 및 시간 연산 수행
여러 개의 관련 시간 유지(이러한 시간이 서로 다른 두 개의 값이나 구조체의 두 멤버로 저장되는 경우에 한해)
참고: |
---|
일반적으로 DateTime 값보다 DateTimeOffset 값이 훨씬 더 많이 사용됩니다. 따라서 응용 프로그램을 개발할 때 DateTimeOffset을 기본 날짜 및 시간 형식으로 사용하는 것이 좋습니다. |
DateTimeOffset 값은 특정 표준 시간대에 속하지 않지만 다양한 표준 시간대 중 하나를 기점으로 할 수 있습니다. 이를 설명하기 위해 다음 예제에서는 현지 태평양 표준시를 포함하여 여러 DateTimeOffset 값이 속할 수 있는 표준 시간대를 나열합니다.
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
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
출력 내용을 보면 이 예제에 나오는 각 날짜 및 시간 값은 셋 이상의 서로 다른 표준 시간대에 속할 수 있습니다. DateTimeOffset 값 6/10/2007은 날짜 및 시간 값이 일광 절약 시간을 나타낼 경우 UTC의 오프셋이 원래 표준 시간대의 기본 UTC 오프셋이나 해당 표시 이름에 있는 UTC의 오프셋에 해당하지 않을 수 있음을 보여 줍니다. 즉, 단일 DateTimeOffset 값이 해당 표준 시간대와 밀접하게 결합되어 있지 않기 때문에 표준 시간대의 원래 시간과 일광 절약 시간 간의 전환 결과를 반영할 수 없습니다. 이것은 날짜 및 시간 연산을 사용하여 DateTimeOffset 값을 조작할 때 특히 문제가 될 수 있습니다. 표준 시간대의 조정 규칙을 고려하면서 날짜 및 시간 연산을 수행하는 방법에 대한 자세한 내용은 날짜 및 시간에 대한 산술 연산 수행을 참조하십시오.
TimeZoneInfo 클래스
TimeZoneInfo 클래스는 표준 시간대 중 하나를 나타내며, 특정 표준 시간대의 날짜와 시간을 다른 표준 시간대의 날짜와 시간으로 변환하는 데 사용할 수 있습니다. TimeZoneInfo 클래스를 사용하면 날짜 및 시간 작업을 통해 날짜 및 시간 값이 특정 시간을 명확하게 식별하도록 할 수 있습니다. 또한 TimeZoneInfo 클래스는 확장이 가능합니다. 이 클래스는 Windows 시스템에서 제공하며 레지스트리에 정의된 표준 시간대 정보를 사용하지만 사용자 지정 표준 시간대 만들기를 지원합니다. 뿐만 아니라 표준 시간대 정보의 serialization 및 deserialization도 지원합니다.
경우에 따라 TimeZoneInfo 클래스를 최대한 활용하려면 추가적인 개발 작업이 필요할 수 있습니다. 첫째, 날짜 및 시간 값이 해당 표준 시간대와 밀접하게 결합되어 있지 않기 때문에 응용 프로그램에서 날짜 및 시간을 해당 표준 시간대와 연결하는 메커니즘을 제공하지 않을 경우 특정 날짜 및 시간 값이 해당 표준 시간대와 연결되지 않을 가능성이 높습니다. 이 정보를 연결하는 한 가지 방법은 날짜 및 시간 값과 해당 연결된 표준 시간대 개체가 모두 포함된 클래스나 구조체를 정의하는 것입니다. 둘째, Windows XP와 그 이전 버전의 Windows에서는 기록 표준 시간대 정보를 실질적으로 지원하지 않고 Windows Vista에서는 제한적으로만 지원하기 때문에 기록 날짜 및 시간을 처리하도록 설계된 응용 프로그램에서 사용자 지정 표준 시간대를 폭넓게 사용해야 합니다.
날짜 및 시간 개체의 인스턴스가 만들어질 때 해당 날짜 및 시간 값이 속한 표준 시간대를 알 수 있는 경우에만 .NET Framework에서 표준 시간대 지원을 활용할 수 있습니다. 그러나 종종 특히, 웹 또는 네트워크 응용 프로그램에서는 이와 다를 수 있습니다.