zzz가있는 C # DateTime.ToString이 dotnet 프레임 워크에서 중단되지만 dotnet 코어에서는 중단됨

Nov 25 2020

글을 쓰는 시간은 GMT +01 : 00으로 현지 시간입니다. 다음과 같은 방식으로 ToString을 수행 할 때 예기치 않은 일이 발생합니다. 여기 있습니다 :

+01 : 00 시간대로 로컬 시스템 설정 시연 (모두 녹색으로 표시됨) :

var myLocalDate = new DateTime(2020, 11, 25, 08, 00, 00, DateTimeKind.Local);
Assert.AreEqual("2020-11-25T08:00:00+01:00", myLocalDate.ToString(@"yyyy-MM-dd\THH:mm:sszzz"));
Assert.AreEqual(DateTimeKind.Local, myLocalDate.Kind);
Assert.AreEqual(myLocalDate, myLocalDate.ToLocalTime());

이제 수동으로 한 시간을 빼고 "utc"를 종류로 지정하여 utc에서 동일한 시간을 만듭니다. 하지만 ToString을 호출하면 시간대가 +00 : 00으로 예상되는 +01 : 00으로 작성됩니다.

var myUtcDate = new DateTime(2020, 11, 25, 07, 00, 00, DateTimeKind.Utc);
// THIS Breaks:
Assert.AreEqual("2020-11-25T07:00:00+00:00", myUtcDate.ToString(@"yyyy-MM-dd\THH:mm:sszzz"));

에러 메시지:

메시지 : Assert.AreEqual이 실패했습니다. 예상 : <2020-11-25T07 : 00 : 00 + 00 : 00>. 실제 : <2020-11-25T07 : 00 : 00 + 01 : 00>.

여기서 날짜 시간과 형식에 대해 놓친 것이 있습니까, 아니면 알려진 버그 일 수 있습니까?

.Net Framework 4.8을 실행합니다.

이 게시물은 동일한 문제에 대한 것입니다. DateTimeInvalidLocalFormat 오류를 해결하는 방법 : "UTC DateTime이 현지 시간에만 올바른 형식의 텍스트로 변환되고 있습니다."?

최신 정보:

다음 프로그램을 실행하면 dotnet 프레임 워크와 dotnet 코어 (evk에서 언급 한대로)에서 다른 결과가 생성됩니다.

Console.WriteLine(new DateTime(2025, 11, 25, 07, 00, 00, DateTimeKind.Utc).ToString(@"yyyy-MM-dd\THH:mm:sszzz"));

dotnet 코어 인쇄 :

2020-11-25T07 : 00 : 00 + 00 : 00

dotnet 프레임 워크는 다음을 인쇄합니다.

2020-11-25T07 : 00 : 00 + 01 : 00

또한 디버그 모드에서 dotnet 프레임 워크를 실행할 때 다음 디버그 도우미 메시지가 표시되지만 DateTime.ToString ()에서 내부적으로 무시됩니다.

Managed Debugging Assistant 'DateTimeInvalidLocalFormat': 'UTC DateTime이 현지 시간에만 올바른 형식의 텍스트로 변환되고 있습니다. 이는 출력에 현지 표준 시간대 오프셋을 포함하는 'z'형식 지정자를 사용하여 DateTime.ToString을 호출 할 때 발생할 수 있습니다. 이 경우 UTC 시간을 지정하는 'Z'형식 지정자를 사용하거나 텍스트에서 DateTime을 유지하는 데 권장되는 방법 인 'o'형식 문자열을 사용하십시오. XmlConvert 또는 DataSet에서 serialize 할 DateTime을 전달할 때도 발생할 수 있습니다. XmlConvert.ToString을 사용하는 경우 XmlDateTimeSerializationMode.RoundtripKind를 전달하여 올바르게 직렬화합니다. DataSet을 사용하는 경우 DataColumn 개체의 DateTimeMode를 DataSetDateTime.Utc로 설정합니다. '

답변

5 JonSkeet Nov 25 2020 at 19:09

아니요, 문서화 된대로 작동합니다. 형식 지정자 (강조 내) 의 문서에서zzz :

으로 DateTime값은 "ZZZ"사용자 지정 형식 지정자는이 시간과 분 단위로 측정 UTC에서 로컬 운영 체제의 시간대의 오프셋 (offset) 서명 나타냅니다. 인스턴스의 DateTime.Kind속성 값을 반영하지 않습니다 . 이러한 이유로 "zzz"형식 지정자는 DateTime값 에 사용하지 않는 것이 좋습니다 .

틀림없이 그것은 불행한 일이지만 버그는 아닙니다.

.NET Core (및 .NET 5.0)는 분명히 문서화 된대로 작동 하지 않습니다 . .NET Core에서 "수정"되었다고 주장 할 수 있지만 문서화되지 않은 방식으로 동작하는 것은 그 자체로 버그이며 예상보다 코드 마이그레이션을 더 어렵게 만들 수있는 버그라고 제안합니다.

난 당신이 문서의 권고에 따라, 그리고 사용하지 않는 것이 좋습니다 zzz으로 DateTime값. 나는 또한 내 Noda Time 라이브러리를 대신 사용하는 것이 좋습니다 . 여기서 값이 "현지 일 수도 있고 UTC 일 수도 있습니다"라는 점에서 모호하지 않지만 이는 약간 다른 문제입니다. (Noda Time을 사용하여이 문제가 발생할 것으로 예상하지 않으며 다른 날짜 / 시간 코드가 더 명확 해지기를 바랍니다.)