Использование инвариантной культуры с IFormatProvider в DateTime.ParseExact

В Первой перегрузке метода ParseExact

public static DateTime ParseExact (string s, string format, IFormatProvider provider);

по словам Microsoft:

Если формат представляет собой шаблон пользовательского формата, который не включает разделители даты или времени (например, "yyyyMMddHHmm"), используйте инвариантную культуру для параметра провайдера и самую широкую форму каждого спецификатора пользовательского формата. Например, если вы хотите указать часы в шаблоне формата, укажите более широкую форму "HH" вместо более узкой формы "H".

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

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

2 ответа

Цель InvariantCulture должен иметь хорошо известный способ форматирования дат и чисел, который не зависит от системы или языкового стандарта пользователя.

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


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

// omitting CultureInfo.InvariantCulture for brevity
var dt = new DateTime(2018,1,2,3,45,6);
dt.ToString("yyyyMMddHHmmss") // returns "20180102034506"
dt.ToString("yyyyMdHms")      // returns "2018123456"

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

Настоящая цель инвариантной культуры взята из ответа на этот вопрос, так как он лучше всего описывает ее цель:

Не все культуры используют один и тот же формат для дат и десятичных значений / значений валют.

Это будет иметь значение для вас, когда вы конвертируете входные значения (чтение), которые хранятся в виде строк, в DateTime, float, double или decimal. Также имеет значение, если вы попытаетесь отформатировать вышеупомянутые типы данных в строки (запись) для отображения или хранения.

Если вы знаете, в какой конкретной культуре будут находиться ваши даты и десятичные значения / значения валют, вы можете использовать это конкретное свойство CultureInfo (то есть CultureInfo("en-GB")). Например, если вы ожидаете ввода пользователя.

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

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

самый широкий пользовательский спецификатор

значит этим.

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