Co robi IFormatProvider?

Odpowiedzi:

62

W uzupełnieniu do odpowiedzi Iana Boyda:

CultureInfoImplementuje również ten interfejs i może być używany w twoim przypadku. Na przykład można przeanalizować francuski łańcuch daty; mógłbyś użyć

var ci = new CultureInfo("fr-FR");
DateTime dt = DateTime.ParseExact(yourDateInputString, yourFormatString, ci);
Andrei Rînea
źródło
2
Wygląda na to, że nie ma już przeciążenia, które pasowałoby do Twojego przykładu w .NET Framework 4.6. DateTime.ParseExact(string, string, IFormatProvider)Uważam, że zamiast tego należy użyć : DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
James King
1
W .NET Framework 4.6.2 nie ma żadnych parametrów wejściowych, jak wskazujesz. Używam tylko dwóch i działa dobrze. DateTime dt = DateTime.Parse(yourDateInputString, ci);Popraw odpowiedź.
DmitryBoyko
1
Przepraszam, moja odpowiedź była bardzo spóźniona.
Andrei Rînea
49

IFormatProviderInterfejs jest zazwyczaj realizowane za ciebie przez CultureInfoklasy, np:

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

Interfejs jest bramą dla funkcji, która pobiera zestaw danych specyficznych dla kultury z kultury. Dwa powszechnie dostępne obiekty kultury, o które IFormatProvidermożna zapytać, to:

Sposób, w jaki normalnie by działał, polega na tym, że prosisz IFormatProvidero DateTimeFormatInfoprzedmiot:

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

Istnieje również wewnętrzna wiedza, że ​​każdy IFormatProviderinterfejs jest prawdopodobnie implementowany przez klasę, która pochodzi CultureInfolub pochodzi z DateTimeFormatInfo, więc możesz rzutować interfejs bezpośrednio:

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);

Ale nie rób tego

Cała ta ciężka praca została już dla Ciebie napisana:

Aby otrzymać DateTimeFormatInfoodIFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

Aby otrzymać NumberFormatInfoodIFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

Wartość IFormatProviderpolega na tym, że tworzysz własne obiekty kultury. Dopóki implementują IFormatProvideri zwracają obiekty, o które są proszone, można ominąć kultury wbudowane.

Możesz również użyć IFormatProviderdo przekazywania dowolnych obiektów kultury - przez IFormatProvider. Np. Imię boga w różnych kulturach

  • Bóg
  • Bóg
  • Jehova
  • Jahwe
  • יהוה
  • אהיה אשר אהיה

Dzięki temu Twoja niestandardowa LordsNameFormatInfoklasa jedzie w środku IFormatProvideri możesz zachować idiom.

W rzeczywistości nigdy nie będziesz musiał nazywać własnej GetFormatmetody IFormatProvider.

Zawsze, gdy potrzebujesz IFormatProvider, możesz przekazać CultureInfoobiekt:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

Uwaga : każdy kod jest udostępniany w domenie publicznej. Nie jest wymagane podanie źródła.

Ian Boyd
źródło
18

Podanie wartości null, ponieważ IFormatProvidernie jest właściwym sposobem, aby to zrobić. Jeśli użytkownik ma niestandardowy format daty / czasu na swoim komputerze, będziesz mieć problemy z analizowaniem i konwersją na ciąg. Właśnie naprawiłem błąd, w którym ktoś przekazał wartość null jako IFormatProvider podczas konwersji na ciąg.

Zamiast tego powinieneś używać CultureInfo.InvariantCulture

Źle:

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

Poprawny:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", CultureInfo.InvariantCulture);
Tim
źródło
2
Czy jest jakiś powód, dla którego powinniśmy używać CultureInfo.InvariantCulturezamiast CultureInfo.CurrentCulture?
Stephen Booher
5
InvariantCulture to specjalna kultura, która zawsze istnieje na dowolnej maszynie i zawsze będzie konwertować i analizować z powrotem do tych samych wartości. CurrentCulture jest kulturą bieżącego wątku. Może się to różnić i jeśli nie użyjesz tej samej kultury do konwersji na ciąg i parsowania, otrzymasz błędy formatu ...
Tim
5
@StephenBooher przekazanie nullbędzie domyślnie CultureInfo.CurrentCulture. Zobacz wywołanie w źródle odniesienia , jeśli podążasz za łańcuchem wywołań, wartość null ostatecznie zostanie zastąpiona przez, DateTimeFormatInfo.CurrentInfoco jest równoważne z danymi CultureInfo.CurrentCulturewyjściowymi.
Scott Chamberlain
InvariantCulture jest tym, czego szukałem. Dzięki
Chicowitz,
5

IFormatProvider udostępnia informacje o kulturze do danej metody. DateTimeFormatInfo implementuje IFormatProvider i umożliwia określenie formatu, w jakim ma być wyświetlana data / godzina. Przykłady można znaleźć na odpowiednich stronach MSDN.

Raithlin
źródło
2

Przez MSDN

NET Framework zawiera następujące trzy predefiniowane implementacje IFormatProvider, które zapewniają informacje specyficzne dla kultury, które są używane w formatowaniu lub analizowaniu wartości liczbowych oraz wartości daty i godziny:

  1. NumberFormatInfoKlasa, która dostarcza informacji, która jest używana do formatowania liczb, takich jak waluty, tysiące separatora i symboli separator dziesiętny dla danej kultury. Aby uzyskać informacje na temat wstępnie zdefiniowanych ciągów formatu rozpoznawanych przez NumberFormatInfoobiekt i używanych w operacjach formatowania liczb, zobacz Standardowe ciągi formatujące liczby i Niestandardowe ciągi formatujące.
  2. DateTimeFormatInfoKlasa, która dostarcza informacji, która jest używana do formatowania dat i czasów, takich jak data i godzina symboli Separator określonej kultury lub kolejności i formy komponentów rok, miesiąc i dzień na randkę. Aby uzyskać informacje o wstępnie zdefiniowanych ciągach formatu rozpoznawanych przez plikDateTimeFormatInfo obiekt i używanych w operacjach formatowania liczbowego, zobacz standardowe formatujące datę i godzinę oraz niestandardowe ciągi formatujące datę i godzinę.
  3. CultureInfoKlasa, która stanowi szczególną kulturę. Jego GetFormatmetoda zwraca obiekt specyficzny dla kultury NumberFormatInfolub DateTimeFormatInfoobiekt, w zależności od tego, czy CultureInfoobiekt jest używany w operacji formatowania lub analizowania, która obejmuje liczby lub daty i godziny.

NET Framework obsługuje również formatowanie niestandardowe. Zwykle wiąże się to z utworzeniem klasy formatowania, która implementuje zarówno IFormatProvider, jak i ICustomFormatter. Wystąpienie tej klasy jest następnie przekazywane jako parametr do metody, która wykonuje niestandardową operację formatowania, taką jak String.Format(IFormatProvider, String, Object[]).

Duże oczy
źródło
1

W DateTimeFormatInfo klasa implementuje ten interfejs, dzięki czemu pozwala kontrolować formatowanie ciągów DateTime.

Gerrie Schenck
źródło