Windows와 IANA 시간대를 어떻게 변환합니까?


149

시간대 태그 wiki에 설명 된대로 두 가지 다른 시간대 스타일이 있습니다.

  • Windows 및 .Net TimeZoneInfo클래스 (Windows에서 실행시) 와 함께 사용하기 위해 Microsoft에서 제공 한 항목 은 다음과 같은 값으로 식별됩니다 "Eastern Standard Time".

  • TZDB의 IANA에서 제공하고 TimeZoneInfoLinux 또는 OSX에서 실행할 때 .NET 클래스에서 사용되는 항목은 과 같은 값으로 식별됩니다 "America/New_York".

많은 인터넷 기반 API는 IANA 표준 시간대를 사용하지만 여러 가지 이유로이 표준을 Windows 표준 시간대 ID로 또는 그 반대로 변환해야 할 수도 있습니다.

.Net에서 어떻게이 작업을 수행 할 수 있습니까?

답변:


198

Windows와 IANA 시간대 ID 간 변환을위한 데이터의 기본 소스는 windowsZones.xml파일이며 유니 코드 CLDR 프로젝트의 일부로 분배됩니다 . 최신 개발 버전은 여기 에서 찾을 수 있습니다 .

그러나 CLDR은 매년 두 번만 릴리스됩니다. 이로 인해 Windows 업데이트주기 및 IANA 표준 시간대 데이터베이스의 불규칙 업데이트와 함께 CLDR 데이터를 직접 사용하는 것이 복잡해집니다. 표준 시간대 변경 자체는 전 세계 여러 정부의 요구에 따라 이루어지며 모든 변경이 각각의 유효 날짜 이전에 이러한 릴리스 주기로 변경 될 수 있도록 충분한 통지를받은 것은 아닙니다.

CLDR이 엄밀히 다루지 않는 처리해야 할 몇 가지 다른 경우가 있으며 때때로 새로운 경우가 나타납니다. 따라서 솔루션의 복잡성 을 Nuget에서 설치할 수있는 TimeZoneConverter 마이크로 라이브러리에 캡슐화했습니다.

이 라이브러리를 사용하는 것은 간단합니다. 다음은 변환의 예입니다.

string tz = TZConvert.IanaToWindows("America/New_York");
// Result:  "Eastern Standard Time"

string tz = TZConvert.WindowsToIana("Eastern Standard Time");
// result:  "America/New_York"

string tz = TZConvert.WindowsToIana("Eastern Standard Time", "CA");
// result:  "America/Toronto"

프로젝트 사이트 에는 더 많은 예제 가 있습니다 .

IANA 표준 시간대를 단일 Windows 표준 시간대로 매핑 할 수 있지만 그 반대는 아닙니다. 단일 Windows 시간대가 둘 이상의 IANA 시간대에 매핑 될 수 있습니다. 이것은 위의 예에서 볼 수 있습니다. 여기서는 및로 Eastern Standard Time모두 매핑 America/New_York됩니다 America/Toronto. TimeZoneConverter는 "001"국가 코드를 구체적으로 제공하지 않고 해당 국가의 다른 영역과 일치하지 않는 한 CLDR 이 "골든 존"이라고 표시 한 것을 제공합니다.

참고 :이 답변은 수년간 발전해 왔으므로 아래 주석은 현재 개정판에 적용되거나 적용되지 않을 수 있습니다. 자세한 내용은 편집 기록을 검토하십시오. 감사.


1
변환 할 때이 방법을 사용하여 (GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi제공 Asia/Calcutta이 있어야한다 Asia/Kolkata. TzdbDateTimeZoneSource이전 값 이 포함 된 것 같습니다 .
Anto Subash

1
@MattJohnson Asia/Kolkata사용 IanaToWindows 방법 을 변환하는 동안 실패합니다. 그러나 Asia/Calcutta이전 이름 과 함께 작동 합니다. 메서드를 업데이트 WindowsToIana했지만 IanaToWindows동일한 문제가 있습니다. 작동하지 않는 몇 가지 다른 영역은 America/Argentina/Buenos_Aires, America/Indiana/Indianapolis, Asia/Kathmandu.
Anto Subash

1
@AntoJSubash-다시 한번, 훌륭한 관찰! IanaToWindows보상 방법을 편집했습니다 . 매우 감사합니다!
Matt Johnson-Pint

2
@MattJohnson 두 번째 @sirrocco의 관찰입니다. 정식 ID를 사용하는 것도 var canonical = tzdbSource.CanonicalIdMap[ ianaZoneId ]; links = Enumerable.Repeat( canonical, 1 ).Concat( links );나를 위해 속임수를 사용했습니다.
Johannes Rudolph

2
@sirrocco-귀하의 의견을 더 빨리 보지 못했습니다. 기능을 업데이트했습니다. 감사!
Matt Johnson-Pint

4

나는 이것이 오래된 질문이라는 것을 알고 있지만 검색 할 때 찾은 가장 관련성 높은 게시물이기 때문에 여기서 공유 할 유스 케이스가있었습니다. 도커 리눅스 컨테이너를 사용하지만 Windows 서버에 배포하기 위해 .NET Core 앱을 개발 중이었습니다. 그래서 windows 시간대 이름을 지원하기 위해 docker Linux 컨테이너 만 필요했습니다. 다음을 수행하여 응용 프로그램 코드를 변경하지 않고이 작업을 수행했습니다.

cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
cp /usr/share/zoneinfo/America/New_York "/usr/share/zoneinfo/Eastern Standard Time"
cp /usr/share/zoneinfo/America/Denver "/usr/share/zoneinfo/Mountain Standard Time"
cp /usr/share/zoneinfo/America/Los_Angeles "/usr/share/zoneinfo/Pacific Standard Time"

그런 다음 내 .NET 코드에서 다음을 수정하지 않고 작동했습니다. TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")


1
그것은 매우 훌륭한 아이디어입니다! 특정 시간대를 다루는 한 괜찮은 것 같습니다. 미국에는 4 명 이상이 있다는 것을 명심하십시오. 현재 하루에 50 개 주를 포함하기 위해, 당신은 또한에 대한 링크를 추가해야합니다 America/Phoenix"US Mountain Standard Time", Pacific/Honolulu"Hawaiian Standard Time", America/Anchorage"Alaskan Standard Time", 그리고 America/Adak"Aleutian Standard Time". 그것은 미국 영토 나 역사적 불일치를 다루지 않지만 시작하게 할 것입니다.
Matt Johnson-Pint

2
전 세계를 대상으로하거나 유효한 시간대 식별자를 처리하려는 경우이 방법을 사용하지 않는 것이 좋습니다. 목록이 너무 길고 너무 휘발성입니다.
Matt Johnson-Pint
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.