Was macht IFormatProvider?

93

Ich habe mit der Datetime.ParseExact-Methode herumgespielt und sie möchte einen IFormatProvider ...

Es funktioniert mit der Eingabe von Null, aber was genau macht es?

Moulde
quelle
3
Mögliches Duplikat von Warum DateTime.ParseExact (String, String, IFormatProvider) den IFormatProvider benötigt? . Ich stimme dafür, mit einem neueren zu schließen, weil es besser formuliert ist und eine bessere Antwort hat.
Nawfal

Antworten:

61

Zusätzlich zu Ian Boyds Antwort:

Auch CultureInfoimplementiert diese Schnittstelle und kann in Ihrem Fall verwendet werden. So können Sie beispielsweise eine französische Datumszeichenfolge analysieren. Du könntest benutzen

var ci = new CultureInfo("fr-FR");
DateTime dt = DateTime.ParseExact(yourDateInputString, yourFormatString, ci);
Andrei Rînea
quelle
2
In .NET Framework 4.6 scheint es keine Überlastung mehr zu geben, die Ihrem Beispiel entspricht. Sie müssen DateTime.ParseExact(string, string, IFormatProvider)stattdessen verwenden, ich glaube - als solches: DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
James King
1
In .NET Framework 4.6.2 gibt es keine Eingabeparameter, wie Sie zeigen. Ich benutze nur zwei und es funktioniert gut DateTime dt = DateTime.Parse(yourDateInputString, ci);Bitte überarbeiten Sie Ihre Antwort.
Entwickler
1
Sorry Leute, meine Antwort wurde längst überfällig aktualisiert.
Andrei Rînea
49

Die IFormatProviderSchnittstelle wird normalerweise von einer CultureInfoKlasse für Sie implementiert , z.

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

Die Schnittstelle ist ein Gateway für eine Funktion zum Abrufen eines Satzes kulturspezifischer Daten aus einer Kultur. Die zwei allgemein verfügbaren Kulturobjekte, IFormatProvidernach denen abgefragt werden kann, sind:

Normalerweise funktioniert es so, dass Sie den bitten IFormatProvider, Ihnen ein DateTimeFormatInfoObjekt zu geben :

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

Es gibt auch Insiderwissen, dass jede IFormatProviderSchnittstelle wahrscheinlich von einer Klasse implementiert wird, die von CultureInfooder absteigt DateTimeFormatInfo, sodass Sie die Schnittstelle direkt umwandeln können:

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

Aber tu das nicht

All diese harte Arbeit wurde bereits für Sie geschrieben:

So erhalten Sie eine DateTimeFormatInfovonIFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

So erhalten Sie eine NumberFormatInfovonIFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

Der Wert von IFormatProviderist, dass Sie Ihre eigenen Kulturobjekte erstellen. Solange sie IFormatProviderObjekte implementieren und zurückgeben, nach denen sie gefragt werden, können Sie die integrierten Kulturen umgehen.

Sie können auch IFormatProviderbeliebige Kulturobjekte weiterleiten - durch die IFormatProvider. ZB der Name Gottes in verschiedenen Kulturen

  • Gott
  • Gott
  • Jehova
  • Jahwe
  • יהוה
  • אהיה אשר אהיה

Auf diese Weise kann Ihre benutzerdefinierte LordsNameFormatInfoKlasse in einem mitfahren IFormatProvider, und Sie können die Redewendung beibehalten.

In Wirklichkeit müssen Sie niemals die GetFormatMethode Ihrer IFormatProviderselbst aufrufen .

Wann immer Sie eine benötigen IFormatProvider, können Sie ein CultureInfoObjekt übergeben:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

Hinweis : Jeder Code wird öffentlich zugänglich gemacht. Keine Zuordnung erforderlich.

Ian Boyd
quelle
18

Das Übergeben von null als IFormatProviderist nicht der richtige Weg, dies zu tun. Wenn der Benutzer ein benutzerdefiniertes Datums- / Uhrzeitformat auf seinem PC hat, treten Probleme beim Parsen und Konvertieren in Zeichenfolgen auf. Ich habe gerade einen Fehler behoben, bei dem jemand beim Konvertieren in einen String null als IFormatProvider übergeben hatte.

Stattdessen sollten Sie verwenden CultureInfo.InvariantCulture

Falsch:

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

Richtig:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", CultureInfo.InvariantCulture);
Tim
quelle
2
Gibt es einen Grund, den wir CultureInfo.InvariantCultureanstelle von verwenden sollten CultureInfo.CurrentCulture?
Stephen Booher
5
InvariantCulture ist eine spezielle Kultur, die garantiert immer auf jedem Computer vorhanden ist und immer dieselben Werte konvertiert und zurückspielt. CurrentCulture ist die Kultur des aktuellen Threads. Dies kann variieren und wenn Sie nicht die gleiche Kultur zum Konvertieren in String und Parse verwenden, erhalten Sie Formatfehler ...
Tim
5
@StephenBooher nullwird standardmäßig übergeben CultureInfo.CurrentCulture. Siehe den Aufruf in der Referenzquelle . Wenn Sie der Aufrufkette folgen, wird die Null schließlich durch DateTimeFormatInfo.CurrentInfodie ersetzt, die den CultureInfo.CurrentCultureAusgaben entspricht.
Scott Chamberlain
InvariantCulture ist das, wonach ich gesucht habe. Danke
Chicowitz
5

IFormatProvider bietet Kulturinformationen zu der betreffenden Methode. DateTimeFormatInfo implementiert IFormatProvider und ermöglicht es Ihnen, das Format anzugeben, in dem Datum und Uhrzeit angezeigt werden sollen. Beispiele finden Sie auf den entsprechenden MSDN-Seiten.

Raithlin
quelle
2

Von MSDN

Das .NET Framework enthält die folgenden drei vordefinierten IFormatProvider-Implementierungen, um kulturspezifische Informationen bereitzustellen, die beim Formatieren oder Parsen von numerischen Werten sowie Datums- und Zeitwerten verwendet werden:

  1. Die NumberFormatInfoKlasse, die Informationen bereitstellt, die zum Formatieren von Zahlen verwendet werden, z. B. die Symbole für Währung, Tausendertrennzeichen und Dezimaltrennzeichen für eine bestimmte Kultur. Informationen zu den vordefinierten Formatzeichenfolgen, die von einem NumberFormatInfoObjekt erkannt und in numerischen Formatierungsvorgängen verwendet werden, finden Sie unter Standardzeichenfolgen für numerische Formate und Zeichenfolgen für benutzerdefinierte numerische Formate .
  2. Die DateTimeFormatInfoKlasse, die Informationen bereitstellt, die zum Formatieren von Datum und Uhrzeit verwendet werden, z. B. die Datums- und Zeittrennzeichen für eine bestimmte Kultur oder die Reihenfolge und das Format der Jahres-, Monats- und Tageskomponenten eines Datums. Informationen zu den vordefinierten Formatzeichenfolgen, die von einem DateTimeFormatInfoObjekt erkannt und in numerischen Formatierungsvorgängen verwendet werden, finden Sie unter Standard-Formatzeichenfolgen für Datum und Uhrzeit sowie Benutzerdefinierte Zeichenfolgen für Datums- und Zeitformat.
  3. Die CultureInfoKlasse, die eine bestimmte Kultur repräsentiert. Seine GetFormatMethode gibt eine kulturspezifische NumberFormatInfooder DateTimeFormatInfoObjekt, je nachdem , ob das CultureInfoObjekt in einer Formatierung oder Parsen Operation verwendet wird , die Zahlen oder Datumsangaben und Zeiten beinhaltet.

Das .NET Framework unterstützt auch benutzerdefinierte Formatierungen. Dies beinhaltet normalerweise die Erstellung einer Formatierungsklasse, die sowohl IFormatProvider als auch ICustomFormatter implementiert. Eine Instanz dieser Klasse wird dann als Parameter an eine Methode übergeben, die eine benutzerdefinierte Formatierungsoperation ausführt, z String.Format(IFormatProvider, String, Object[]).

Große Augen
quelle
1

Die DateTimeFormatInfo- Klasse implementiert diese Schnittstelle, sodass Sie die Formatierung Ihrer DateTime-Zeichenfolgen steuern können.

Gerrie Schenck
quelle