Что делает IFormatProvider?

Я играл с методом Datetime.ParseExact, и он хочет IFormatProvider...

Он работает, вводя ноль, но что именно он делает?

9 ответов

Решение

В дополнение к ответу Яна Бойда:

Также CultureInfo реализует этот интерфейс и может быть использован в вашем случае. Таким образом, вы можете проанализировать французскую строку даты, например; вы могли бы использовать

var ci = new CultureInfo("fr-FR");
DateTime dt = DateTime.ParseExact(yourDateInputString, yourFormatString, ci);

IFormatProvider интерфейс обычно реализуется для вас CultureInfo класс, например:

  • CultureInfo.CurrentCulture
  • CultureInfo.CurrentUICulture
  • CultureInfo.InvariantCulture
  • CultureInfo.CreateSpecificCulture("de-CA") //German (Canada)

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

  • DateTimeFormatInfo
  • NumberFormatInfo

Как это обычно работает, вы спрашиваете IFormatProvider чтобы дать вам DateTimeFormatInfo объект:

DateTimeFormatInfo format;
format = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo));
if (format != null)
   DoStuffWithDatesOrTimes(format);

Там также внутри знания, что любой IFormatProvider Интерфейс, вероятно, реализуется классом, который происходит от CultureInfo или происходит от DateTimeFormatInfo, так что вы можете привести интерфейс напрямую:

CultureInfo info = provider as CultureInfo;
if (info != null)
   format = info.DateTimeInfo;
else
{
   DateTimeFormatInfo dtfi = provider as DateTimeFormatInfo;
   if (dtfi != null)
       format = dtfi;
   else
       format = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo));
}

if (format != null)
   DoStuffWithDatesOrTimes(format);

Но не делай этого

Вся эта тяжелая работа уже написана для вас:

Чтобы получить DateTimeFormatInfo из IFormatProvider:

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

Чтобы получить NumberFormatInfo из IFormatProvider:

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

Значение IFormatProvider является то, что вы создаете свои собственные объекты культуры. Пока они реализуют IFormatProvider и возвращая запрашиваемые объекты, вы можете обойти встроенные культуры.

Вы также можете использовать IFormatProvider для способа прохождения произвольных объектов культуры - через IFormatProvider, Например, имя бога в разных культурах

  • Бог
  • Бог
  • Jehova
  • Яхве
  • יהוה
  • אהיה אשר אהיה

Это позволяет вашему обычаю LordsNameFormatInfo классная прогулка внутри IFormatProvider и вы можете сохранить идиому.

На самом деле вам никогда не понадобится звонить GetFormat метод IFormatProvider сам.

Всякий раз, когда вам нужно IFormatProvider Вы можете передать CultureInfo объект:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

transactionID.toString(CultureInfo.CreateSpecificCulture("qps-ploc"));

Примечание. Любой код публикуется в открытом доступе. Атрибуция не требуется.

Проходя ноль как IFormatProvider это не правильный способ сделать это. Если у пользователя есть пользовательский формат даты / времени на его ПК, у вас будут проблемы при разборе и преобразовании в строку. Я только что исправил ошибку, когда кто-то передавал null как IFormatProvider при преобразовании в строку.

Вместо этого вы должны использовать CultureInfo.InvariantCulture

Неправильно:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", null);

Правильный:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", CultureInfo.InvariantCulture);

Вы можете увидеть здесь http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx

Смотрите примечания и пример раздела там.

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

По MSDN

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

  1. NumberFormatInfo класс, который предоставляет информацию, используемую для форматирования чисел, такую ​​как валюта, разделитель тысяч и символы десятичного разделителя для конкретной культуры. Для получения информации о предопределенных строках формата, распознаваемых NumberFormatInfo объект и используется в операциях форматирования чисел, см. Строки стандартного числового формата и Строки настраиваемого числового формата.
  2. DateTimeFormatInfo класс, который предоставляет информацию, используемую для форматирования даты и времени, такую ​​как символы разделителя даты и времени для конкретной культуры или порядок и формат компонентов даты, года, месяца и дня. Для получения информации о предопределенных строках формата, распознаваемых DateTimeFormatInfo объект и используется в операциях форматирования чисел, см. Стандартные строки формата даты и времени и Пользовательские строки формата даты и времени.
  3. CultureInfo класс, который представляет определенную культуру. это GetFormat метод возвращает специфичный для культуры NumberFormatInfo или же DateTimeFormatInfo объект, в зависимости от того, является ли CultureInfo Объект используется в операции форматирования или синтаксического анализа, которая включает числа или даты и время.

.NET Framework также поддерживает пользовательское форматирование. Обычно это включает создание класса форматирования, который реализует IFormatProvider и ICustomFormatter. Экземпляр этого класса затем передается в качестве параметра методу, который выполняет пользовательскую операцию форматирования, такую ​​как String.Format(IFormatProvider, String, Object[]),

Вопрос касается IFormatProvider и DateTime, но вы можете использовать IFormatProvider и в других контекстах .NET, например для string.Format.

Затем вы передаете экземпляр IFormatProvider и можете, реализуя IFormatProvider, указать, как строка форматируется для объекта. Таким образом, использование IFormatProvider и связанного с ним интерфейса ICustomFormatter в .NET шире, чем только для дат.

Например, рассмотрим эту реализацию:

      using System;

namespace ConsoleApp
{
    class EmployeeProductivityFormatProvider : IFormatProvider, ICustomFormatter
    {
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            int rating = (int)arg;

            if (rating == 0)
            {
                return $"{rating} (new employee)";
            }

            if (rating > 0)
            {
                return $"{rating} (good employee)";
            }

            return $"{rating} (bad employee)";
        }

        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter))
            {
                return this;
            }

            return null;
        }
    }
}

Теперь мы можем получить строковое представление сотрудника, указав значение типа int следующим образом:

          string prod = string.Format(new EmployeeProductivityFormatProvider(),
                                "Productivity rating: {0}",
                                employee.ProductivityRating);

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

Класс DateTimeFormatInfo реализует этот интерфейс, поэтому он позволяет вам контролировать форматирование строк DateTime.

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