ISO 8601 형식에서 .NET DateTime을 만드는 방법


130

DateTime을 ISO 8601 형식 으로 바꾸는 방법을 찾았 지만 C #에서 반대로하는 방법은 없습니다.

나는 그것을 가지고 2010-08-20T15:00:00Z있고 그것을 DateTime객체 로 바꾸고 싶다 .

나는 끈 부분을 스스로 분리 할 수는 있지만 이미 국제 표준 인 무언가를 위해 많은 일을하는 것처럼 보입니다.



1
@Aidin : 8 월 24 일 10 시 12:02
abatishchev

@Aidin : 그리고 네, 이것은 중복입니다. 형식의 유일한 차이점입니다. 나머지는 동일합니다.
abatishchev

6
@abatishchev, 그리고 그것이 복제본이 아닌 이유입니다. "중복"의 답변은 8601을 처리하지 않습니다.
Spiralis

3
예, 이것은 중복이 아닙니다. 이 질문은 ISO 8601 형식의 구문 분석과 관련이 있습니다.
호세

답변:


142

이 솔루션은 DateTimeStyles 열거 형 을 사용 하며 Z에서도 작동합니다.

DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);

이것은 솔루션을 완벽하게 인쇄합니다.


3
편집 된 솔루션이 DateTime d2= DateTime.Parse("2010-08-20T15:00:00Z", null, DateTimeStyles.RoundtripKind);잘 작동 하는 것 같습니다.
j3ko

4
DateTimeStyles.RoundtripKind? MSDN 설명 에 대해 자세히 알고 싶은 사람 은 비어 있습니다.
Steve Parish

8
이 질문은 더 나은 답변을 반영하기 위해 편집 된 것으로 보이지만 @MamtaD는 원래 답변을 덮어 썼으므로 의견이 매우 오도됩니다. 처음에 나는 위의 주석으로 인해 답변이 정확한지 확신하지 못했지만, 잘못된 답변이 후자가 올바른 것으로 대체되었음을 깨달았습니다.
Aidin

5
소수 자릿수로는 작동하지 않습니다. 2018-06-19T14:56:14.123ZUTC가 아닌 현지 시간으로 구문 분석됩니다. CultureInfo.InvariantCulturenull 대신 사용 합니다.
Erik Hart

1
에 대한 자세한 내용 DateTimeStyles.RoundTripKindstackoverflow.com/q/39572395/2014893
Robert K. Bell

33

MSDN에 따르면 "s"및 "o"형식은 표준을 반영하지만 제한된 하위 집합 만 구문 분석 할 수있는 것으로 보입니다. 문자열에 시간대 지정이 포함 된 경우 특히 문제가됩니다. (기본 ISO8601 형식이나 정밀도가 낮은 형식에는 해당되지 않습니다. 그러나 정확히 그렇지는 않습니다.) ISO8601을 구문 분석 할 때 사용자 지정 형식 문자열을 사용하는 이유입니다. 현재 내가 선호하는 스 니펫은 다음과 같습니다.

static readonly string[] formats = { 
    // Basic formats
    "yyyyMMddTHHmmsszzz",
    "yyyyMMddTHHmmsszz",
    "yyyyMMddTHHmmssZ",
    // Extended formats
    "yyyy-MM-ddTHH:mm:sszzz",
    "yyyy-MM-ddTHH:mm:sszz",
    "yyyy-MM-ddTHH:mm:ssZ",
    // All of the above with reduced accuracy
    "yyyyMMddTHHmmzzz",
    "yyyyMMddTHHmmzz",
    "yyyyMMddTHHmmZ",
    "yyyy-MM-ddTHH:mmzzz",
    "yyyy-MM-ddTHH:mmzz",
    "yyyy-MM-ddTHH:mmZ",
    // Accuracy reduced to hours
    "yyyyMMddTHHzzz",
    "yyyyMMddTHHzz",
    "yyyyMMddTHHZ",
    "yyyy-MM-ddTHHzzz",
    "yyyy-MM-ddTHHzz",
    "yyyy-MM-ddTHHZ"
    };

public static DateTime ParseISO8601String ( string str )
{
    return DateTime.ParseExact ( str, formats, 
        CultureInfo.InvariantCulture, DateTimeStyles.None );
}

TZ-less 문자열을 구문 분석하지 않아도되는 경우 (내가하는) "s"행을 추가하여 적용되는 형식 변경 수를 크게 확장 할 수 있습니다.


3
내가 추가 할 수 "yyyyMMdd"에서 formats이 때때로 RFC 5545 RRULE의 시간을 제공하기 위해 DTSTART에 의존의 경우와 같이, 일 감소 정확성을 배열입니다.
Kyle Falconer

1
를 사용 K하면 다른 시간대 처리를 함께 롤링 할 수 있습니다. 나는 stackoverflow.com/a/31246449/400547 에서 더 광범위한 변형을 가지고 있지만 너무 광범위한 것이면 (유효한 ISO 8601이지만 더 일반적인 프로파일에서는 사용되지 않는 것을 허용) 어떻게 K크기를 줄일 수 있는지 보여줍니다 제삼.
Jon Hanna

20
using System.Globalization;

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00",
    "s",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, out d);

1
LinqPad에서 False 및 d ~~> "1/1/0001 12:00:00 AM"생성 :(
Reb.Cabin

@Reb : "2010-08-20T15 : 00 : 00"및 "s"(끝에 "Z"가없는 경우
abatishchev

수정 됨 :) Z가 모든 샘플에 나타납니다 (다양한 GPS 장치 및 GPX 파일
제공됨

다른 ISO 8601 참조에서 "Z"는 표준 시간대와 마찬가지로 영역을 나타냅니다.
Reb. Cabin

30
Z는 실제로 Zulu 시간 또는 UTC를 나타냅니다. en.wikipedia.org/wiki/ISO_8601#UTC
피터 스티븐스

19

다음은 나를 위해 더 잘 작동하는 것입니다 ( LINQPad 버전).

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00Z",
    @"yyyy-MM-dd\THH:mm:ss\Z",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, 
    out d);
d.ToString()

생산

true
8/20/2010 8:00:00 AM

현재 단위 테스트에서 날짜로 예상되는 모든 문자열이 Iso8601 형식인지 확인하기 위해 이것을 사용합니다. 감사!
anthv123

1
왜 이것이 UTC가 아닌 타임 스탬프를 반환합니까?! "AssumeUniversal"과 함께 "불변 문화"가 전 세계적으로 크게 다르기 때문에이 작업을 수행하지 않아야하므로 최소 놀랍게도 원칙을 크게 위반하면, 코드를 실행하기 시작하면 현지 표준 시간대로 돌아 오면 버그가 발생할 수 있습니다. 설정이 다른 서버에서!
Elaskanator

7

TryParseExact작동 하려면 ISO 문자열 형식과 정확히 일치하는 것이 중요합니다 . 나는 정확한 것이 정확 하고이 대답은 대부분 분명하지만 어쨌든 분명합니다 ...

제 경우에는 아래의 "값"에 따라 약간 다른 입력이 있기 때문에 Reb.Cabin의 답변이 작동하지 않습니다.

값: 2012-08-10T14:00:00.000Z

밀리 초 동안 거기에 약간의 000이 있고 더있을 수 있습니다.

그러나 .fff아래에 표시된 것처럼 형식 에 일부 를 추가하면 모두 정상입니다.

형식 문자열 : @"yyyy-MM-dd\THH:mm:ss.fff\Z"

VS2010 즉시 실행 창에서 :

DateTime.TryParseExact(value,@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture,DateTimeStyles.AssumeUniversal, out d);

진실

당신은 DateTimeStyles.AssumeLocal당신의 시간이 어느 지역인지에 따라 잘 사용해야 할 수도 있습니다 ...


1
이것은 나를 위해 일했지만 나도로 변경 AssumeUniversal해야했습니다 AdjustToUniversal.
Augusto Barreto

4

이것은 LINQPad4에서 잘 작동합니다.

Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00Z"));
Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00"));
Console.WriteLine(DateTime.Parse("2010-08-20 15:00:00"));

-1

DateTime.ParseExact(...) 파서에게 각 문자가 무엇을 나타내는 지 알려줄 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.