Класс DateTimeFormatInfo

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

Свойства DateTimeFormatInfo класса содержат сведения о языке и региональных параметрах для форматирования или анализа значений даты и времени, таких как:

  • Шаблоны, используемые для форматирования значений дат.
  • Шаблоны, используемые для форматирования значений времени.
  • Имена дней недели.
  • Имена месяцев года.
  • Конструкторы A.M. и P.M. используются в значениях времени.
  • Календарь, в котором выражаются даты.

Создание экземпляра объекта DateTimeFormatInfo

Объект DateTimeFormatInfo может представлять соглашения о форматировании инвариантного языка и региональных параметров, определенного языка и региональных параметров, нейтрального языка и региональных параметров или текущего языка и региональных параметров. В этом разделе описывается создание экземпляра DateTimeFormatInfo каждого типа объекта.

Создание экземпляра объекта DateTimeFormatInfo для инвариантного языка и региональных параметров

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

В следующем примере каждый из этих методов используется для создания экземпляра DateTimeFormatInfo объекта, представляющего инвариантный язык и региональные параметры. Затем он указывает, доступен ли объект только для чтения.

System.Globalization.DateTimeFormatInfo dtfi;

dtfi = System.Globalization.DateTimeFormatInfo.InvariantInfo;
Console.WriteLine(dtfi.IsReadOnly);

dtfi = new System.Globalization.DateTimeFormatInfo();
Console.WriteLine(dtfi.IsReadOnly);

dtfi = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat;
Console.WriteLine(dtfi.IsReadOnly);
// The example displays the following output:
//       True
//       False
//       True

Создание экземпляра объекта DateTimeFormatInfo для определенного языка и региональных параметров

Определенный язык и региональные параметры представляют язык, который говорится в определенной стране или регионе. Например, en-US — это определенная культура, представляющая английский язык, который говорится в США, а en-CA — это определенная культура, представляющая английский язык, который говорится в Канаде. Вы можете создать экземпляр DateTimeFormatInfo объекта, представляющего соглашения о форматировании определенного языка и региональных параметров следующим образом:

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

System.Globalization.CultureInfo ci = null;
System.Globalization.DateTimeFormatInfo dtfi = null;

// Instantiate a culture using CreateSpecificCulture.
ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from CreateSpecificCulture: {1}", ci.Name, dtfi.IsReadOnly);

// Instantiate a culture using the CultureInfo constructor.
ci = new System.Globalization.CultureInfo("en-CA");
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from CultureInfo constructor: {1}", ci.Name, dtfi.IsReadOnly);

// Retrieve a culture by calling the GetCultureInfo method.
ci = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from GetCultureInfo: {1}", ci.Name, dtfi.IsReadOnly);

// Instantiate a DateTimeFormatInfo object by calling DateTimeFormatInfo.GetInstance.
ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");
dtfi = System.Globalization.DateTimeFormatInfo.GetInstance(ci);
Console.WriteLine("{0} from GetInstance: {1}", ci.Name, dtfi.IsReadOnly);

// The example displays the following output:
//      en-US from CreateSpecificCulture: False
//      en-CA from CultureInfo constructor: False
//      en-AU from GetCultureInfo: True
//      en-GB from GetInstance: False

Создание экземпляра объекта DateTimeFormatInfo для нейтрального языка и региональных параметров

Нейтральный язык и региональные параметры представляют язык или язык, не зависящий от страны или региона; Обычно это родитель одного или нескольких конкретных языков и региональных параметров. Например, Fr является нейтральным языком для французского языка и родительским языком fr-FR. Вы можете создать DateTimeFormatInfo экземпляр объекта, представляющего соглашения о форматировании нейтрального языка и региональных параметров таким же образом, как создать DateTimeFormatInfo объект, представляющий соглашения о форматировании определенного языка и региональных параметров. Кроме того, можно получить объект нейтрального языка и DateTimeFormatInfo региональных параметров, извлекая нейтральный язык и региональные параметры из свойства конкретного языка CultureInfo.Parent и извлекая DateTimeFormatInfo объект, возвращаемый его CultureInfo.DateTimeFormat свойством. Если родительский язык и региональные параметры не представляют инвариантный язык и региональные параметры, возвращаемый DateTimeFormatInfo объект считывается или записывается. В следующем примере показано, как создать экземпляр DateTimeFormatInfo объекта, представляющего нейтральный язык и региональные параметры.

System.Globalization.CultureInfo specific, neutral;
System.Globalization.DateTimeFormatInfo dtfi;

// Instantiate a culture by creating a specific culture and using its Parent property.
specific = System.Globalization.CultureInfo.GetCultureInfo("fr-FR");
neutral = specific.Parent;
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from Parent property: {1}", neutral.Name, dtfi.IsReadOnly);

dtfi = System.Globalization.CultureInfo.GetCultureInfo("fr-FR").Parent.DateTimeFormat;
Console.WriteLine("{0} from Parent property: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a neutral culture using the CultureInfo constructor.
neutral = new System.Globalization.CultureInfo("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from CultureInfo constructor: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a culture using CreateSpecificCulture.
neutral = System.Globalization.CultureInfo.CreateSpecificCulture("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from CreateSpecificCulture: {1}", neutral.Name, dtfi.IsReadOnly);

// Retrieve a culture by calling the GetCultureInfo method.
neutral = System.Globalization.CultureInfo.GetCultureInfo("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from GetCultureInfo: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a DateTimeFormatInfo object by calling GetInstance.
neutral = System.Globalization.CultureInfo.CreateSpecificCulture("fr");
dtfi = System.Globalization.DateTimeFormatInfo.GetInstance(neutral);
Console.WriteLine("{0} from GetInstance: {1}", neutral.Name, dtfi.IsReadOnly);

// The example displays the following output:
//       fr from Parent property: False
//       fr from Parent property: False
//       fr from CultureInfo constructor: False
//       fr-FR from CreateSpecificCulture: False
//       fr from GetCultureInfo: True
//       fr-FR from GetInstance: False

Однако нейтральный язык и региональные параметры не имеют сведений о форматировании, так как они не зависят от конкретной страны или региона. Вместо заполнения DateTimeFormatInfo объекта универсальными значениями .NET возвращает DateTimeFormatInfo объект, который отражает соглашения о форматировании определенного языка и региональных параметров, который является дочерним элементом нейтрального языка и региональных параметров. Например, DateTimeFormatInfo объект для нейтрального языка и региональных параметров отражает соглашения о форматировании языка и региональных параметров en-US, а DateTimeFormatInfo объект для языка и региональных параметров fr отражает соглашения о форматировании языка fr-FR.

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

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

public class InstantiateEx6
{
    public static void Main()
    {
        // Get all the neutral cultures
        List<String> names = new List<String>();
        Array.ForEach(CultureInfo.GetCultures(CultureTypes.NeutralCultures),
                      culture => names.Add(culture.Name));
        names.Sort();
        foreach (var name in names)
        {
            // Ignore the invariant culture.
            if (name == "") continue;

            ListSimilarChildCultures(name);
        }
    }

    private static void ListSimilarChildCultures(String name)
    {
        // Create the neutral DateTimeFormatInfo object.
        DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo(name).DateTimeFormat;
        // Retrieve all specific cultures of the neutral culture.
        CultureInfo[] cultures = Array.FindAll(CultureInfo.GetCultures(CultureTypes.SpecificCultures),
                                 culture => culture.Name.StartsWith(name + "-", StringComparison.OrdinalIgnoreCase));
        // Create an array of DateTimeFormatInfo properties
        PropertyInfo[] properties = typeof(DateTimeFormatInfo).GetProperties(BindingFlags.Instance | BindingFlags.Public);
        bool hasOneMatch = false;

        foreach (var ci in cultures)
        {
            bool match = true;
            // Get the DateTimeFormatInfo for a specific culture.
            DateTimeFormatInfo specificDtfi = ci.DateTimeFormat;
            // Compare the property values of the two.
            foreach (var prop in properties)
            {
                // We're not interested in the value of IsReadOnly.
                if (prop.Name == "IsReadOnly") continue;

                // For arrays, iterate the individual elements to see if they are the same.
                if (prop.PropertyType.IsArray)
                {
                    IList nList = (IList)prop.GetValue(dtfi, null);
                    IList sList = (IList)prop.GetValue(specificDtfi, null);
                    if (nList.Count != sList.Count)
                    {
                        match = false;
                        Console.WriteLine("   Different n in {2} array for {0} and {1}", name, ci.Name, prop.Name);
                        break;
                    }

                    for (int ctr = 0; ctr < nList.Count; ctr++)
                    {
                        if (!nList[ctr].Equals(sList[ctr]))
                        {
                            match = false;
                            Console.WriteLine("   {0} value different for {1} and {2}", prop.Name, name, ci.Name);
                            break;
                        }
                    }

                    if (!match) break;
                }
                // Get non-array values.
                else
                {
                    Object specificValue = prop.GetValue(specificDtfi);
                    Object neutralValue = prop.GetValue(dtfi);

                    // Handle comparison of Calendar objects.
                    if (prop.Name == "Calendar")
                    {
                        // The cultures have a different calendar type.
                        if (specificValue.ToString() != neutralValue.ToString())
                        {
                            Console.WriteLine("   Different calendar types for {0} and {1}", name, ci.Name);
                            match = false;
                            break;
                        }

                        if (specificValue is GregorianCalendar)
                        {
                            if (((GregorianCalendar)specificValue).CalendarType != ((GregorianCalendar)neutralValue).CalendarType)
                            {
                                Console.WriteLine("   Different Gregorian calendar types for {0} and {1}", name, ci.Name);
                                match = false;
                                break;
                            }
                        }
                    }
                    else if (!specificValue.Equals(neutralValue))
                    {
                        match = false;
                        Console.WriteLine("   Different {0} values for {1} and {2}", prop.Name, name, ci.Name);
                        break;
                    }
                }
            }
            if (match)
            {
                Console.WriteLine("DateTimeFormatInfo object for '{0}' matches '{1}'",
                                  name, ci.Name);
                hasOneMatch = true;
            }
        }
        if (!hasOneMatch)
            Console.WriteLine("DateTimeFormatInfo object for '{0}' --> No Match", name);

        Console.WriteLine();
    }
}

Создание экземпляра объекта DateTimeFormatInfo для текущего языка и региональных параметров

Вы можете создать экземпляр DateTimeFormatInfo объекта, представляющего соглашения о форматировании текущего языка и региональных параметров следующим образом:

  • Извлекая значение CurrentInfo свойства. Возвращаемый DateTimeFormatInfo объект доступен только для чтения.

  • Извлекая значение DateTimeFormat свойства из CultureInfo объекта, возвращаемого свойством CultureInfo.CurrentCulture . Возвращаемый DateTimeFormatInfo объект доступен только для чтения.

  • Вызывая GetInstance метод с CultureInfo объектом, который представляет текущий язык и региональные параметры. Возвращаемый DateTimeFormatInfo объект доступен только для чтения.

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

DateTimeFormatInfo dtfi;

dtfi = DateTimeFormatInfo.CurrentInfo;
Console.WriteLine(dtfi.IsReadOnly);

dtfi = CultureInfo.CurrentCulture.DateTimeFormat;
Console.WriteLine(dtfi.IsReadOnly);

dtfi = DateTimeFormatInfo.GetInstance(CultureInfo.CurrentCulture);
Console.WriteLine(dtfi.IsReadOnly);
// The example displays the following output:
//     True
//     True
//     True

Вы можете создать объект, доступный DateTimeFormatInfo для записи, который представляет соглашения текущего языка и региональных параметров одним из следующих способов:

  • Извлекая объект в любом из трех предыдущих способов и вызывая DateTimeFormatInfo Clone метод для возвращаемого DateTimeFormatInfo объекта. При этом создается копия исходного DateTimeFormatInfo объекта, за исключением того, что его IsReadOnly свойство имеет falseзначение.

  • Вызывая CultureInfo.CreateSpecificCulture метод для создания CultureInfo объекта, представляющего текущий язык и региональные параметры, а затем используя его CultureInfo.DateTimeFormat свойство для получения DateTimeFormatInfo объекта.

В следующем примере показано, как создать экземпляр объекта чтения и записи DateTimeFormatInfo и отобразить значение его IsReadOnly свойства.

using System;
using System.Globalization;

public class InstantiateEx1
{
    public static void Main()
    {
        DateTimeFormatInfo current1 = DateTimeFormatInfo.CurrentInfo;
        current1 = (DateTimeFormatInfo)current1.Clone();
        Console.WriteLine(current1.IsReadOnly);

        CultureInfo culture2 = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
        DateTimeFormatInfo current2 = culture2.DateTimeFormat;
        Console.WriteLine(current2.IsReadOnly);
    }
}
// The example displays the following output:
//       False
//       False

В Windows пользователь может переопределить некоторые DateTimeFormatInfo значения свойств, используемые в операциях форматирования и синтаксического анализа с помощью приложения "Регион" и "Язык" в панель управления. Например, пользователь, язык и региональные параметры которого — английский (США) могут отображать длинные значения времени, используя 24-часовые часы (в формате HH:mm:ss) вместо 12-часовых часов (в формате h:mm:ss tt). Объекты DateTimeFormatInfo , полученные ранее, отражают переопределения этих пользователей. Если это нежелательно, можно создать NumberFormatInfo объект, который не отражает переопределения пользователей (а не только для чтения или записи), вызвав CultureInfo.CultureInfo(String, Boolean) конструктор и указав значение аргумента false useUserOverride . В следующем примере показано это для системы с текущим языком и региональными параметрами (США) и длинным шаблоном времени которого по умолчанию было изменено значение h:mm:ss tt на HH:mm:ss.

using System;
using System.Globalization;

public class InstantiateEx3
{
    public static void Main()
    {
        CultureInfo culture;
        DateTimeFormatInfo dtfi;

        culture = CultureInfo.CurrentCulture;
        dtfi = culture.DateTimeFormat;
        Console.WriteLine("Culture Name:      {0}", culture.Name);
        Console.WriteLine("User Overrides:    {0}", culture.UseUserOverride);
        Console.WriteLine("Long Time Pattern: {0}\n", culture.DateTimeFormat.LongTimePattern);

        culture = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
        Console.WriteLine("Culture Name:      {0}", culture.Name);
        Console.WriteLine("User Overrides:    {0}", culture.UseUserOverride);
        Console.WriteLine("Long Time Pattern: {0}\n", culture.DateTimeFormat.LongTimePattern);
    }
}
// The example displays the following output:
//       Culture Name:      en-US
//       User Overrides:    True
//       Long Time Pattern: HH:mm:ss
//
//       Culture Name:      en-US
//       User Overrides:    False
//       Long Time Pattern: h:mm:ss tt

DateTimeFormatInfo и динамические данные

Данные, зависящие DateTimeFormatInfo от языка и региональных параметров, для форматирования значений даты и времени, предоставляемых классом, являются динамическими, как и региональные данные, предоставляемые классом CultureInfo . Не следует делать никаких предположений о стабильности значений для DateTimeFormatInfo объектов, связанных с конкретными CultureInfo объектами. Только данные, предоставляемые инвариантным языком и языком и связанным DateTimeFormatInfo объектом, стабильны. Другие данные могут изменяться между сеансами приложений или даже во время работы приложения. Существует четыре основных источника изменений:

  • Обновления системы. Культурные предпочтения, такие как предпочтительный календарь или обычные форматы даты и времени, меняются со временем. В этом случае Обновл. Windows включает изменения DateTimeFormatInfo в значение свойства для определенного языка и региональных параметров.

  • Язык и региональные параметры замены. Класс CultureAndRegionInfoBuilder можно использовать для замены данных существующего языка и региональных параметров.

  • Каскадные изменения значений свойств. Ряд свойств, связанных с языком и региональными параметрами, может изменяться во время выполнения, что, в свою очередь, приводит DateTimeFormatInfo к изменению данных. Например, текущий язык и региональные параметры можно изменить программным способом или с помощью действия пользователя. Когда это происходит, объект, возвращаемый свойствомCurrentInfo, DateTimeFormatInfo изменяется на объект, связанный с текущим языком и региональными параметрами. Аналогичным образом календарь языка и региональных параметров может измениться, что может привести к изменению многочисленных DateTimeFormatInfo значений свойств.

  • Параметры пользователя. Пользователи приложения могут переопределить некоторые значения, связанные с текущим языком и региональными параметрами системы, с помощью региональных и языковых параметров в панель управления. Например, пользователи могут выбрать отображение даты в другом формате. CultureInfo.UseUserOverride Если для свойства задано trueзначение, свойства DateTimeFormatInfo объекта также извлекаются из параметров пользователя. Если параметры пользователя несовместимы с языком и региональными параметрами, связанными с CultureInfo объектом (например, если выбранный календарь не является одним из календарей, указанных OptionalCalendars свойством), результаты методов и значения свойств не определены.

Чтобы свести к минимуму возможность несогласованных данных, все переопределительные свойства DateTimeFormatInfo объекта инициализированы при создании объекта. Существует по-прежнему вероятность несоответствия, поскольку ни создание объекта, ни процесс переопределения пользователя атомарным, а соответствующие значения могут изменяться во время создания объекта. Однако эта ситуация должна быть крайне редкой.

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

Источник объекта CultureInfo и DateTimeFormatInfo Отражает переопределение пользователей
Свойство CultureInfo.CurrentCulture.DateTimeFormat Да
Свойство DateTimeFormatInfo.CurrentInfo Да
CultureInfo.CreateSpecificCultureМетод Да
CultureInfo.GetCultureInfoМетод No
Конструктор CultureInfo.CultureInfo(String) Да
Конструктор CultureInfo.CultureInfo(String, Boolean) Зависит от значения useUserOverride параметра

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

Форматирование дат и времени

DateTimeFormatInfo Объект используется неявно или явно во всех операциях форматирования даты и времени. К ним относятся вызовы следующих методов:

Все операции форматирования даты и времени используют реализацию IFormatProvider . Интерфейс IFormatProvider включает один метод. IFormatProvider.GetFormat(Type) Этот метод обратного вызова передает объект, представляющий тип, необходимый Type для предоставления сведений о форматировании. Метод возвращает либо экземпляр этого типа, либо null если он не может предоставить экземпляр типа. .NET включает две IFormatProvider реализации для форматирования дат и времени:

  • Класс CultureInfo , представляющий определенный язык и региональные параметры (или определенный язык в определенной стране или регионе). В операции форматирования даты и времени метод возвращает DateTimeFormatInfo объект, CultureInfo.GetFormat связанный с его CultureInfo.DateTimeFormat свойством.
  • Класс DateTimeFormatInfo , предоставляющий сведения о соглашениях форматирования связанного языка и региональных параметров. Метод DateTimeFormatInfo.GetFormat возвращает сам экземпляр.

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

В следующем примере показана связь между интерфейсом IFormatProvider и DateTimeFormatInfo классом в операциях форматирования. Он определяет пользовательскую IFormatProvider реализацию, метод которой GetFormat отображает тип объекта, запрошенного операцией форматирования. Если он запрашивает DateTimeFormatInfo объект, метод предоставляет DateTimeFormatInfo объект для текущего языка и региональных параметров. Как показано в выходных данных из примера, Decimal.ToString(IFormatProvider) метод запрашивает DateTimeFormatInfo объект для предоставления сведений о форматировании, в то время как String.Format(IFormatProvider, String, Object[]) запросы NumberFormatInfo метода и DateTimeFormatInfo объекты, а также ICustomFormatter реализация.

using System;
using System.Globalization;

public class CurrentCultureFormatProvider : IFormatProvider
{
    public Object GetFormat(Type formatType)
    {
        Console.WriteLine("Requesting an object of type {0}",
                          formatType.Name);
        if (formatType == typeof(NumberFormatInfo))
            return NumberFormatInfo.CurrentInfo;
        else if (formatType == typeof(DateTimeFormatInfo))
            return DateTimeFormatInfo.CurrentInfo;
        else
            return null;
    }
}

public class FormatProviderEx1
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 5, 28, 13, 30, 0);
        string value = dateValue.ToString("F", new CurrentCultureFormatProvider());
        Console.WriteLine(value);
        Console.WriteLine();
        string composite = String.Format(new CurrentCultureFormatProvider(),
                                         "Date: {0:d}   Amount: {1:C}   Description: {2}",
                                         dateValue, 1264.03m, "Service Charge");
        Console.WriteLine(composite);
        Console.WriteLine();
    }
}
// The example displays output like the following:
//       Requesting an object of type DateTimeFormatInfo
//       Tuesday, May 28, 2013 1:30:00 PM
//
//       Requesting an object of type ICustomFormatter
//       Requesting an object of type DateTimeFormatInfo
//       Requesting an object of type NumberFormatInfo
//       Date: 5/28/2013   Amount: $1,264.03   Description: Service Charge

Форматирование строк и свойств DateTimeFormatInfo

Объект DateTimeFormatInfo включает три типа свойств, которые используются в операциях форматирования со значениями даты и времени:

  • Свойства, связанные с календарем. Такие свойства, как AbbreviatedDayNames, AbbreviatedMonthNamesи DayNamesMonthNames, связаны с календарем, используемым языком и региональными параметрами, которые определяются свойствомCalendar. Эти свойства используются для длинных форматов дат и времени.

  • Свойства, которые создают определяемую стандартами строку результата. SortableDateTimePatternСвойства RFC1123Patternи UniversalSortableDateTimePattern свойства содержат пользовательские строки форматирования, которые создают строки результатов, определенные международными стандартами. Эти свойства доступны только для чтения и не могут быть изменены.

  • Свойства, определяющие строки результатов с учетом языка и региональных параметров. Некоторые свойства, такие как FullDateTimePattern и, содержат настраиваемые строки форматирования, которые указывают ShortDatePatternформат строки результата. Другие, такие как AMDesignator, DateSeparatorи PMDesignator, определяют символы и региональные параметры или TimeSeparatorподстроки, которые можно включить в результирующую строку.

Стандартные строки формата даты и времени, такие как "d", "D", "f" и "F", являются псевдонимами, соответствующими определенным DateTimeFormatInfo свойствам шаблона формата. Большинство строк пользовательского формата даты и времени связаны со строками или подстроками, которые операция форматирования вставляет в результирующий поток. В следующей таблице перечислены стандартные и настраиваемые описатели формата даты и времени и связанные DateTimeFormatInfo с ними свойства. Дополнительные сведения об использовании этих описателей формата см. в разделе "Стандартные строки формата даты и времени" и "Настраиваемые строки формата даты и времени". Обратите внимание, что каждая строка стандартного DateTimeFormatInfo формата соответствует свойству, значение которого является настраиваемой строкой формата даты и времени. Отдельные описатели в этой строке настраиваемого формата, в свою очередь, соответствуют другим DateTimeFormatInfo свойствам. В таблице перечислены только DateTimeFormatInfo свойства, для которых стандартные строки формата являются псевдонимами, и не перечисляет свойства, к которым могут обращаться строки пользовательского формата, назначенные этим свойствам псевдонима. Кроме того, в таблице перечислены только настраиваемые описатели формата, соответствующие DateTimeFormatInfo свойствам.

Спецификатор формата Связанные свойства
"d" (короткая дата; строка стандартного формата) ShortDatePattern, чтобы определить общий формат строки результата.
"D" (длинная дата; строка стандартного формата) LongDatePattern, чтобы определить общий формат строки результата.
"f" (полная дата / короткое время; стандартная строка форматирования) LongDatePattern, чтобы определить формат компонента даты результирующих строк.

ShortTimePattern, чтобы определить формат компонента времени результирующих строк.
"F" (полная дата / долгое время; строка стандартного формата) LongDatePattern, чтобы определить формат компонента даты результирующих строк.

LongTimePattern, чтобы определить формат компонента времени результирующих строк.
"g" (общая дата / короткое время; строка стандартного формата) ShortDatePattern, чтобы определить формат компонента даты результирующих строк.

ShortTimePattern, чтобы определить формат компонента времени результирующих строк.
"G" (общая дата/ долгое время; строка стандартного формата) ShortDatePattern, чтобы определить формат компонента даты результирующих строк.

LongTimePattern, чтобы определить формат компонента времени результирующих строк.
"M", "m" (месяц/день; стандартная строка формата) MonthDayPattern, чтобы определить общий формат строки результата.
"O", "o" (дата и время кругового пути; строка стандартного формата) Нет.
"R", "r" (RFC1123; строка стандартного формата) RFC1123Pattern, чтобы определить строку результатов, соответствующую стандарту RFC 1123. свойство доступно только для чтения.
"s" (сортировка даты и времени; строка стандартного формата) SortableDateTimePattern, чтобы определить строку результатов, соответствующую стандарту ISO 8601. свойство доступно только для чтения.
"t" (короткое время; строка стандартного формата) ShortTimePattern, чтобы определить общий формат строки результата.
"T" (долгое время; строка стандартного формата) LongTimePattern, чтобы определить общий формат строки результата.
"u" (универсальная сортировка даты и времени; стандартная строка форматирования) UniversalSortableDateTimePattern, чтобы определить строку результатов, соответствующую стандарту ISO 8601 для согласованного универсального времени. свойство доступно только для чтения.
"U" (универсальная полная дата и время; строка стандартного формата) FullDateTimePattern, чтобы определить общий формат строки результата.
"Y", "y" (месяц года; стандартная строка формата) YearMonthPattern, чтобы определить общий формат строки результата.
"ddd" (настраиваемый описатель формата) AbbreviatedDayNames, чтобы включить сокращенное имя дня недели в результирующем строке.
"g", "gg" (настраиваемый описатель формата) GetEraName Вызывает метод для вставки имени эры в результируемую строку.
MMM (описатель пользовательского формата) AbbreviatedMonthNames или AbbreviatedMonthGenitiveNames, чтобы включить сокращенное имя месяца в строку результата.
MMMM (описатель пользовательского формата) MonthNames или MonthGenitiveNames, чтобы включить полное имя месяца в строку результата.
"t" (описатель пользовательского формата) AMDesignator или PMDesignator, чтобы включить первый символ конструктора AM/PM в строку результата.
"tt" (описатель пользовательского формата) AMDesignator или PMDesignator, чтобы включить полный конструктор AM/PM в строку результата.
":" (описатель пользовательского формата) TimeSeparator, чтобы включить разделитель времени в результирующую строку.
"/" (описатель пользовательского формата) DateSeparator, чтобы включить разделитель даты в результирующую строку.

Изменение свойств DateTimeFormatInfo

Вы можете изменить строку результатов, созданную строками формата даты и времени, изменив связанные свойства записываемого DateTimeFormatInfo объекта. Чтобы определить, является ли DateTimeFormatInfo объект записываемым, используйте IsReadOnly свойство. Чтобы настроить DateTimeFormatInfo объект таким образом, выполните указанные ниже действия.

  1. Создайте копию объекта с чтением и записью DateTimeFormatInfo , соглашения о форматировании которого необходимо изменить.

  2. Измените свойство или свойства, используемые для создания требуемой строки результата. (Сведения о том, как методы форматирования используют DateTimeFormatInfo свойства для определения строк результатов, см. в предыдущем разделе, в разделе "Форматирование строк" и свойств DateTimeFormatInfo.)

  3. Используйте пользовательский DateTimeFormatInfo объект, созданный в качестве аргумента IFormatProvider в вызовах методов форматирования.

Существует два других способа изменить формат результирующих строк:

  • Класс можно использовать CultureAndRegionInfoBuilder для определения пользовательского языка и региональных параметров (языка и региональных параметров, который имеет уникальное имя и дополняет существующие региональные параметры) или замещающего языка и региональных параметров (который используется вместо конкретного языка и региональных параметров). Этот язык и региональные параметры можно сохранять программным образом, так как любой CultureInfo объект, поддерживаемый .NET.

  • Если результируемая строка не учитывает язык и региональные параметры и не соответствует заданному формату, можно использовать настраиваемую строку формата даты и времени. Например, если вы сериализуете данные даты и времени в формате YYYYMMDDHHmmss, можно создать строку результата, передав строку настраиваемого формата DateTime.ToString(String) в метод, и можно преобразовать строку результата обратно в DateTime значение, вызвав DateTime.ParseExact метод.

Изменение шаблона короткой даты

В следующем примере изменяется формат строки результата, созданной строкой стандартного формата "d" (short date). Он изменяет связанное ShortDatePattern свойство для языка en-US или английского языка (США) со значения по умолчанию "M/d/y" на "y'-"MM"-"dd" и использует стандартную строку формата "d" для отображения даты как до, так и после ShortDatePattern изменения свойства.

using System;
using System.Globalization;

public class Example1
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 8, 18);
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        DateTimeFormatInfo dtfi = enUS.DateTimeFormat;

        Console.WriteLine("Before modifying DateTimeFormatInfo object: ");
        Console.WriteLine("{0}: {1}\n", dtfi.ShortDatePattern,
                                      dateValue.ToString("d", enUS));

        // Modify the short date pattern.
        dtfi.ShortDatePattern = "yyyy-MM-dd";
        Console.WriteLine("After modifying DateTimeFormatInfo object: ");
        Console.WriteLine("{0}: {1}", dtfi.ShortDatePattern,
                                      dateValue.ToString("d", enUS));
    }
}
// The example displays the following output:
//       Before modifying DateTimeFormatInfo object:
//       M/d/yyyy: 8/18/2013
//
//       After modifying DateTimeFormatInfo object:
//       yyyy-MM-dd: 2013-08-18

Изменение символа разделителя дат

В следующем примере изменяется символ разделителя даты в объекте DateTimeFormatInfo , который представляет соглашения о форматировании языка и региональных параметров fr-FR. В примере используется строка стандартного формата "g" для отображения даты как до, так и после DateSeparator изменения свойства.

using System;
using System.Globalization;

public class Example3
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 08, 28);
        CultureInfo frFR = CultureInfo.CreateSpecificCulture("fr-FR");
        DateTimeFormatInfo dtfi = frFR.DateTimeFormat;

        Console.WriteLine("Before modifying DateSeparator property: {0}",
                          dateValue.ToString("g", frFR));

        // Modify the date separator.
        dtfi.DateSeparator = "-";
        Console.WriteLine("After modifying the DateSeparator property: {0}",
                          dateValue.ToString("g", frFR));
    }
}
// The example displays the following output:
//       Before modifying DateSeparator property: 28/08/2013 00:00
//       After modifying the DateSeparator property: 28-08-2013 00:00

Изменение аббревиаций имени дня и шаблона длинной даты

В некоторых случаях шаблон длинной даты, который обычно отображает полное имя дня и месяца вместе с числом дня месяца и года, может быть слишком длинным. В следующем примере сокращен шаблон длинной даты для языка и региональных параметров en-US для возврата сокращенного имени дня с одним символом или двумя символами, за которым следует номер дня, сокращенное название месяца и год. Это делается путем назначения сокращенных AbbreviatedDayNames сокращений имени дня массиву, а также путем изменения строки настраиваемого формата, назначенной свойству LongDatePattern . Это влияет на строки результатов, возвращаемые строками стандартного формата "D" и "f".

using System;
using System.Globalization;

public class Example2
{
    public static void Main()
    {
        DateTime value = new DateTime(2013, 7, 9);
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
        String[] formats = { "D", "F", "f" };

        // Display date before modifying properties.
        foreach (var fmt in formats)
            Console.WriteLine("{0}: {1}", fmt, value.ToString(fmt, dtfi));

        Console.WriteLine();

        // We don't want to change the FullDateTimePattern, so we need to save it.
        String originalFullDateTimePattern = dtfi.FullDateTimePattern;

        // Modify day name abbreviations and long date pattern.
        dtfi.AbbreviatedDayNames = new String[] { "Su", "M", "Tu", "W", "Th", "F", "Sa" };
        dtfi.LongDatePattern = "ddd dd-MMM-yyyy";
        dtfi.FullDateTimePattern = originalFullDateTimePattern;
        foreach (var fmt in formats)
            Console.WriteLine("{0}: {1}", fmt, value.ToString(fmt, dtfi));
    }
}
// The example displays the following output:
//       D: Tuesday, July 9, 2013
//       F: Tuesday, July 9, 2013 12:00:00 AM
//       f: Tuesday, July 9, 2013 12:00 AM
//
//       D: Tu 09-Jul-2013
//       F: Tuesday, July 9, 2013 12:00:00 AM
//       f: Tu 09-Jul-2013 12:00 AM

Как правило, изменение LongDatePattern свойства также влияет на FullDateTimePattern свойство, которое, в свою очередь, определяет строку результата, возвращаемую строкой стандартного формата F. Чтобы сохранить исходный шаблон полной даты и времени, пример переназначает исходную строку пользовательского формата, назначенную FullDateTimePattern свойству после LongDatePattern изменения свойства.

Изменение с 12-часовых часов на 24-часовые часы

Для многих культур в .NET время выражается с помощью 12-часовых часов и конструктора AM/PM. В следующем примере определяется ReplaceWith24HourClock метод, который заменяет любой формат времени, использующий 12-часовые часы форматом, использующим 24-часовые часы.

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class Example5
{
    public static void Main()
    {
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        DateTimeFormatInfo dtfi = enUS.DateTimeFormat;

        Console.WriteLine("Original Property Values:");
        Console.WriteLine("ShortTimePattern: " + dtfi.ShortTimePattern);
        Console.WriteLine("LongTimePattern: " + dtfi.LongTimePattern);
        Console.WriteLine("FullDateTimePattern: " + dtfi.FullDateTimePattern);
        Console.WriteLine();

        dtfi.LongTimePattern = ReplaceWith24HourClock(dtfi.LongTimePattern);
        dtfi.ShortTimePattern = ReplaceWith24HourClock(dtfi.ShortTimePattern);

        Console.WriteLine("Modififed Property Values:");
        Console.WriteLine("ShortTimePattern: " + dtfi.ShortTimePattern);
        Console.WriteLine("LongTimePattern: " + dtfi.LongTimePattern);
        Console.WriteLine("FullDateTimePattern: " + dtfi.FullDateTimePattern);
    }

    private static string ReplaceWith24HourClock(string fmt)
    {
        string pattern = @"^(?<openAMPM>\s*t+\s*)? " +
                         @"(?(openAMPM) h+(?<nonHours>[^ht]+)$ " +
                         @"| \s*h+(?<nonHours>[^ht]+)\s*t+)";
        return Regex.Replace(fmt, pattern, "HH${nonHours}",
                             RegexOptions.IgnorePatternWhitespace);
    }
}
// The example displays the following output:
//       Original Property Values:
//       ShortTimePattern: h:mm tt
//       LongTimePattern: h:mm:ss tt
//       FullDateTimePattern: dddd, MMMM dd, yyyy h:mm:ss tt
//
//       Modififed Property Values:
//       ShortTimePattern: HH:mm
//       LongTimePattern: HH:mm:ss
//       FullDateTimePattern: dddd, MMMM dd, yyyy HH:mm:ss

В примере используется регулярное выражение для изменения строки форматирования. Шаблон @"^(?<openAMPM>\s*t+\s*)? (?(openAMPM) h+(?<nonHours>[^ht]+)$ | \s*h+(?<nonHours>[^ht]+)\s*t+) регулярного выражения определяется следующим образом:

Расписание Description
^ Начало совпадения в начале строки.
(?<openAMPM>\s*t+\s*)? Соответствует нулю или одному вхождения нулю или нескольким символам пробела, за которым следует буква "t" один или несколько раз, за которым следует ноль или несколько символов пробелов. Эта группа записи называется openAMPM.
(?(openAMPM) h+(?<nonHours>[^ht]+)$ openAMPM Если группа имеет совпадение, соответствует букве "h" один или несколько раз, а затем один или несколько символов, которые не являются "h" или "t". Совпадение заканчивается в конце строки. Все символы, захваченные после "h", включаются в группу записи с именем nonHours.
&#124; \s*h+(?<nonHours>[^ht]+)\s*t+) openAMPM Если у группы нет совпадений, совпадайте с буквой "h" один или несколько раз, а затем один или несколько символов, которые не являются "h" или "t", за которыми следует ноль или несколько символов пробелов. Наконец, соответствует одному или нескольким вхождениям буквы "t". Все символы, захваченные после "h" и до пробелов и t, включаются в группу записи с именем nonHours.

Группа nonHours записи содержит минуту и, возможно, второй компонент настраиваемой строки формата даты и времени, а также символы разделителя времени. Шаблон замены HH${nonHours} добавляет подстроку "HH" к этим элементам.

Отображение и изменение эпохи в дате

В следующем примере добавляется описатель LongDatePattern пользовательского формата g в свойство объекта, представляющего соглашения о форматировании языка и региональных параметров en-US. Это дополнение влияет на следующие три стандартные строки формата:

  • Строка стандартного формата "D" (long date), которая сопоставляется непосредственно с свойством LongDatePattern .

  • Строка стандартного формата "f" (полная дата или короткое время), которая создает строку результата, которая объединяет подстроки, созданные свойствами LongDatePattern и ShortTimePattern свойствами.

  • Строка стандартного формата "F" (полная дата или долгое время), которая сопоставляется непосредственно с свойством FullDateTimePattern . Так как мы явно не задали это значение свойства, он создается динамически путем объединения LongDatePattern свойств и LongTimePattern свойств.

В примере также показано, как изменить имя эпохи для культуры, календарь которого имеет одну эру. В этом случае язык и региональные параметры en-US используют григорианский календарь, который представлен GregorianCalendar объектом. Класс GregorianCalendar поддерживает одну эру, которая называется A.D. (Anno Domini). Пример изменяет имя эры на C.E. (Common Era), заменив описатель пользовательского формата g в строке формата, назначенной FullDateTimePattern свойству литеральной строкой. Необходимо использовать литеральную строку, так как имя эпохи обычно возвращается методом GetEraName из частных данных в таблицах языка и региональных параметров, предоставляемых .NET или операционной системой.

using System;
using System.Globalization;

public class Example4
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 5, 18, 13, 30, 0);
        String[] formats = { "D", "f", "F" };

        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
        String originalLongDatePattern = dtfi.LongDatePattern;

        // Display the default form of three long date formats.
        foreach (var fmt in formats)
            Console.WriteLine(dateValue.ToString(fmt, dtfi));

        Console.WriteLine();

        // Modify the long date pattern.
        dtfi.LongDatePattern = originalLongDatePattern + " g";
        foreach (var fmt in formats)
            Console.WriteLine(dateValue.ToString(fmt, dtfi));

        Console.WriteLine();

        // Change A.D. to C.E. (for Common Era)
        dtfi.LongDatePattern = originalLongDatePattern + @" 'C.E.'";
        foreach (var fmt in formats)
            Console.WriteLine(dateValue.ToString(fmt, dtfi));
    }
}
// The example displays the following output:
//       Saturday, May 18, 2013
//       Saturday, May 18, 2013 1:30 PM
//       Saturday, May 18, 2013 1:30:00 PM
//
//       Saturday, May 18, 2013 A.D.
//       Saturday, May 18, 2013 A.D. 1:30 PM
//       Saturday, May 18, 2013 A.D. 1:30:00 PM
//
//       Saturday, May 18, 2013 C.E.
//       Saturday, May 18, 2013 C.E. 1:30 PM
//       Saturday, May 18, 2013 C.E. 1:30:00 PM

Анализ строк даты и времени

Синтаксический анализ включает преобразование строкового представления даты и времени в DateTime или DateTimeOffset значение. Оба этих типа включают Parseметоды , TryParseParseExactи TryParseExact методы для поддержки операций синтаксического анализа. TryParse Методы Parse преобразуют строку, которая может иметь различные форматы, в то время как ParseExact TryParseExact для строки требуется определенный формат или формат. Если операция синтаксического анализа завершается ошибкой, Parse и ParseExact создается исключение, в то время как TryParse возвращается и TryParseExact возвращается false.

Методы синтаксического анализа неявно или явно используют DateTimeStyles значение перечисления, чтобы определить, какие элементы стиля (например, начальные, конечные или внутренние пробелы) могут присутствовать в строке для анализа, а также как интерпретировать синтаксический анализ или любые отсутствующие элементы. Если при вызове Parse или методе не задано DateTimeStyles значение, по умолчанию используется DateTimeStyles.AllowWhiteSpacesсоставной стиль, включающий DateTimeStyles.AllowLeadingWhiteDateTimeStyles.AllowTrailingWhiteфлаги , и DateTimeStyles.AllowInnerWhite флагиTryParse. ParseExact Для и TryParseExact методов используется DateTimeStyles.Noneзначение по умолчанию; входная строка должна точно соответствовать определенной пользовательской строке формата даты и времени.

Методы синтаксического анализа также неявно или явно используют DateTimeFormatInfo объект, определяющий определенные символы и шаблоны, которые могут возникать в строке для анализа. Если объект не указан DateTimeFormatInfo , DateTimeFormatInfo по умолчанию используется объект для текущего языка и региональных параметров. Дополнительные сведения о синтаксическом анализе строк даты и времени см. в отдельных методах синтаксического анализа, таких как DateTime.Parse, DateTime.TryParseи DateTimeOffset.ParseExactDateTimeOffset.TryParseExact.

В следующем примере показан характер анализа строк даты и времени с учетом языка и региональных параметров. Он пытается проанализировать две строки даты с помощью соглашений en-US, en-GB, fr-FR и fi-FI. Дата, интерпретируемая как 8.18.2014 в языке и региональных параметров en-US, вызывает FormatException исключение в других трех языках и региональных параметрах, так как 18 интерпретируется как номер месяца. 1/2.2015 анализируется как второй день первого месяца в культуре en-US, но как первый день второго месяца в остальных культурах.

using System;
using System.Globalization;

public class ParseEx1
{
    public static void Main()
    {
        string[] dateStrings = { "08/18/2014", "01/02/2015" };
        string[] cultureNames = { "en-US", "en-GB", "fr-FR", "fi-FI" };

        foreach (var cultureName in cultureNames)
        {
            CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
            Console.WriteLine("Parsing strings using the {0} culture.",
                              culture.Name);
            foreach (var dateStr in dateStrings)
            {
                try
                {
                    Console.WriteLine(String.Format(culture,
                                      "   '{0}' --> {1:D}", dateStr,
                                      DateTime.Parse(dateStr, culture)));
                }
                catch (FormatException)
                {
                    Console.WriteLine("   Unable to parse '{0}'", dateStr);
                }
            }
        }
    }
}
// The example displays the following output:
//       Parsing strings using the en-US culture.
//          '08/18/2014' --> Monday, August 18, 2014
//          '01/02/2015' --> Friday, January 02, 2015
//       Parsing strings using the en-GB culture.
//          Unable to parse '08/18/2014'
//          '01/02/2015' --> 01 February 2015
//       Parsing strings using the fr-FR culture.
//          Unable to parse '08/18/2014'
//          '01/02/2015' --> dimanche 1 février 2015
//       Parsing strings using the fi-FI culture.
//          Unable to parse '08/18/2014'
//          '01/02/2015' --> 1. helmikuuta 2015

Строки даты и времени обычно анализируются по двум причинам:

  • Преобразование входных данных пользователя в значение даты и времени.
  • Для обхода значения даты и времени; То есть для десериализации значения даты и времени, ранее сериализованного в виде строки.

В следующих разделах подробно рассматриваются эти две операции.

Анализ строк пользователей

При синтаксическом анализе строк даты и времени, введенных пользователем, всегда следует создать экземпляр DateTimeFormatInfo объекта, который отражает культурные параметры пользователя, включая любые настройки, которые пользователь мог сделать. В противном случае объект даты и времени может иметь неправильные значения. Сведения о создании экземпляра DateTimeFormatInfo объекта, который отражает пользовательские культурные настройки, см. в разделе DateTimeFormatInfo и динамических данных .

В следующем примере показано различие между операцией синтаксического анализа, которая отражает региональные параметры пользователя и ту, которая не соответствует. В этом случае системный язык и региональные параметры по умолчанию — en-US, но пользователь использовал панель управления, регион и язык для изменения шаблона короткой даты с значения по умолчанию "M/d/гггг" на "гггг/ММ/дд". Когда пользователь вводит строку, которая отражает параметры пользователя, и строка анализируется объектом, который также отражает параметры пользователя (переопределяет), операция синтаксического DateTimeFormatInfo анализа возвращает правильный результат. Однако при анализе строки объектом, который отражает стандартные региональные параметры en-US, метод синтаксического DateTimeFormatInfo анализа создает FormatException исключение, так как он интерпретирует 14 как число месяца, а не последние две цифры года.

using System;
using System.Globalization;

public class ParseEx2
{
    public static void Main()
    {
        string inputDate = "14/05/10";

        CultureInfo[] cultures = { CultureInfo.GetCultureInfo("en-US"),
                                 CultureInfo.CreateSpecificCulture("en-US") };

        foreach (var culture in cultures)
        {
            try
            {
                Console.WriteLine("{0} culture reflects user overrides: {1}",
                                  culture.Name, culture.UseUserOverride);
                DateTime occasion = DateTime.Parse(inputDate, culture);
                Console.WriteLine("'{0}' --> {1}", inputDate,
                                  occasion.ToString("D", CultureInfo.InvariantCulture));
            }
            catch (FormatException)
            {
                Console.WriteLine("Unable to parse '{0}'", inputDate);
            }
            Console.WriteLine();
        }
    }
}
// The example displays the following output:
//       en-US culture reflects user overrides: False
//       Unable to parse '14/05/10'
//
//       en-US culture reflects user overrides: True
//       '14/05/10' --> Saturday, 10 May 2014

Сериализация и десериализация данных даты и времени

Сериализованные данные даты и времени, как ожидается, будут циклизированы; То есть все сериализованные и десериализированные значения должны совпадать. Если значение даты и времени представляет один момент времени, десериализированное значение должно представлять тот же момент времени независимо от языка и региональных параметров или часового пояса системы, на которой она была восстановлена. Для успешного обхода данных даты и времени необходимо использовать соглашения инвариантного языка и региональных параметров, возвращаемых свойством InvariantInfo , для создания и анализа данных. Операции форматирования и синтаксического анализа никогда не должны отражать соглашения языка и региональных параметров по умолчанию. Если вы используете параметры культуры по умолчанию, переносимость данных строго ограничена; она может быть успешно десериализирована только в потоке, параметры которого соответствуют параметрам, зависящим от культуры, идентичным параметрам потока, на котором она была сериализована. В некоторых случаях это означает, что данные даже не могут быть успешно сериализованы и десериализированы в той же системе.

Если компонент времени значения даты и времени имеет значительное значение, его также следует преобразовать в формате UTC и сериализовать с помощью строки стандартного формата "o" или "r". Затем данные времени можно восстановить, вызвав метод синтаксического анализа и передавая соответствующую строку формата вместе с инвариантным языком и региональными параметрами в качестве аргумента provider .

В следующем примере показано, как обойти значение даты и времени. Она сериализует дату и время в системе, которая наблюдает время в США и текущий язык и региональные параметры en-US.

using System;
using System.Globalization;
using System.IO;

public class SerializeEx1
{
    public static void Main()
    {
        StreamWriter sw = new StreamWriter(@".\DateData.dat");
        // Define a date and time to serialize.
        DateTime originalDate = new DateTime(2014, 08, 18, 08, 16, 35);
        // Display information on the date and time.
        Console.WriteLine("Date to serialize: {0:F}", originalDate);
        Console.WriteLine("Current Culture:   {0}",
                          CultureInfo.CurrentCulture.Name);
        Console.WriteLine("Time Zone:         {0}",
                          TimeZoneInfo.Local.DisplayName);
        // Convert the date value to UTC.
        DateTime utcDate = originalDate.ToUniversalTime();
        // Serialize the UTC value.
        sw.Write(utcDate.ToString("o", DateTimeFormatInfo.InvariantInfo));
        sw.Close();
    }
}
// The example displays the following output:
//       Date to serialize: Monday, August 18, 2014 8:16:35 AM
//       Current Culture:   en-US
//       Time Zone:         (UTC-08:00) Pacific Time (US & Canada)

Он десериализирует данные о системе в Брюсселе, Копенгагене, Мадриде и Парижском часовом поясе, а текущая культура — fr-FR. Восстановленная дата составляет девять часов позже исходной даты, которая отражает корректировку часового пояса от восьми часов за utc до одного часа впереди UTC. Исходная дата и восстановленная дата представляют один и тот же момент времени.

using System;
using System.Globalization;
using System.IO;

public class SerializeEx2
{
    public static void Main()
    {
        // Open the file and retrieve the date string.
        StreamReader sr = new StreamReader(@".\DateData.dat");
        String dateValue = sr.ReadToEnd();

        // Parse the date.
        DateTime parsedDate = DateTime.ParseExact(dateValue, "o",
                              DateTimeFormatInfo.InvariantInfo);
        // Convert it to local time.
        DateTime restoredDate = parsedDate.ToLocalTime();
        // Display information on the date and time.
        Console.WriteLine("Deserialized date: {0:F}", restoredDate);
        Console.WriteLine("Current Culture:   {0}",
                          CultureInfo.CurrentCulture.Name);
        Console.WriteLine("Time Zone:         {0}",
                          TimeZoneInfo.Local.DisplayName);
    }
}
// The example displays the following output:
//    Deserialized date: lundi 18 août 2014 17:16:35
//    Current Culture:   fr-FR
//    Time Zone:         (UTC+01:00) Brussels, Copenhagen, Madrid, Paris