DateTime.TryParse проблема с датами в формате гггг-дд-мм

У меня есть следующая дата в формате строки "2011-29-01 12:00 утра" . Сейчас я пытаюсь преобразовать это в формат datetime с помощью следующего кода:

DateTime.TryParse(dateTime, out dt); 

Но я всегда получаю dt как {1/1/0001 12:00:00 AM}. Скажите, пожалуйста, почему? и как я могу преобразовать эту строку в дату.

РЕДАКТИРОВАТЬ: я только что видел, как все упоминали использовать аргумент формата Сейчас я упомяну, что я не могу использовать параметр формата, поскольку у меня есть некоторые настройки для выбора пользовательского формата даты, который хочет пользователь, и на основе этого пользователь может автоматически получать дату в текстовом поле в этом формате через jQuery datepicker.

7 ответов

Решение

Это должно работать на основе вашего примера "2011-29-01 12:00 утра"

DateTime dt;
DateTime.TryParseExact(dateTime, 
                       "yyyy-dd-MM hh:mm tt", 
                       CultureInfo.InvariantCulture, 
                       DateTimeStyles.None, 
                       out dt);

Вам нужно использовать ParseExact метод. Это принимает строку в качестве второго аргумента, который определяет формат даты и времени, например:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
try
{
   result = DateTime.ParseExact(dateString, format, provider);
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
catch (FormatException)
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

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

Если есть вероятность, что ввод будет неправильным (например, пользовательский ввод), лучше использовать TryParseExact вместо использования исключений для обработки ошибки:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
DateTime result;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out result))
{
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
else
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

Лучшей альтернативой может быть не предоставление пользователю выбора форматов даты, а использование перегрузки, которая принимает массив форматов:

// A list of possible American date formats - swap M and d for European formats
string[] formats= {"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",
                   "MM/d/yyyy HH:mm:ss.ffffff" };
string dateString; // The string the date gets read into

try
{
    dateValue = DateTime.ParseExact(dateString, formats, 
                                    new CultureInfo("en-US"), 
                                    DateTimeStyles.None);
    Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}                                               

Если вы читаете возможные форматы из файла конфигурации или базы данных, вы можете добавить к ним различные способы, с помощью которых люди хотят вводить даты.

Попробуйте использовать безопасный метод TryParseExact

DateTime temp;
string   date = "2011-29-01 12:00 am";

DateTime.TryParseExact(date, "yyyy-dd-MM hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out temp);

С DateTime на MSDN:

Тип: System.DateTime% Когда этот метод возвращает значение, содержит значение DateTime, эквивалентное дате и времени, содержащемуся в s, если преобразование выполнено успешно, или MinValue, если преобразование не выполнено. Преобразование завершается неудачно, если параметр s имеет значение null, является пустой строкой ("") или не содержит допустимого строкового представления даты и времени. Этот параметр передается неинициализированным.

Используйте parseexact со строкой формата "yyyy-dd-MM hh:mm tt" вместо.

Это работает:

DateTime dt = DateTime.ParseExact("2011-29-01 12:00 am", "yyyy-dd-MM hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
DateTime dt = DateTime.ParseExact("11-22-2012 12:00 am", "MM-dd-yyyy hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);

Если вы дадите пользователю возможность изменить формат даты / времени, вам придется создать соответствующую строку формата для использования при разборе. Если вы знаете возможные форматы даты (т.е. пользователь должен выбрать из списка), то это намного проще, потому что вы можете создавать эти строки формата во время компиляции.

Если вы позволите пользователю делать произвольный дизайн формата даты / времени, то вам придется создать соответствующий DateTime форматировать строки во время выполнения.

Другие вопросы по тегам