Что делает 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 для предоставления специфичной для культуры информации, которая используется при форматировании или анализе числовых значений, а также значений даты и времени:
NumberFormatInfo
класс, который предоставляет информацию, используемую для форматирования чисел, такую как валюта, разделитель тысяч и символы десятичного разделителя для конкретной культуры. Для получения информации о предопределенных строках формата, распознаваемыхNumberFormatInfo
объект и используется в операциях форматирования чисел, см. Строки стандартного числового формата и Строки настраиваемого числового формата.DateTimeFormatInfo
класс, который предоставляет информацию, используемую для форматирования даты и времени, такую как символы разделителя даты и времени для конкретной культуры или порядок и формат компонентов даты, года, месяца и дня. Для получения информации о предопределенных строках формата, распознаваемыхDateTimeFormatInfo
объект и используется в операциях форматирования чисел, см. Стандартные строки формата даты и времени и Пользовательские строки формата даты и времени.CultureInfo
класс, который представляет определенную культуру. этоGetFormat
метод возвращает специфичный для культурыNumberFormatInfo
или жеDateTimeFormatInfo
объект, в зависимости от того, является лиCultureInfo
Объект используется в операции форматирования или синтаксического анализа, которая включает числа или даты и время.
.NET Framework также поддерживает пользовательское форматирование. Обычно это включает создание класса форматирования, который реализует IFormatProvider и ICustomFormatter. Экземпляр этого класса затем передается в качестве параметра методу, который выполняет пользовательскую операцию форматирования, такую как String.Format(IFormatProvider, String, Object[])
,
Проверьте http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx для API.
Вопрос касается 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.