TimeZoneInfo를 사용하여 일광 절약 시간 동안 현지 시간을 얻는 방법은 무엇입니까?


84

나는 DateTimeOffset어떤 시간대에서든 특정 순간을 전달 하기 위해 노력하고 있습니다 . TimeZoneInfo일광 절약 시간제 를 사용하는 방법을 알 수 없습니다 .

var dt = DateTime.UtcNow;
Console.WriteLine(dt.ToLocalTime());

var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
Console.WriteLine(utcOffset.ToOffset(tz.BaseUtcOffset));

다음과 같이 출력됩니다.

2010-06-02 오후 4:37:19
2010 년 6 월 2 일 오후 3:37:19 -06 : 00

저는 중부 표준 시간대에 있으며 현재 일광 절약 시간제입니다. 두 번째 줄을 읽으려고합니다.

2010 년 6 월 2 일 오후 4:37:19 -05 : 00

BaseUtcOffset 분명히 DST에 따라 변경되지 않습니다.

적절한 오프셋 값으로 적절한 시간을 어떻게 얻을 수 있습니까?


13
한 - 그것은 나를 TimeZoneInfo.ConvertTimeBySystemTimeZoneId이 : 아니 그냥 작업을 수행하는 것이 미친 드라이브
제임스 매닝

@JamesManning- dt.Kind올바르게 설정 되었다고 가정 합니다.
Matt Johnson-Pint

답변:


61

TimeZoneInfo에서 UtcOffset을 가져온 다음 ToOffset () 메서드에 전달해야합니다.

var dt = DateTime.UtcNow;
Console.WriteLine(dt.ToLocalTime());

var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));

알겠습니다. 시간대의 특정 날짜에 대한 UTC 오프셋을 가져와야합니다. 감사.
jaminto

5
이에 비해 가장 좋은 방법이 아니다 칼 Gjertsen의 대답 (가) 새로운 던져 - 멀리 생성을 통해 오프셋 추출하는 대신 일을 하나의 닷넷 함수를 사용합니다 DateTimeOffset.
ErikE

59

일광 절약 시간을 허용하는 TimeZoneInfo.ConvertTimeFromUtc를 사용할 수도 있습니다.

DateTime utc = DateTime.UtcNow;
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utc, zone);

우리나라의 시간대가 여름에는 EEST이고 겨울에는 EET이면 어떻게됩니까? 일광 절약과 어떻게 작동합니까?
Rami Zebian

1
Windows는 일광 절약 시간 날짜와 함께 시간대 정보를 알고 있습니다. 미리 정의 된 시간대 중 하나를 선택하면 해결되어야합니다.
Karl Gjertsen

11

또는 시간대 식별자 를 하드 코딩하지 않으려는 경우 :

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id);
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tzi);

2
그냥 TimeZoneInfo.Local직접 사용할 수 없나요? 왜 전화가 필요 FindSystemTimeZoneById합니까?
CoderDennis

4
당신 말이 맞습니다. 우리는 그것을 필요로하지 않습니다. 우리는 이렇게 할 수 있습니다DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(networkDateTime, TimeZoneInfo.Local);
Pabinator

1
그러나 그러면 단일 시간대로 고정됩니다. 내가 추측하는 코드를 사용하려는 방법에 따라 다릅니다. :-)
Karl Gjertsen 2015

9
이것은 매우 안전하지 않습니다. 애플리케이션을 클라우드 환경으로 아웃소싱하는 경우 어떤 시간대가 그 자체로 로컬인지 알 수 없습니다.

5

저는 .NET과 stackoverflow의 초보자이므로 틀릴 수 있지만 여기에 있습니다.

TimeZoneInfo.ConvertTimeFromUtc를 사용하면 일광 절약 시간이 허용되며 시간대 + 가능한 DST 오프셋에 따라 올바른 시간으로 변환됩니다. 그러나 결과 개체의 오프셋 자체는 표준 시간에 대한 오프셋을 표시하며 일광 절약 시간을 고려하지 않습니다. 따라서 객체에서 ToString을 수행하려는 경우 올바른 시간 (시간 및 분)이 표시되지만 일광 절약 시간 동안 잘못된 오프셋이 발생하여 나중에 코드에서 잘못된 시간으로 이어질 수 있습니다.

대신 GetUtcOffset을 사용하여 특정 시간에 대한 오프셋을 가져온 다음 DateTimeOffset 개체에 대해 ToOffset을 수행하면 시간 / 분과 오프셋 자체가 모두 올바르게 변환되고 ToString을 안전하게 수행 할 수 있습니다.

string ExpectedDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss''zzz";
string timeZoneId = "FLE Standard Time";
string dateTimestr = "2017-10-09T09:00:00+02:00";

DateTimeOffset dto = DateTimeOffset.Parse(dateTimeStr);
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
TimeSpan offset = zone.GetUtcOffset(dto);
dto = dto.ToOffset(offset);
string localTime = dto.ToString(ExpectedDateTimePattern);

localTime은 '2017-10-09T10 : 00 : 00 + 03 : 00'을 반환합니다.


OP에 따르면 이것이 정답입니다. 이해해야 할 가장 중요한 것은 timzone에 대한 UtcOffset이 일정하지 않고 일광 절약 규칙 때문에 우리가 말하는 날짜 자체에 의존한다는 것 입니다. 따라서 OP가 수행 한 유일한 실수는 GetUtcOffset (myDate) 대신 상수 BaseUtcOffset을 사용하는 것입니다
g.pickardou
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.