Синтаксический анализ строк даты и времени в .NET

Чтобы анализировать строки для преобразования их в объекты DateTime, нужно указать, как значения даты и времени представлены в текстовом формате. Для различных языков и региональных параметров значения дня, месяца и года приводятся в разном порядке. В некоторых представлениях используются 24-часовые часы, а другие — "AM" и "PM". Для некоторых приложений требуется только дата. В других — только время. Тем не менее, другим необходимо указать дату и время. Методы преобразования строк в объекты DateTime позволяют предоставлять подробные сведения о требуемых форматах и элементах дат и времени, которые необходимы для вашего приложения. Есть три подзадачи для правильного преобразования текста в DateTime:

  1. Укажите требуемый формат текста, представляющего дату и время.
  2. Можно указать язык и региональные параметры для формата даты.
  3. Можно указать, как отсутствующие компоненты в текстовом представлении задаются в дате и времени.

Методы Parse и TryParse позволяют преобразовать много стандартных представлений даты и времени. Методы ParseExactи TryParseExact позволяют преобразовать строковое представление, соответствующее шаблону, указанному в строке формата даты и времени. Дополнительные сведения см. в статьях о стандартных строках формата даты и времени и настраиваемых строках формата даты и времени.

Текущий объект DateTimeFormatInfo обеспечивает более точный контроль над тем, как текст должен интерпретироваться в качестве даты и времени. DateTimeFormatInfo Свойства разделителей даты и времени, имена месяцев, дней и эр, а также формат для обозначений AM и PM. Возвращаемое CultureInfoCultureInfo.CurrentCulture свойство имеет CultureInfo.DateTimeFormat свойство, представляющее текущий язык и региональные параметры. Если требуется задать определенные язык и региональные параметры или настраиваемые параметры, укажите для метода анализа параметр IFormatProvider. Для параметра IFormatProvider следует указать объект CultureInfo, представляющий язык и региональные параметры, или объект DateTimeFormatInfo.

Текст, представляющий дату или время, может пропустить некоторые сведения. Например, большинство пользователей будет считать, что дата "12 марта" относится к текущему году. Аналогичным образом, "март 2018 г." представляет месяц март 2018 года. Текст, представляющий время, часто включает только часы, минуты и обозначение AM/PM. При помощи методов анализа эти отсутствующие данные обрабатываются с использованием обоснованных значений по умолчанию:

  • если указано только время, в части даты используется текущая дата;
  • если указана только дата, в части времени задается полночь;
  • если в дате не указан год, используется текущий год;
  • Если день месяца не указан, используется первый день месяца.

Если в строке есть дата, она должна включать месяц и день или год. Если указано время, значение должно содержать час и минуты или обозначение AM либо PM.

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

Помимо компонента даты и времени строковое представление даты и времени может содержать смещение, которое указывает, насколько время отличается от универсального синхронизированного времени (UTC). Например, строка "14/02/2007 5:32:00 -7: 00" определяет время, которое на семь часов меньше, чем UTC. Если в строковом представлении времени не задано смещение, то синтаксический анализ возвращает объект DateTime, свойство Kind которого имеет значение DateTimeKind.Unspecified. Если задано смещение, синтаксический анализ возвращает DateTime объект со своим Kind свойством, равным DateTimeKind.Local. Его значение также настраивается на локальный часовой пояс компьютера. Это поведение можно изменить, указав для метода анализа значение DateTimeStyles.

Поставщик формата также используется для интерпретации неоднозначных числовых дат. Неясно, какие компоненты даты представлены строкой "02/03/04" — это месяц, день и год. Такие компоненты интерпретируются согласно их порядку расположения в схожих форматах даты в поставщике формата.

Разбор

Ниже приведен пример использования метода DateTime.Parse для преобразования string в DateTime. В этом примере используются язык и региональные параметры, связанные с текущим потоком. CultureInfo Если связанный с текущим языком и региональными параметрами не может проанализировать входную строку, FormatException создается исключение.

Совет

Все примеры C# в этой статье выполняются в браузере. Нажмите кнопку Выполнить, чтобы просмотреть выходные данные. Вы можете поэкспериментировать, изменяя их значения.

Примечание.

Эти примеры для C# и Visual Basic см. в репозитории с документацией GitHub.

string dateInput = "Jan 1, 2009";
var parsedDate = DateTime.Parse(dateInput);
Console.WriteLine(parsedDate);
// Displays the following output on a system whose culture is en-US:
//       1/1/2009 00:00:00
Dim MyString As String = "Jan 1, 2009"
Dim MyDateTime As DateTime = DateTime.Parse(MyString)
Console.WriteLine(MyDateTime)
' Displays the following output on a system whose culture is en-US:
'       1/1/2009 00:00:00

Кроме того, вы можете явно определить язык и региональные параметры, соглашения о форматировании для которых используются при анализе строки. Укажите один из стандартных объектов DateTimeFormatInfo, возвращенных свойством CultureInfo.DateTimeFormat. В приведенном ниже примере поставщик формата используется для анализа строки на немецком языке в DateTime. Для представления языка и региональных параметров de-DE создается CultureInfo. Этот объект CultureInfo обеспечивает успешный анализ определенной строки. Этот процесс исключает любой параметр в CurrentCulture параметре CurrentThread.

var cultureInfo = new CultureInfo("de-DE");
string dateString = "12 Juni 2008";
var dateTime = DateTime.Parse(dateString, cultureInfo);
Console.WriteLine(dateTime);
// The example displays the following output:
//       6/12/2008 00:00:00
Dim MyCultureInfo As New CultureInfo("de-DE")
Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo)
Console.WriteLine(MyDateTime)
' The example displays the following output:
'       6/12/2008 00:00:00

Однако можно использовать перегрузки метода для указания настраиваемых поставщиков Parse форматов. Метод Parse не поддерживает синтаксический анализ форматов, отличных от стандартных. Вместо этого используйте метод ParseExact для анализа даты и времени, выраженных в нестандартном формате.

В следующем примере перечисление DateTimeStyles используется для указания того, что текущие сведения о дате и времени не должны быть добавлены в DateTime поля без указания.

var cultureInfo = new CultureInfo("de-DE");
string dateString = "12 Juni 2008";
var dateTime = DateTime.Parse(dateString, cultureInfo,
                                DateTimeStyles.NoCurrentDateDefault);
Console.WriteLine(dateTime);
// The example displays the following output if the current culture is en-US:
//      6/12/2008 00:00:00
Dim MyCultureInfo As New CultureInfo("de-DE")
Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo,
                           DateTimeStyles.NoCurrentDateDefault)
Console.WriteLine(MyDateTime)
' The example displays the following output if the current culture is en-US:
'       6/12/2008 00:00:00

ParseExact

Метод DateTime.ParseExact позволяет преобразовать строку в объект DateTime, если она соответствует одному из указанных шаблонов строк. Если строка, которая не является одной из указанных форм, передается этому методу, FormatException создается исключение. Можно задать один из стандартных описателей формата даты и времени или сочетание пользовательских описателей формата. С помощью пользовательских описателей формата можно создать настраиваемую строку распознавания. Описание описателей см. в статьях о стандартных строках формата даты и времени и настраиваемых строк формата даты и времени.

В приведенном ниже примере в метод DateTime.ParseExact передается переназначенный для анализа строковый объект. Затем следует описатель формата, который сопровождается объектом CultureInfo. С помощью этого метода ParseExact можно анализировать только строки, соответствующие шаблону полной даты для языка и региональных параметров en-US.

var cultureInfo = new CultureInfo("en-US");
string[] dateStrings = { " Friday, April 10, 2009", "Friday, April 10, 2009" };
foreach (string dateString in dateStrings)
{
    try
    {
        var dateTime = DateTime.ParseExact(dateString, "D", cultureInfo);
        Console.WriteLine(dateTime);
    }
    catch (FormatException)
    {
        Console.WriteLine("Unable to parse '{0}'", dateString);
    }
}
// The example displays the following output:
//       Unable to parse ' Friday, April 10, 2009'
//       4/10/2009 00:00:00
Dim MyCultureInfo As New CultureInfo("en-US")
Dim MyString() As String = {" Friday, April 10, 2009", "Friday, April 10, 2009"}
For Each dateString As String In MyString
    Try
        Dim MyDateTime As DateTime = DateTime.ParseExact(dateString, "D",
                                                     MyCultureInfo)
        Console.WriteLine(MyDateTime)
    Catch e As FormatException
        Console.WriteLine("Unable to parse '{0}'", dateString)
    End Try
Next
' The example displays the following output:
'       Unable to parse ' Friday, April 10, 2009'
'       4/10/2009 00:00:00

При каждой перегрузке методов Parse и ParseExact также используется параметр IFormatProvider, который предоставляет сведения о языке и региональных параметрах для форматирования строки. Объект IFormatProvider — это CultureInfo объект, представляющий стандартный язык и региональные параметры или DateTimeFormatInfo объект, возвращаемый свойством CultureInfo.DateTimeFormat . Кроме того, в методе ParseExact используется дополнительная строка или аргумент массива строк для определения одного или нескольких настраиваемых форматов даты и времени.

См. также