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

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

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

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

Текущий объект DateTimeFormatInfo обеспечивает более точный контроль над тем, как текст должен интерпретироваться в качестве даты и времени. В свойствах DateTimeFormatInfo описываются разделители даты и времени, названия месяцев, дней и эр, а также формат для обозначения AM и PM. Объект DateTimeFormatInfo в текущем потоке представляет текущие язык и региональные параметры. Если требуется задать определенные язык и региональные параметры или настраиваемые параметры, укажите для метода анализа параметр 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" неясно, какие компоненты соответствуют месяцу, дню и году. Такие компоненты интерпретируются согласно их порядку расположения в схожих форматах даты в поставщике формата.

Parse

Ниже приведен пример использования метода 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. Но такой метод не поддерживает анализ нестандартных форматов. Вместо этого используйте метод 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 используется дополнительная строка или аргумент массива строк для определения одного или нескольких настраиваемых форматов даты и времени.

См. также