2009-02-03 20 views
65

Stavo giocando con il metodo Datetime.ParseExact e vuole un IFormatProvider ...Cosa fa IFormatProvider?

Funziona inserendo null, ma cosa fa esattamente?

+3

possibile duplicato di [Perché DateTime.ParseExact (String, String, IFormatProvider) ha bisogno di IFormatProvider?] (Http://stackoverflow.com/questions/18961520/why-datetime-parseexactstring-string-iformatprovider-need-the- iformatprovide). Sto votando per chiuderla con una più nuova perché è formulata meglio e ha una risposta migliore. – nawfal

risposta

41

Anche CultureInfo implementa questa interfaccia e può essere utilizzata nel tuo caso. Quindi potresti analizzare una stringa di date francese per esempio; si potrebbe usare

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

Non sembra esserci un sovraccarico che corrisponde più all'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)' –

+0

Aggiornerò la risposta :) –

1

La classe DateTimeFormatInfo implementa questa interfaccia, quindi consente di controllare la formattazione delle stringhe DateTime.

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 si trovano nelle pagine MSDN pertinenti.

14

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

Invece si dovrebbe 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 ragione per utilizzare 'CultureInfo.InvariantCulture' invece di' CultureInfo.CurrentCulture'? –

+4

InvariantCulture è una cultura speciale che è sempre garantita su qualsiasi macchina e che converte e analizza sempre agli stessi valori. CurrentCulture è la cultura del thread corrente. Questo può variare e se non si utilizza la stessa cultura per convertire in string e analizzare, si otterranno errori di formato ... – Tim

+5

@StephenBooher passando in 'null' verrà automaticamente impostato su' CultureInfo.CurrentCulture'. Vedere la chiamata nella [fonte di riferimento] (http://referencesource.microsoft.com/mscorlib/a.html#bfc8add12515d311), se si segue la catena di chiamate, il risultato finale viene sostituito con ['DateTimeFormatInfo.CurrentInfo' ] (http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.currentinfo (v = vs.110) .aspx) che equivale a ciò che produce "CultureInfo.CurrentCulture". –

29

L'interfaccia IFormatProvider viene normalmente implementato per voi da una classe CultureInfo, ad esempio:

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

L'interfaccia è un gateway per una funzione per ottenere un insieme di dati specifici di coltura da una coltura.Oggetti I due cultura comunemente disponibili che un IFormatProvider possono essere interrogati per sono:

  • DateTimeFormatInfo
  • NumberFormatInfo

Il modo in cui normalmente il lavoro è fare le IFormatProvider per darvi un oggetto DateTimeFormatInfo:

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

C'è anche dentro la conoscenza che qualsiasi IFormatProvider interfaccia è probabilmente in corso di attuazione da una classe che scende dal CultureInfo, o discende da DateTimeFormatInfo, così si potrebbe lanciare l'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 ha già stato scritto per voi:

per ottenere un DateTimeFormatInfo da un IFormatProvider:

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider); 

Per ottenere un NumberFormatInfo da un IFormatProvider:

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider); 

Il valore di IFormatProvider è che si creano i propri oggetti di cultura. Finché implementano IFormatProvider e restituiscono gli oggetti richiesti, è possibile ignorare le culture incorporate.

È inoltre possibile utilizzare IFormatProvider per un modo di passare oggetti di cultura arbitrari - tramite IFormatProvider. Per esempio. il nome di Dio nelle diverse culture

  • dio
  • Dio
  • Geova
  • Yahwe
  • יהוה
  • אהיה אשר אהיה

In questo modo la vostra abitudine LordsNameFormatInfo giro di classe insieme all'interno di un IFormatProvider, ed è possibile conservare t lui idioma.

In realtà non sarà mai necessario chiamare il metodo GetFormat di IFormatProvider.

Ogni volta che avete bisogno di un IFormatProvider è possibile passare un oggetto CultureInfo:

DateTime.Now.ToString(CultureInfo.CurrentCulture); 

endTime.ToString(CultureInfo.InvariantCulture); 

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

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

2

Con MSDN

.NET Framework comprende le seguenti tre implementazioni IFormatProvider predefiniti per fornire informazioni specifiche coltura che viene utilizzato nella formattazione o parsing valori numerici e di data e ora:

  1. La classe NumberFormatInfo, che fornisce informazioni utilizzate per formattare numeri, ad esempio la valuta, il separatore di migliaia e i separatori decimali per una particolare cultura. Per informazioni sulle stringhe di formato predefinite riconosciute da un oggetto NumberFormatInfo e utilizzate nelle operazioni di formattazione numerica, vedere Stringhe di formato numerico standard e stringhe di formato numerico personalizzato.
  2. La classe DateTimeFormatInfo, che fornisce informazioni utilizzate per formattare date e ore, ad esempio i simboli di separatori di data e ora per una particolare cultura o l'ordine e il formato dei componenti di anno, mese e giorno di una data. Per informazioni sulle stringhe di formato predefinite riconosciute da un oggetto DateTimeFormatInfo 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 classe CultureInfo, che rappresenta una particolare cultura. Il suo metodo GetFormat restituisce un oggetto specifico per la cultura NumberFormatInfo o DateTimeFormatInfo, a seconda che l'oggetto CultureInfo sia utilizzato in un'operazione di formattazione o di analisi che coinvolge numeri o date e ore.

.NET Framework supporta anche la formattazione personalizzata. Questo in genere comporta 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[]).