Строка parse для DateTime в C #

У меня есть дата и время в строке, отформатированной так:

"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 в случае, если дата отсутствует в ожидаемом формате)

Обязательно проверяйте строки пользовательских строк даты и времени при построении строки формата, особенно обратите внимание на количество букв и фраз (т.е. «ММ» и «мм» означают совсем другие вещи).

Другим полезным ресурсом для строк формата C # является форматирование строк в C #

Как я объясняю позже, я всегда TryParseExact методы TryParse и TryParseExact . Поскольку они немного громоздки для использования, я написал метод расширения, который упрощает parsing партитуры:

 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 вы можете получить через dt.Value ) или нет (в этом случае оно равно null ).

Это даже позволяет использовать элегантные ярлыки, такие как «Элвис» -оператор » ?. , например:

 int? year = dtStr?.toDate("yyyy-MM-dd HH:mm")?.Year; 

Здесь вы также можете использовать year.HasValue чтобы проверить, удалось ли преобразование, и если оно не получилось, то year будет содержать null , иначе – годовую часть даты. Если конверсия не удалась, не возникает никакого исключения.

Попробуйте в .NetFiddle

 public static class Extensions { public static DateTime? toDate(this string dateTimeStr, 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"}); const DateTimeStyles style = DateTimeStyles.AllowWhiteSpaces; if (dateFmt == null) { var dateInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat; dateFmt=dateInfo.GetAllDateTimePatterns(); } DateTime? result = null; DateTime dt; if (DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture, style, out dt)) result = dt; return result; } public static DateTime? toDate(this string dateTimeStr, string dateFmt=null) { // example: var dt="2011-03-21 13:26".toDate("yyyy-MM-dd HH:mm"); // or simply var dt="2011-03-21 13:26".toDate(); // call overloaded function with string array param string[] dateFmtArr = dateFmt == null ? null : new string[] { dateFmt }; return toDate(dateTimeStr, dateFmtArr); } } 

Обновление: .toDate() (без параметров) теперь по умолчанию используется для всех общих шаблонов даты / времени текущей культуры streamа.
Заметим, что нам нужен result и dt вместе, потому что TryParseExact не позволяет использовать DateTime? , которые мы намерены вернуть. В C # Version 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; 

(Также было бы возможно записать out DateTime dt вместо out var dt .)

Пример:

 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 чтобы вы точно знали, была ли принята правильная строка даты / времени или нет.


NB Перегруженная функция позволяет передавать массив допустимых форматов, используемых для парсинга / преобразования дат, как показано здесь ( 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); 

Однако, чтобы сохранить код коротким, я использую только перегрузку массива TryParseExact, потому что он не работает с параметром Generic.

Расширенный пример:
Вы можете использовать оператора по умолчанию в безопасном формате, например

 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" в качестве резервной копии. Таким образом, функция расширения позволяет легко «сгруппировать» различные резервные форматы.


Наконец, вот некоторые комментарии к фону (то есть причина, по которой я написал это так):

Я предпочитаю TryParseExact в этом методе расширения, потому что вы избегаете обработки исключений – вы можете прочитать в статье Эрика Липперта об исключениях, почему вы должны использовать TryParse, а не Parse, я цитирую его по этой теме: 2)

Это неудачное дизайнерское решение 1) [аннотация: чтобы метод Parse выбрал исключение] настолько огорчился, что, конечно, команда разработчиков реализовала TryParse вскоре после этого, что делает правильные вещи.

Это действительно так, но TryParse и TryParseExact все еще намного меньше, чем удобно использовать: они заставляют вас использовать неинициализированную переменную как параметр out который не должен быть нулевым, а при преобразовании вам нужно оценить возвращаемое значение boolean – либо вам нужно немедленно использовать оператор if либо вам нужно сохранить возвращаемое значение в дополнительной логической переменной, чтобы вы могли выполнить проверку позже. И вы не можете просто использовать целевую переменную, не зная, было ли преобразование успешным или нет.

В большинстве случаев вам просто нужно знать, было ли преобразование успешным или нет (и, конечно, значение, если оно было успешным) , поэтому нулевая целевая переменная, которая сохраняет всю информацию, была бы желательной и намного более элегантной, поскольку вся информация просто хранится в одном месте: это непротиворечиво и просто в использовании, а тем более подвержено ошибкам.

Метод расширения, который я написал, делает именно это (он также показывает вам, какой код вам придется писать каждый раз, если вы не собираетесь его использовать).

Я считаю, что преимущество .toDate(strDateFormat) том, что оно выглядит просто и чисто – так же просто, как и исходное DateTime.Parse должно было быть, – но с возможностью проверить, было ли преобразование успешным и не выбрасывало исключения.


1) Здесь имеется в виду, что обработка исключений (т. Е. try { ... } catch(Exception ex) { ...} block) – что необходимо, когда вы используете Parse, потому что он будет генерировать исключение, если недействительный строка анализируется – в данном случае это не только необязательно, но и раздражает и усложняет ваш код. TryParse избегает всего этого, как показывает пример кода, который я предоставил.


2) Эрик Липперт является известным сотрудником StackOverflow и уже несколько лет работает в Microsoft в качестве основного разработчика в команде компилятора C #.

 var dateStr = @"2011-03-21 13:26"; var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm", CultureInfo.CurrentCulture); 

Проверьте эту ссылку для других строк формата!

DateTime.Parse () должен отлично работать для этого формата строки. Справка:

http://msdn.microsoft.com/en-us/library/1k1skd40.aspx#Y1240

Это бросает для вас исключение FormatException?

Поместите значение удобочитаемой строки в .NET DateTime с таким кодом:

 DateTime.ParseExact("April 16, 2011 4:27 pm", "MMMM d, yyyy h:mm tt", null); 

Вы также можете использовать 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); 

Подробнее о различных параметрах parsingа. 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. * */ 
  • Является ли строка типом значения или ссылочным типом?
  • Как инициализировать список строк C # (List ) со многими строковыми значениями
  • Используя оператор равенства == для сравнения двух строк для равенства в C
  • Разница между char * str = "STRING" и char str = "STRING"?
  • Как отсортировать массив объектов в Java?
  • Разделить строку на массив строк на основе разделителя
  • Конкатенация строк без оператора «+»
  • Сортировка по строке, которая может содержать число
  • Как проверить, начинается ли строка с другой строки в C?
  • Как конкатенировать строки в шаблонах django?
  • Разница между типами string и char в C ++
  • Давайте будем гением компьютера.