다음을 통해 공유


표준 시간대 간에 시간 변환

업데이트: 2007년 11월

날짜 및 시간을 사용하여 작업하는 응용 프로그램에서 표준 시간대 간의 차이를 처리하는 것이 더욱 중요해지고 있습니다. 응용 프로그램에서는 더 이상 DateTime 구조체를 통해 얻을 수 있는 시간인 현지 시간으로 모든 시간을 표시할 수 있다고 가정할 수 없습니다. 예를 들어 미국 동부 지역의 현재 시간을 표시하는 웹 페이지는 동아시아의 고객에게는 신뢰성이 떨어집니다. 이 항목에서는 한 표준 시간대에서 다른 표준 시간대로 변환하는 방법 및 표준 시간대 인식 수준이 제한된 DateTimeOffset 값을 변환하는 방법에 대해 설명합니다.

협정 세계시로 변환

UTC(협정 세계시)는 고정밀도 원자 시간 표준입니다. 전 세계의 표준 시간대는 UTC에서의 양 또는 음의 오프셋으로 표시됩니다. 따라서 UTC는 어느 정도 표준 시간대에서 자유롭거나 표준 시간대에 대해 중립적인 시간을 제공합니다. 컴퓨터 간에 날짜 및 시간의 이식성이 중요한 경우 UTC 시간을 사용하는 것이 좋습니다. 날짜 및 시간 사용에 대한 자세한 내용 및 기타 유용한 정보는 Coding Best Practices Using DateTime in the .NET Framework를 참조하십시오. 개별 표준 시간대를 UTC로 변환하면 보다 쉽게 시간을 비교할 수 있습니다.

참고:

또한 DateTimeOffset 구조체를 serialize하여 단일 시점을 명확하게 나타낼 수 있습니다. DateTimeOffset 개체에서는 날짜 및 시간 값과 UTC에서의 오프셋을 함께 저장하므로 항상 UTC를 기준으로 특정 시점을 나타냅니다.

시간을 UTC로 변환하는 가장 쉬운 방법은 static(Visual Basic의 경우 Shared) TimeZoneInfo.ConvertTimeToUtc(DateTime) 메서드를 호출하는 것입니다. 이 메서드에서 수행되는 정확한 변환은 다음 표와 같이 dateTime 매개 변수의 Kind 속성 값에 따라 다릅니다.

DateTime.Kind 속성

변환

DateTimeKind.Local

현지 시간을 UTC로 변환합니다.

DateTimeKind.Unspecified

dateTime 매개 변수가 현지 시간인 것으로 가정하고 현지 시간을 UTC로 변환합니다.

DateTimeKind.Utc

dateTime 매개 변수를 변경하지 않고 반환합니다.

다음 코드에서는 현재 현지 시간을 UTC로 변환하고 결과를 콘솔에 표시합니다.

Dim dateNow As Date = Date.Now      
Console.WriteLine("The date and time are {0} UTC.", _
                  TimeZoneInfo.ConvertTimeToUtc(dateNow))
DateTime dateNow = DateTime.Now;
Console.WriteLine("The date and time are {0} UTC.", 
                   TimeZoneInfo.ConvertTimeToUtc(dateNow));
참고:

TimeZoneInfo.ConvertTimeToUtc(DateTime) 메서드의 결과가 TimeZone.ToUniversalTimeDateTime.ToUniversalTime 메서드와 다를 수도 있습니다. 호스트 시스템의 현지 표준 시간대에 여러 조정 규칙이 포함된 경우 , TimeZoneInfo.ConvertTimeToUtc(DateTime)는 특정 날짜 및 시간에 적절한 규칙을 적용합니다. 다른 두 메서드는 항상 최신 조정 규칙을 적용합니다.

날짜 및 시간 값이 현지 시간이나 UTC를 나타내지 않는 경우 ToUniversalTime 메서드에서 잘못된 결과가 반환될 수 있습니다. 그러나 TimeZoneInfo.ConvertTimeToUtc 메서드를 사용하여 지정된 표준 시간대의 날짜 및 시간을 변환할 수 있습니다. 대상 표준 시간대를 나타내는 TimeZoneInfo 개체를 검색하는 방법에 대한 자세한 내용은 로컬 시스템에 정의된 표준 시간대 찾기를 참조하십시오. 다음 코드에서는 TimeZoneInfo.ConvertTimeToUtc 메서드를 사용하여 동부 표준시를 UTC로 변환합니다.

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                           
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 {0} UTC.", 
                     TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone));
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("Unable to find the {0} zone in the registry.", 
                     easternZoneId);
}                           
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the {0} zone has been corrupted.", 
                     easternZoneId);
}

DateTime 개체의 Kind 속성과 표준 시간대가 일치하지 않는 경우 이 메서드에서는 ArgumentException을 throw합니다. Kind 속성이 DateTimeKind.Local이지만 TimeZoneInfo 개체가 현지 표준 시간대를 나타내지 않는 경우 또는 Kind 속성이 DateTimeKind.Utc이지만 TimeZoneInfo 개체가 DateTimeKind.Utc와 같지 않은 경우에 불일치가 발생합니다.

이러한 모든 메서드에서는 DateTime 값을 매개 변수로 사용하고 DateTime 값을 반환합니다. DateTimeOffset 값의 경우 DateTimeOffset 구조체에 현재 인스턴스의 날짜 및 시간을 UTC로 변환하는 ToUniversalTime 인스턴스 메서드가 있습니다. 다음 예제에서는 ToUniversalTime 메서드를 호출하여 현지 시간과 여러 다른 시간을 UTC(협정 세계시)로 변환합니다.

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   
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   

UTC를 지정한 표준 시간대로 변환

UTC를 현지 시간으로 변환하려면 다음에 나오는 "UTC를 현지 시간으로 변환" 단원을 참조하십시오. UTC를 사용자가 지정하는 표준 시간대의 시간으로 변환하려면 ConvertTimeFromUtc 메서드를 호출합니다. 이 메서드에서는 다음과 같이 두 개의 매개 변수를 사용합니다.

다음 코드에서는 UTC를 중부 표준시로 변환합니다.

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
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.");
}

UTC를 현지 시간으로 변환

UTC를 현지 시간으로 변환하려면 시간을 변환할 DateTime 개체의 ToLocalTime 메서드를 호출합니다. 이 메서드의 정확한 동작은 다음 표에서 보여 주는 것처럼 개체의 Kind 속성 값에 따라 다릅니다.

DateTime.Kind 속성

변환

DateTimeKind.Local

DateTime 값을 변경하지 않고 반환합니다.

DateTimeKind.Unspecified

DateTime 값이 UTC인 것으로 가정하고 UTC를 현지 시간으로 변환합니다.

DateTimeKind.Utc

DateTime 값을 현지 시간으로 변환합니다.

참고   TimeZone.ToLocalTime 메서드는 DateTime.ToLocalTime 메서드와 똑같이 동작합니다. 이 메서드는 변환할 날짜 및 시간 값이라는 한 개의 매개 변수를 사용합니다.

또한 static(Visual Basic의 경우 Shared) TimeZoneInfo.ConvertTime 메서드를 사용하여 지정한 표준 시간대의 시간을 현지 시간으로 변환할 수 있습니다. 이 방법에 대해서는 다음 단원에서 설명합니다.

두 표준 시간대 간에 변환

TimeZoneInfo 클래스의 다음 두 static(Visual Basic의 경우 Shared) 메서드 중 하나를 사용하여 두 표준 시간대 간에 변환할 수 있습니다.

  • ConvertTime

    이 메서드의 매개 변수는 변환할 날짜 및 시간 값, 이 날짜 및 시간 값의 표준 시간대를 나타내는 TimeZoneInfo 개체, 날짜 및 시간 값을 변환할 표준 시간대를 나타내는 TimeZoneInfo 개체입니다.

  • ConvertTimeBySystemTimeZoneId

    이 메서드의 매개 변수는 변환할 날짜 및 시간 값, 이 날짜 및 시간 값의 표준 시간대에 대한 식별자, 날짜 및 시간 값을 변환할 표준 시간대에 대한 식별자입니다.

두 메서드의 경우 변환할 날짜 및 시간 값의 Kind 속성과 표준 시간대를 나타내는 TimeZoneInfo 개체 또는 표준 시간대 식별자가 각 메서드에 해당해야 합니다. 그렇지 않으면 ArgumentException이 throw됩니다. 예를 들어 날짜 및 시간 값의 Kind 속성이 DateTimeKind.Local이면 메서드에 매개 변수로 전달된 TimeZoneInfo 개체가 TimeZoneInfo.Local과 같지 않은 경우 예외가 throw됩니다. 메서드에 매개 변수로 전달된 식별자가 TimeZoneInfo.Local.Id와 같지 않은 경우에도 예외가 throw됩니다.

다음 예제에서는 ConvertTime 메서드를 사용하여 하와이 표준시를 현지 시간으로 변환합니다.

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                     
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.");
}

DateTimeOffset 값 변환

DateTimeOffset개체는 인스턴스화될 때 표준 시간대에서 분리되므로 이 개체로 나타낸 날짜 및 시간 값이 표준 시간대를 완전하게 인식하지 않습니다. 그러나 많은 경우 응용 프로그램에서는 특정 표준 시간대의 시간을 기준으로 하지 않고 단순히 UTC에서의 서로 다른 두 개의 오프셋을 기준으로 날짜 및 시간을 변환하면 됩니다. 이러한 변환을 수행하려면 현재 인스턴스의 ToOffset 메서드를 호출합니다. 이 메서드의 단일 매개 변수는 메서드에서 반환할 새 날짜 및 시간 값의 오프셋입니다.

예를 들어 웹 페이지에 대한 사용자 요청의 날짜 및 시간을 알고 있고 이 값이 MM/dd/yyyy hh:mm:ss zzzz 형식의 문자열로 serialize된 경우 다음 ReturnTimeOnServer 메서드에서는 이 날짜 및 시간 값을 웹 서버의 날짜 및 시간으로 변환합니다.

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
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;
   }
}

UTC보다 다섯 시간 이른 표준 시간대의 날짜 및 시간을 나타내는 문자열 "9/1/2007 5:32:07 -05:00"이 메서드에 전달되는 경우 이 메서드에서는 미국 태평양 표준 시간대에 있는 서버에 대해 9/1/2007 3:32:07 AM -07:00을 반환합니다.

TimeZoneInfo 클래스에는 DateTimeOffset 값을 사용하여 표준 시간대 변환을 수행하는 TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) 메서드의 오버로드도 포함되어 있습니다. 이 메서드의 매개 변수는 DateTimeOffset 값 및 시간이 변환될 표준 시간대에 대한 참조입니다. 이 메서드를 호출하면 DateTimeOffset 값이 반환됩니다. 예를 들어 이전 예제의 ReturnTimeOnServer 메서드를 다음과 같이 다시 작성하여 ConvertTime(DateTimeOffset, TimeZoneInfo) 메서드를 호출할 수 있습니다.

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
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;
   }
}

참고 항목

개념

로컬 시스템에 정의된 표준 시간대 찾기

참조

TimeZoneInfo

기타 리소스

시간 및 표준 시간대