Program Tip

DateTime.Parse ( "2012-09-30T23 : 00 : 00.0000000Z")는 항상 DateTimeKind.Local로 변환됩니다.

programtip 2020. 12. 15. 19:46
반응형

DateTime.Parse ( "2012-09-30T23 : 00 : 00.0000000Z")는 항상 DateTimeKind.Local로 변환됩니다.


UTC 형식으로 DateTime을 나타내는 문자열을 구문 분석하고 싶습니다.

내 문자열 표현에는 문자열이 UTC 시간을 나타내는 것을 나타내는 Zulu 시간 사양이 포함되어 있습니다.

var myDate = DateTime.Parse("2012-09-30T23:00:00.0000000Z");    

위에서 myDate.Kind가 DateTimeKind.Utc가 될 것으로 예상하고 대신 DatetimeKind.Local입니다.

내가 뭘 잘못하고 UTC 시간을 나타내는 문자열을 구문 분석하는 방법은 무엇입니까?

감사합니다!


저는 제 노다 타임 프로젝트를 개인적으로 사용할 것 입니다. (분명 나는 저자로서 편견이 있지만 더 깨끗할 것입니다 ...)하지만 그렇게 할 수 없다면 ...

어느 사용을 DateTime.ParseExact예상하고 포함 정확한 형식 지정 DateTimeStyles.AssumeUniversalDateTimeStyles.AdjustToUniversal구문 분석 코드를 :

using System;
using System.Globalization;

class Test
{
    static void Main()        
    {
        var date = DateTime.ParseExact("2012-09-30T23:00:00.0000000Z",
                                       "yyyy-MM-dd'T'HH:mm:ss.fffffff'Z'",
                                       CultureInfo.InvariantCulture,
                                       DateTimeStyles.AssumeUniversal |
                                       DateTimeStyles.AdjustToUniversal);
        Console.WriteLine(date);
        Console.WriteLine(date.Kind);
    }
}

(기본적으로 로컬로 조정되는 이유 AdjustToUniversal는 나를 넘어서지 만 신경 쓰지 마십시오 ...)

편집 : Mattytommo의 제안에 대한 이의를 확장하기 위해 정보를 잃을 것임을 증명하는 것을 목표로했습니다. 나는 지금까지 실패했지만 매우 독특한 방식으로 실패했습니다. 유럽 ​​/ 런던 시간대에서 실행되며 2012 년 10 월 28 일 현지 시간으로 오전 2시 (UTC 기준 오전 1시)로 돌아갑니다.

DateTime local1 = DateTime.Parse("2012-10-28T00:30:00.0000000Z");
DateTime local2 = DateTime.Parse("2012-10-28T01:30:00.0000000Z");
Console.WriteLine(local1 == local2); // True

DateTime utc1 = TimeZoneInfo.ConvertTimeToUtc(local1);
DateTime utc2 = TimeZoneInfo.ConvertTimeToUtc(local2);
Console.WriteLine(utc1 == utc2); // False. Hmm.

"DST 포함 또는 제외"플래그가 어딘가에 저장되어 있는 것 같습니다 .하지만 어디 에서 작업 할 수 있으면 날려 버릴 것입니다. TimeZoneInfo.ConvertTimeToUtc상태 문서

경우 dateTime으로는 모호한 시간에 대응하고,이 방법은 소스 시간 영역의 기준 시간임을 가정한다.

변환 할 때 여기 에서는 그렇지 않은 것 같습니다local2 .

편집 : 좋아, 그것은 더 이상해진다-사용중인 프레임 워크의 버전에 따라 다릅니다. 이 프로그램을 고려하십시오.

using System;
using System.Globalization;

class Test
{
    static void Main()        
    {
        DateTime local1 = DateTime.Parse("2012-10-28T00:30:00.0000000Z");
        DateTime local2 = DateTime.Parse("2012-10-28T01:30:00.0000000Z");

        DateTime utc1 = TimeZoneInfo.ConvertTimeToUtc(local1);
        DateTime utc2 = TimeZoneInfo.ConvertTimeToUtc(local2);
        Console.WriteLine(utc1);
        Console.WriteLine(utc2);

        DateTime utc3 = local1.ToUniversalTime();
        DateTime utc4 = local2.ToUniversalTime();
        Console.WriteLine(utc3);
        Console.WriteLine(utc4);
    }
}

따라서 두 가지 다른 UTC 값을 가져 와서로 파싱 DateTime.Parse한 다음 두 가지 다른 방법으로 다시 UTC로 변환합니다.

.NET 3.5에서의 결과 :

28/10/2012 01:30:00 // Look - we've lost information
28/10/2012 01:30:00
28/10/2012 00:30:00 // But ToUniversalTime() seems okay...
28/10/2012 01:30:00

.NET 4.5 베타 결과 :

28/10/2012 00:30:00 // It's okay!
28/10/2012 01:30:00
28/10/2012 00:30:00
28/10/2012 01:30:00

평소와 같이 Jon의 대답은 매우 포괄적입니다. 즉, 아직 아무도 언급하지 않았습니다 DateTimeStyles.RoundtripKind. DateTime을 문자열로 변환하고 동일한 DateTime으로 다시 변환하려면 ( DateTime.Kind설정 유지 포함 ) DateTimeStyles.RoundtripKind플래그를 사용합니다 .

As Jon said, the correct thing to do is to use the "O" formatter when converting a DateTime object to a string. This preserves both the precision and timezone information. Again, as Jon said, use DateTime.ParseExact when converting back. But if you use DateTimeStyles.RoundtripKind, you always get back what you put in:

var now = DateTime.UtcNow;
var strNow = now.ToString("O");
var newNow = DateTime.ParseExact(strNow, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);

In the above code, newNow is a exact same time as now, including the fact that it is UTC. If run the same code except substitute DateTime.Now for DateTime.UtcNow, you'll get an exact copy of now back as newNow, but this time as a local time.

For my purposes, this was the right thing since I wanted to make that sure that whatever was passed in and converted is converted back to the exact same thing.


Use the TimeZoneInfo class using the following:

var myDate = TimeZoneInfo.ConvertTimeToUtc(DateTime.Parse("2012-09-30T23:00:00.0000000Z"));

You can use the following format for parser method: yyyy-MM-ddTHH:mm:ss.ffffffK

This shall properly process time zone information at the end (starting from .NET 2.0).

RE: ISO 8601


Ran into a similar issue before and several hours (and pulled hairs) later ended up using DateTime.SpecifyKind:

DateTime.SpecifyKind(inputDate, DateTimeKind.Utc);

I believe someone also eluded to this in a comment above as well.

ReferenceURL : https://stackoverflow.com/questions/10029099/datetime-parse2012-09-30t230000-0000000z-always-converts-to-datetimekind-l

반응형