Cosa fa IFormatProvider?


Risposte:


61

In aggiunta alla risposta di Ian Boyd:

CultureInfoImplementa anche questa interfaccia e può essere utilizzata nel tuo caso. Quindi potresti analizzare una stringa di data francese, ad esempio; potresti usare

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

2
Non sembra più esserci un sovraccarico che corrisponde al tuo esempio in .NET Framework 4.6. Devi usare DateTime.ParseExact(string, string, IFormatProvider)invece, credo - come tale: DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
James King

1
In .NET Framework 4.6.2 non sono presenti parametri di input al momento del puntamento. Ne uso solo due e funziona bene DateTime dt = DateTime.Parse(yourDateInputString, ci);. Rivedi la tua risposta.
Sviluppatore

1
Scusate ragazzi, è stato fatto un aggiornamento atteso da tempo alla mia risposta.
Andrei Rînea

49

L' IFormatProviderinterfaccia è normalmente implementata per te da una CultureInfoclasse, ad esempio:

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

L'interfaccia è un gateway per una funzione per ottenere un set di dati specifici delle impostazioni cultura da una cultura. I due oggetti cultura comunemente disponibili per i quali è IFormatProviderpossibile eseguire query sono:

Il modo in cui normalmente funzionerebbe è che chiedi IFormatProvidera te di darti un DateTimeFormatInfooggetto:

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

C'è anche la consapevolezza che qualsiasi IFormatProviderinterfaccia è probabilmente implementata da una classe che discende CultureInfoo discende da DateTimeFormatInfo, quindi puoi eseguire il cast dell'interfaccia direttamente:

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

Ma non farlo

Tutto quel duro lavoro è già stato scritto per te:

Per ottenere un DateTimeFormatInfoda unIFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

Per ottenere un NumberFormatInfoda unIFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

Il valore di IFormatProviderè che crei i tuoi oggetti culturali. Finché implementano IFormatProvidere restituiscono gli oggetti richiesti, puoi ignorare le impostazioni cultura incorporate.

Puoi anche usare IFormatProvider per passare oggetti cultura arbitrari - attraverso il file IFormatProvider. Ad esempio il nome di dio in culture diverse

  • Dio
  • Dio
  • Jehova
  • Yahwe
  • יהוה
  • אהיה אשר אהיה

Ciò consente alla tua LordsNameFormatInfoclasse personalizzata di viaggiare all'interno di un fileIFormatProvider e puoi preservare l'idioma.

In realtà non avrai mai bisogno di chiamare il GetFormatmetodo diIFormatProvider te stesso.

Ogni volta che ne hai bisogno IFormatProviderpuoi passare un CultureInfooggetto:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

Nota : qualsiasi codice viene rilasciato nel pubblico dominio. Nessuna attribuzione richiesta.


18

Passando null come il IFormatProvider non è il modo corretto per farlo. Se l'utente ha un formato data / ora personalizzato sul proprio PC, si avranno problemi nell'analisi e nella conversione in stringa. Ho appena corretto un bug in cui qualcuno aveva passato null come IFormatProvider durante la conversione in stringa.

Invece dovresti usare CultureInfo.InvariantCulture

Sbagliato:

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

Corretta:

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

2
C'è qualche motivo che dovremmo usare al CultureInfo.InvariantCultureposto di CultureInfo.CurrentCulture?
Stephen Booher

5
InvariantCulture è una cultura speciale di cui è garantito che esista sempre su qualsiasi macchina e che convertirà e analizzerà sempre gli stessi valori. CurrentCulture è la cultura del thread corrente. Questo può variare e se non usi la stessa cultura per convertire in stringa e analizzare, otterrai errori di formato ...
Tim

5
@StephenBooher che passa per nullimpostazione predefinita CultureInfo.CurrentCulture. Vedi la chiamata nella fonte di riferimento , se segui la catena di chiamate, il null alla fine viene sostituito con DateTimeFormatInfo.CurrentInfoche è equivalente a ciò che CultureInfo.CurrentCultureproduce.
Scott Chamberlain,

InvariantCulture è quello che stavo cercando. Grazie
Chicowitz

5

IFormatProvider fornisce informazioni sulla cultura al metodo in questione. DateTimeFormatInfo implementa IFormatProvider e consente di specificare il formato in cui si desidera visualizzare la data / ora. Gli esempi sono disponibili nelle pagine MSDN pertinenti.




2

Di MSDN

.NET Framework include le seguenti tre implementazioni IFormatProvider predefinite per fornire informazioni specifiche delle impostazioni cultura utilizzate nella formattazione o nell'analisi di valori numerici e di data e ora:

  1. La NumberFormatInfoclasse, che fornisce le informazioni utilizzate per formattare i numeri, come la valuta, il separatore delle migliaia e i simboli del separatore decimale per una determinata lingua. Per informazioni sulle stringhe di formato predefinite riconosciute da un NumberFormatInfooggetto e utilizzate nelle operazioni di formattazione numerica, vedere Stringhe di formato numerico standard e Stringhe di formato numerico personalizzate.
  2. La DateTimeFormatInfoclasse, che fornisce le informazioni utilizzate per formattare le date e le ore, come i simboli di separazione della data e dell'ora per una determinata lingua o l'ordine e il formato dei componenti anno, mese e giorno di una data. Per informazioni sulle stringhe di formato predefinite riconosciute da un fileDateTimeFormatInfo oggetto e utilizzate nelle operazioni di formattazione numerica, vedere stringhe di formato di data e ora standard e stringhe di formato di data e ora personalizzate.
  3. La CultureInfoclasse, che rappresenta una cultura particolare. Il relativo GetFormatmetodo restituisce un oggetto NumberFormatInfoo una specifica delle impostazioni cultura DateTimeFormatInfo, a seconda che l' CultureInfooggetto venga utilizzato in un'operazione di formattazione o analisi che coinvolge numeri o date e ore.

.NET Framework supporta anche la formattazione personalizzata. Ciò implica in genere la creazione di una classe di formattazione che implementa sia IFormatProvider che ICustomFormatter. Un'istanza di questa classe viene quindi passata come parametro a un metodo che esegue un'operazione di formattazione personalizzata, ad esempio String.Format(IFormatProvider, String, Object[]).


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.