다음 과 같은 형식의 문자열에 날짜와 시간 이 있습니다 .
"2011-03-21 13:26" //year-month-day hour:minute
어떻게 파싱 할 수 System.DateTime
있습니까?
날짜 형식을 수동으로 지정할 수 있도록 DateTime.Parse()
또는 DateTime.ParseExact()
가능한 경우 와 같은 기능을 사용하고 싶습니다 .
다음 과 같은 형식의 문자열에 날짜와 시간 이 있습니다 .
"2011-03-21 13:26" //year-month-day hour:minute
어떻게 파싱 할 수 System.DateTime
있습니까?
날짜 형식을 수동으로 지정할 수 있도록 DateTime.Parse()
또는 DateTime.ParseExact()
가능한 경우 와 같은 기능을 사용하고 싶습니다 .
답변:
DateTime.Parse()
주어진 날짜의 형식을 알아 내려고 시도하면 일반적으로 잘 작동합니다. 날짜가 항상 주어진 형식으로 보장 될 수 있다면 다음을 사용할 수 있습니다 ParseExact()
.
string s = "2011-03-21 13:26";
DateTime dt =
DateTime.ParseExact(s, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
(하지만 날짜가 예상 형식이 아닌 경우 일반적으로 TryParse 메서드 중 하나를 사용하는 것이 더 안전합니다)
사용자 정의 날짜 및 시간 형식 문자열 을 확인하십시오 을 구성 할 때 . 특히 문자 수와 대소 문자에주의하십시오 (예 : "MM"과 "mm"은 매우 다른 의미).
C # 형식 문자열에 유용한 또 다른 리소스는 C #의 문자열 형식입니다.
s
. 따라서 TryParseExcact 를 사용하는 것이 좋습니다 . 아래 답변에서 이유를 지적했습니다.
나중에 설명 할 때 항상 TryParse
and TryParseExact
메소드를 선호합니다 . 그것들은 사용하기에 부피가 크므로 구문 분석을 훨씬 쉽게 하는 확장 방법 을 작성했습니다 .
var dtStr = "2011-03-21 13:26";
DateTime? dt = dtStr.ToDate("yyyy-MM-dd HH:mm");
달리 Parse
, ParseExact
등은 예외를 던져, 당신은을 통해 확인할 수 있습니다하지 않습니다
if (dt.HasValue) { // continue processing } else { // do error handling }
변환 (이 경우 성공 여부를 dt
당신이를 통해 액세스 할 수있는 값을 가지고 dt.Value
) 또는하지 (이 경우,이다 null
).
"Elvis"연산자와 같은 고급 바로 가기를 사용할 수도 있습니다. ?.
.
int? year = dtStr?.ToDate("yyyy-MM-dd HH:mm")?.Year;
여기 year.HasValue
에서 전환이 성공했는지 확인하고, 성공하지 못한 경우 year
에는을 포함하고 null
, 그렇지 않으면 날짜의 연도 부분을 포함 할 수도 있습니다. 변환에 실패한 경우 예외가 발생하지 않습니다.
솔루션 : .ToDate () 확장 메소드
public static class Extensions
{
// Extension method parsing a date string to a DateTime?
// dateFmt is optional and allows to pass a parsing pattern array
// or one or more patterns passed as string parameters
public static DateTime? ToDate(this string dateTimeStr, params string[] dateFmt)
{
// example: var dt = "2011-03-21 13:26".ToDate(new string[]{"yyyy-MM-dd HH:mm",
// "M/d/yyyy h:mm:ss tt"});
// or simpler:
// var dt = "2011-03-21 13:26".ToDate("yyyy-MM-dd HH:mm", "M/d/yyyy h:mm:ss tt");
const DateTimeStyles style = DateTimeStyles.AllowWhiteSpaces;
if (dateFmt == null)
{
var dateInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat;
dateFmt=dateInfo.GetAllDateTimePatterns();
}
// Commented out below because it can be done shorter as shown below.
// For older C# versions (older than C#7) you need it like that:
// DateTime? result = null;
// DateTime dt;
// if (DateTime.TryParseExact(dateTimeStr, dateFmt,
// CultureInfo.InvariantCulture, style, out dt)) result = dt;
// In C#7 and above, we can simply write:
var result = DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture,
style, out var dt) ? dt : null as DateTime?;
return result;
}
}
코드에 대한 일부 정보
왜 내가 사용했는지 궁금 할 것입니다. InvariantCulture
전화 TryParseExact
: 이것은 (예를 들어, 그렇지 않으면 항상 치료 형식 패턴 같은 방식으로 기능을 강제로 영어에서 소수 구분 기호로 해석 될 수는 그룹 분리하는 동안 "." 또는 날짜 분리기 독일 사람). 문화 기반 형식 문자열을 몇 줄 전에 이미 쿼리 했으므로 여기서는 괜찮습니다.
업데이트 : .ToDate()
(매개 변수없이) 이제 스레드의 현재 문화권에 대한 모든 공통 날짜 / 시간 패턴이 기본값으로 설정됩니다.
주 우리가 필요로 result
하고 dt
있기 때문에, 서로를 TryParseExact
사용하는 것을 허용하지 않습니다 DateTime?
우리가 돌아갈 계획. 에서 C # 버전 7 당신은을 단순화 할 수ToDate
다음과 같이 함수를 약간 있습니다.
// in C#7 only: "DateTime dt;" - no longer required, declare implicitly
if (DateTime.TryParseExact(dateTimeStr, dateFmt,
CultureInfo.InvariantCulture, style, out var dt)) result = dt;
또는 더 짧은 것을 원한다면 :
// in C#7 only: Declaration of result as a "one-liner" ;-)
var result = DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture,
style, out var dt) ? dt : null as DateTime?;
이 경우 당신은 두 개의 선언이 필요하지 않습니다 DateTime? result = null;
와 DateTime dt;
전혀를 - 당신이 한 줄의 코드에서 그것을 할 수 있습니다. (또한 쓸 수 있습니다out DateTime dt
out var dt
원하는 경우 대신 ).
params
키워드 를 사용하여 코드를 더 단순화했습니다 . 이제 두 번째 가 필요하지 않습니다. 오버로드 된 메소드가 더 이상 .
사용 예
var dtStr="2011-03-21 13:26";
var dt=dtStr.ToDate("yyyy-MM-dd HH:mm");
if (dt.HasValue)
{
Console.WriteLine("Successful!");
// ... dt.Value now contains the converted DateTime ...
}
else
{
Console.WriteLine("Invalid date format!");
}
보시다시피이 예제 dt.HasValue
는 변환이 성공했는지 여부를 쿼리 하기 만합니다 . 추가 보너스로 TryParseExact를 사용하면 엄격한 DateTimeStyles
날짜 를 지정할 수 있으므로 올바른 날짜 / 시간 문자열이 전달되었는지 여부를 정확하게 알 수 있습니다.
더 많은 사용 예
오버로드 된 함수를 사용하면 여기에 표시된 대로 날짜를 구문 분석 / 변환하는 데 사용되는 유효한 형식 의 배열 을 전달할 수 있습니다 ( 예 : 직접 지원).TryParseExact
string[] dateFmt = {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt",
"MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss",
"M/d/yyyy hh:mm tt", "M/d/yyyy hh tt",
"M/d/yyyy h:mm", "M/d/yyyy h:mm",
"MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
var dtStr="5/1/2009 6:32 PM";
var dt=dtStr.ToDate(dateFmt);
템플릿 패턴이 적은 경우 다음과 같이 쓸 수도 있습니다.
var dateStr = "2011-03-21 13:26";
var dt = dateStr.ToDate("yyyy-MM-dd HH:mm", "M/d/yyyy h:mm:ss tt");
고급 예
??
연산자를 사용하여 기본적으로 오류 방지 형식을 사용할 수 있습니다.
var dtStr = "2017-12-30 11:37:00";
var dt = (dtStr.ToDate()) ?? dtStr.ToDate("yyyy-MM-dd HH:mm:ss");
이 경우 .ToDate()
일반적인 현지 문화 날짜 형식을 사용하고,이 모든 것이 실패하면 ISO 표준 형식 을 사용하려고 합니다."yyyy-MM-dd HH:mm:ss"
을 대체로 합니다. 이런 식으로 확장 기능을 사용하면 다양한 대체 형식을 쉽게 "체인"할 수 있습니다.
LINQ에서 확장을 사용할 수도 있습니다.이 기능을 사용해보십시오 (위의 .NetFiddle에 있음).
var patterns=new[] { "dd-MM-yyyy", "dd.MM.yyyy" };
(new[] { "15-01-2019", "15.01.2019" }).Select(s => s.ToDate(patterns)).Dump();
패턴을 사용하여 즉시 배열의 날짜를 변환하고 콘솔에 덤프합니다.
TryParseExact에 대한 배경
마지막으로, 배경에 대한 의견이 있습니다 (즉, 내가 이런 식으로 쓴 이유).
내가 선호하고 TryParseExact을 당신이 있기 때문에,이 확장 방법에 예외 처리를 방지 작업을 수행 할 수 있습니다 - 예외에 대한 에릭 Lippert의의 기사에서 읽기 : 당신이 아니라 구문 분석에 비해 TryParse를 사용해야하는 이유, 내가 그 주제에 대해 그를 인용 ) (2)
이 불행한 디자인 결정은 1) [주석 : Parse 메소드가 예외를 던지게하는 것]은 물론 프레임 워크 팀이 TryParse를 곧바로 구현 한 것이 당연한 일이었습니다.
그것은하지만 TryParse
, TryParseExact
둘 다 사용하기보다 훨씬 적습니다. 초기화되지 않은 변수를 out
매개 변수로 사용하여 nullable해서는 안되며 변환하는 동안 부울 반환 값을 평가해야합니다. 사용하기 위해if
즉시 문을하거나 나중에 확인을 할 수있어 있도록 추가 부울 변수에 반환 값을 저장해야합니다. 변환이 성공했는지 여부를 알지 못하면 대상 변수를 사용할 수 없습니다.
대부분의 경우 변환이 성공했는지 여부와 성공한 경우 값 을 알고 싶기 때문에 nullable 대상 변수 모든 정보를 유지 는 전체 정보가 바람직하기 때문에 바람직하고 훨씬 우아합니다. 한곳에 저장 : 일관성 있고 사용하기 쉬우 며 오류가 발생하기 쉽습니다.
내가 작성한 확장 방법은 정확히 수행합니다 (사용하지 않을 때마다 작성해야 할 코드 종류도 보여줍니다).
나는 .ToDate(strDateFormat)
그것이 원본처럼 간단하고 깨끗하게 보이지만 DateTime.Parse
변환이 성공했는지 여부를 확인하고 예외를 던지지 않고 확인할 수 있는 장점이 있다고 생각합니다 .
1) 여기서 의미 하는 것은 잘못된 문자열이 구문 분석되면 예외를 throw하기 때문에 구문 분석을 사용할 때 필요한 예외 처리 (예 : try { ... } catch(Exception ex) { ...}
블록)는이 경우 불필요 할뿐만 아니라 성가신 것입니다. 코드를 복잡하게 만듭니다. TryParse는 내가 제공 한 코드 샘플이 보여주는 것처럼이 모든 것을 피합니다.
2) Eric Lippert는 유명한 StackOverflow 동료 이며 Microsoft에서 C # 컴파일러 팀의 주요 개발자로 2 년 동안 근무했습니다.
DateTime.Parse ()는 해당 문자열 형식에 적합합니다. 참고:
http://msdn.microsoft.com/en-us/library/1k1skd40.aspx#Y1240
그것은 당신을 위해 FormatException을 던지고 있습니까?
간단하고 간단한 답변->
using System;
namespace DemoApp.App
{
public class TestClassDate
{
public static DateTime GetDate(string string_date)
{
DateTime dateValue;
if (DateTime.TryParse(string_date, out dateValue))
Console.WriteLine("Converted '{0}' to {1}.", string_date, dateValue);
else
Console.WriteLine("Unable to convert '{0}' to a date.", string_date);
return dateValue;
}
public static void Main()
{
string inString = "05/01/2009 06:32:00";
GetDate(inString);
}
}
}
/**
* Output:
* Converted '05/01/2009 06:32:00' to 5/1/2009 6:32:00 AM.
* */
XmlConvert.ToDateString을 사용할 수도 있습니다.
var dateStr = "2011-03-21 13:26";
var parsedDate = XmlConvert.ToDateTime(dateStr, "yyyy-MM-dd hh:mm");
날짜 종류를 지정하는 것이 좋습니다. 코드는 다음과 같습니다.
var anotherParsedDate = DateTime.ParseExact(dateStr, "yyyy-MM-dd hh:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
다양한 구문 분석 옵션에 대한 자세한 내용 http://amir-shenodua.blogspot.ie/2017/06/datetime-parsing-in-net.html