Строка parse для DateTime в C #
У меня есть дата и время в строке, отформатированной так:
"2011-03-21 13:26" //year-month-day hour:minute
Как я могу разобрать его на System.DateTime
?
Я хочу использовать функции, такие как DateTime.Parse()
или DateTime.ParseExact()
если это возможно, чтобы указать формат даты вручную.
- char pointer запутанный с cout в c ++
- форматирование строки в формате валюты в отчете jasper
- Преобразовать строку в тип C #
- Лучший способ конкатенации списка объектов String?
- В bash, как я могу проверить, начинается ли строка с некоторого значения?
- Почему строки неизменны во многих языках программирования?
- Как преобразовать имена переименований в строку в c
- Как преобразовать строку в массив char в C ++?
- Сравнение строки с пустой строкой (Java)
- Преобразование списка > в список
- Использование в списке не обновляет значения модели
- Что возвращает sizeof (& array)?
- Показывать номер строки в обработке исключений
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. * */