문자열을 C#의 DateTime에 구문 분석
날짜와 시간은 다음과 같이 형식이 지정된 문자열로 되어 있습니다.
"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#에서의 String Formating입니다.
내가 나중에 설명하는 것처럼, 나는 항상 그것을 선호할 것입니다.TryParse
그리고.TryParseExact
방법들.사용하기에는 부피가 좀 크기 때문에 구문 분석을 훨씬 쉽게 할 수 있는 확장 방법을 작성했습니다.
var dtStr = "2011-03-21 13:26";
DateTime? dt = dtStr.ToDate("yyyy-MM-dd HH:mm");
또는 현재 문화의 날짜 패턴을 암시적으로 사용하려면 다음과 같이 사용할 수 있습니다.
DateTime? dt = dtStr.ToDate();
그런 경우에는 특정 패턴을 지정할 필요가 없습니다.지정하지 않으면 현재 스레드에 있는 현재 문화의 기본 DateTime 패턴이 사용됩니다.
와는 달리Parse
,ParseExact
등. 예외를 두지 않으며, 다음을 통해 확인할 수 있습니다.
if (dt.HasValue) { // continue processing } else { // do error handling }
변환이 성공했는지 여부(이 경우)dt
다음을 통해 액세스할 수 있는 값이 있습니다.dt.Value
) 또는 없음(이 경우 해당)null
).
그것은 심지어 "엘비스" 운영자처럼 우아한 단축키를 사용할 수 있게 해줍니다.?.
, 예를 들어 다음과 같습니다.
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? <para/>
/// <summary>
/// </summary>
/// <param name="dateTimeStr">The date string to parse</param>
/// <param name="dateFmt">dateFmt is optional and allows to pass
/// a parsing pattern array or one or more patterns passed
/// as string parameters</param>
/// <returns>Parsed DateTime or null</returns>
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();
}
var result = DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture,
style, out var dt) ? dt : null as DateTime?;
return result;
}
}
코드에 대한 몇 가지 정보
내가 왜 이런 걸 썼는지 궁금하실 겁니다.InvariantCulture
부르기TryParseExact
: 이것은 함수가 항상 동일한 방식으로 형식 패턴을 처리하도록 강제하기 위함입니다(예를 들어, "."는 영어로 10진수 구분자로 해석할 수 있지만 그룹 구분자 또는 날짜 구분자는 독일어로 해석할 수 있습니다).우리는 이미 몇 줄 전에 문화 기반 형식 문자열을 조회했으므로 여기서는 괜찮습니다.
업데이트: .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
원하신다면요)
C#의 이전 스타일은 다음과 같은 방식으로 요구했을 것입니다(위의 코드에서 제거했습니다).
// DateTime? result = null;
// DateTime dt;
// if (DateTime.TryParseExact(dateTimeStr, dateFmt,
// CultureInfo.InvariantCulture, style, out dt)) result = dt;
나는 코드를 더 단순화 시켰습니다.params
키워드:이제 당신은 2개의nd 오버로드된 방법이 더 이상 필요 없습니다.
사용 예시
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 strDateArray = new[] { "15-01-2019", "15.01.2021" };
var patterns=new[] { "dd-MM-yyyy", "dd.MM.yyyy" };
var dtRange = strDateArray.Select(s => s.ToDate(patterns));
dtRange.Dump();
패턴을 사용하여 배열의 날짜를 즉시 변환하고 콘솔에 덤프합니다.
TryParseExact에 대한 몇 가지 배경
마지막으로 배경에 대한 몇 가지 의견(즉, 제가 이렇게 쓴 이유)을 소개합니다.
저는 이 확장 방법에서 TryParseExact를 선호합니다. 예외 처리를 피할 수 있기 때문입니다. Eric Lippert의 기사에서 Parse가 아닌 TryParse를 사용해야 하는 예외에3) 대한 기사를 읽을 수 있습니다. 저는 2)이 주제에 대해 그의 말을 인용합니다.
이 유감스러운 설계1) 결정[주석: Parse 메서드가 예외를 허용하도록 하는 것]은 매우 번거로웠기 때문에 프레임워크 팀은 곧 올바른 작업을 수행하는 TryParse를 구현했습니다.
있습니다만.TryParse
그리고.TryParseExact
두 가지 모두 여전히 사용하기에 훨씬 불편합니다.초기화되지 않은 변수를 사용하도록 강제합니다.out
null이 되어서는 안되며 변환하는 동안 부울 리턴 값을 평가해야 합니다 - 를 사용해야 합니다.if
statement를 즉시 사용하거나 반환 값을 추가 부울 변수에 저장해야 나중에 확인할 수 있습니다.그리고 변환이 성공했는지 여부를 모른 채 목표 변수만 사용할 수는 없습니다.
대부분의 경우 변환이 성공했는지 여부(물론 성공한 경우의 값)만 알고 싶을 뿐이므로 전체 정보가 한 곳에 저장되기 때문에 모든 정보를 유지하는 nullable target 변수가 바람직하며 훨씬 더 우아합니다.이는 일관성 있고 사용하기 쉬우며 오류가 발생하기 쉽습니다.
제가 작성한 확장 방법이 바로 그것입니다. (사용하지 않을 경우 매번 어떤 코드를 작성해야 하는지도 보여줍니다.)
나는 그들이 가진 것을 믿습니다..ToDate(strDateFormat)
단순하고 깨끗해 보이기 때문입니다 - 원작처럼 단순합니다.DateTime.Parse
원래는 - 하지만 변환이 성공했는지 확인할 수 있는 기능과 함께 예외를 두지 않습니다.
1) 여기서 의미하는 것은 예외 처리(즉,try { ... } catch(Exception ex) { ...}
block) - 잘못된 문자열을 구문 분석하면 예외가 발생하기 때문에 구문 분석을 사용할 때 필요합니다. 이 경우 불필요할 뿐만 아니라 코드가 성가시고 복잡합니다.트라이파스는 제가 제공한 코드 샘플이 보여주므로 이 모든 것을 피합니다.
2) Eric Lippert는 유명한 StackOverflow 연구원으로 마이크로소프트에서 몇 년 동안 C# 컴파일러 팀의 수석 개발자로 일하고 있었습니다.
3) 안타깝게도 마이크로소프트는 MSDN 사이트에서 이 기사를 삭제했습니다.다른 URL에서 찾으시는 분이 있으면 알려주시면 업데이트 해드리겠습니다.
var dateStr = @"2011-03-21 13:26";
var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm", CultureInfo.CurrentCulture);
다른 형식 문자열은 이 링크를 확인해 보세요!
날짜 시간.구문 분석()은 해당 문자열 형식에 대해 정상적으로 작동해야 합니다.참조:
http://msdn.microsoft.com/en-us/library/1k1skd40.aspx#Y1240
포맷 예외가 발생하는 건가요?
사람이 읽을 수 있는 문자열의 값을 에 넣습니다.다음과 같은 코드가 있는 NET DateTime:
DateTime.ParseExact("April 16, 2011 4:27 pm", "MMMM d, yyyy h:mm tt", null);
XmlConvert를 사용할 수도 있습니다.ToDate 문자열
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
간단하고 직설적인 답 -->
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.
* */
다음 코드를 사용해 보십시오.
Month = Date = DateTime.Now.Month.ToString();
Year = DateTime.Now.Year.ToString();
ViewBag.Today = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(Int32.Parse(Month)) + Year;
날짜 시간.ParseExact(DateTime, Format, DateTimeFormatInfo).불변 정보, DateTimeStyle.선도 허용흰색 | 날짜 시간 스타일.추적 허용흰색)
예를 들어 다음과 같습니다.
날짜 시간.ParseExact("2011-03-21 13:26", "yyyy-MM-dd hh:mm", DateTimeFormatInfo.불변 정보, DateTimeStyle.선도 허용흰색 | 날짜 시간 스타일.추적 허용흰색);
언급URL : https://stackoverflow.com/questions/5366285/parse-string-to-datetime-in-c-sharp
'programing' 카테고리의 다른 글
사용자가 카메라 사용을 허락했는지 확인하는 방법은? (0) | 2023.09.13 |
---|---|
utf8_unicode_ci와 utf8mb4_0900_ai_ci의 차이점은 무엇입니까? (0) | 2023.09.13 |
텍스트 파일 및 콘솔에 오류 및 출력 쓰기 (0) | 2023.09.13 |
Jquery: 요소에 특정 CSS 클래스/스타일이 있는지 확인하는 방법 (0) | 2023.09.13 |
Spring HATEOAS 내장 리소스 지원 (0) | 2023.09.13 |