2011-03-01 4 views
14

검색 구문의 일부로 자유 형식의 날짜를 사용하고 있습니다. 문자열에서 날짜를 파싱해야하지만 실제로 지정된 날짜 부분 만 보존합니다. 예를 들어, "2010 년 11 월 1 일"은 특정 날짜이지만 "2010 년 11 월"은 "2010 년 11 월 1 일"에서 2010 년 11 월 30 일까지의 날짜 범위입니다.모든 값을 지정하지 않은 날짜의 구문 분석

불행하게도, DateTime.Parse과 친구 같은 DateTime에이 날짜를 구문 분석 :

DateTime.Parse("November 1, 2010") // == {11/1/2010 12:00:00 AM} 
DateTime.Parse("November, 2010") // == {11/1/2010 12:00:00 AM} 

은 내가 DateTime의 일부가 실제로 구문 분석하고있는 파서 추측 된 알 필요가있다. 본질적으로, 나는 DateTime.Parse("November, 2010") == {11/-1/2010 -1:-1:-1}이 필요하다; 그 다음 날 부분이 누락되어 전체 달을 다루는 날짜 범위를 계산할 수 있습니다.

(내부적으로 C#은 날짜를 구문 분석하고 필요한 정보를 보존하는 DateTimeParseDateTimeResult 클래스를 가지고 있지만 공개 인터페이스에 날짜가 되돌아 와서 제거되었습니다. 차라리 반영하지 않을 것입니다. 이 클래스들은 실제로 유일한 경로가 아니면 제외합니다.) DateTime.Parse은 어떤 형식으로 날짜를 구문 분석했는지 알 수있는 방법이 있습니까? 또는 반환 된 DateTime에는 지정되지 않은 부품에 대한 자리 표시자가 있습니까? 나는 또 다른 날짜 파서를 사용하는 것에 대해 개방적이지만, 내부 파서만큼 신뢰할 수 있고 로케일 유연성이 좋기를 바랍니다. 미리 감사드립니다.

편집 : 나는 또한 ParseExact을 시도했지만 Parse이 처리 할 수있는 모든 형식을 열거하는 것은 거의 불가능한 것처럼 보입니다. 실제로 ParseDateTimeFormatInfo.GetAllDateTimePatterns에 의해 반환되는 것보다 많은 형식을 허용합니다.이 형식은 제가 알 수있는 정식 소스와 같습니다.

답변

2

TryParseExact()를 사용해 볼 수 있습니다. TryParseExact()는 데이터 문자열이 지정된 형식이 아닌 경우 실패합니다. 다양한 조합을 시도해 보면 성공하면 날짜가 들어있는 형식을 알 수 있으므로 파서가 기본값으로 채운 날짜 부분을 알 수 있습니다. 단점은 사용자가 날짜를 입력하는 방법을 예상해야하므로 정확히 예상 할 수 있습니다.

또한 Regex를 사용하여 날짜 문자열을 직접 소화 할 수도 있습니다. 다시 말하지만, 당신은 다른 정규 표현식 (또는 정말로 복잡한 단일 표현식)을 필요로 할 것이다. 그러나 문자열을 이런 식으로 분리하는 것은 가능하다. 그러면 당신은 당신이 실제로 가지고있는 것을 압니다.

+0

위의 편집을 참조하십시오. ParseExact는 일반 날짜 구문 분석에는 불충분 한 것으로 보입니다. – kevingessner

0

는 기본적으로, 나는 DateTime.Parse ("2010 년 11 월을")가 필요 == {11/-1/2,010 -1 : -1 : -1}; 그런 다음 일 부분이 누락 된 것을 볼 수 있으며 은 전체 월 을 다루는 날짜 범위를 계산합니다.

부정적인 시간/초/분/일 값을 가질 수 없기 때문에 원하는 것은 잘못된 DateTime입니다. 합법적 인 DateTime 이외의 다른 것을 반환하려면 DateTime을 반환하지 않는 고유 한 메서드를 작성해야합니다.

DateTime.Parse이 날짜를 구문 분석하는 데 사용하는 형식 말해 갈 수있는 몇 가지 방법이 있나요? 또는 반환 된 DateTime에 지정되지 않은 부분에 대한 자리 표시 자 이 있습니까?또한 다른 날짜 구문 분석기를 사용하여 을 열어두고 있지만 은 신뢰할 수 있고 내부 용으로는 로켈 - 유연성이 좋습니다.

당신은 수동으로이 작업을 수행하는 입력 내용을 추적하기 위해서해야 할 것 여기에 좀 http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx

을 가져 가라. 유일한 해결책은 입력이 올바른 형식인지 확인하는 것입니다.

+3

-1 지정자는 '필자가 추측 한 DateTime의 조각을 문자 그대로 나타내는 신호가있는 메서드가 필요하다는 것'이라고 생각합니다. 문자 그대로 -1이라는 값을 가진 DateTime을 원했을뿐입니다. –

+1

Michael Pryor가 정확합니다. -1은 지정되지 않은 부분의 자리 표시 자라고 -1을 의미했습니다. – kevingessner

2

Parse"January/2010 - 21 12: 00 :2"과 같이 정상적인 사람이 입력하지 않는 많은 내용을 파싱합니다. 필자는 사용자가 정확히 무엇을 입력했는지 알고 싶으면 자신 만의 날짜 파서를 작성해야한다고 생각합니다.

KeithS가 제안한 것처럼 필자는 개인적으로 다음과 같이 제안했습니다. Parse으로 문자열을 구문 분석하고 DateTime 개체의 필드 중 하나에 0이 있으면 자신의 구문 분석 함수 만 호출하십시오. 확인해야 할 가능성이 없습니다. 왜냐하면 하루가 0이면 시간도 0이 될 것이기 때문입니다. 따라서 년, 월, 일 등을 확인하십시오.

또는 사용자가 인식 할 수있는 특정 형식을 사용하기 만하면됩니다.

나는 일 올해의 존재를 확인하기 위해 원래의 문자열로 돌아갑니다이 방법을 사용
+1

"구문 분석을 사용하여 문자열을 구문 분석하고 DateTime 개체의 필드 중 하나에 0이 있으면 자신의 구문 분석 함수 만 호출하십시오." - 안타깝게도 DateTime의 날짜 부분은 0이 될 수 없습니다. 지정되지 않은 경우 1로 설정되며 1로 지정되는 것과 구분할 수 없습니다. – kevingessner

0

: 를 들어

  • 는, 원래의 문자열이 경우 정수 1을 포함해야 하루가 지정되었습니다. 따라서 문자열을 분리하고 1을 찾으십시오. 월이 1 월 (# 1 개월) 인 경우 유일한 예외가 발생하므로 원래 문자열에서 2 개의 1 또는 1과 "1 월"또는 "1 월"을 확인해야합니다.
  • 의 경우 원래 문자열에 연도 (예 : 1900-2100)가 될 수있는 숫자가 포함되어야합니다. 다른 가능성으로는 아포스트로피를 사용하거나 02-10-16 같은 것을 사용할 수 있습니다. 정확히 세 개의 숫자가 있다는 사실을 인식 할 수 있습니다.

이 방법은 꽤 경험적이지만, 대부분의 경우 작동하는 빠르고 간단한 솔루션입니다. 이 알고리즘을 sharp-datefinder 라이브러리의 DateFinder.DayExists()DateFinder.YearExists() 메서드의 C#으로 코딩했습니다.

관련 문제