106 votes

Que fait IFormatProvider ?

Je me suis amusé avec la méthode Datetime.ParseExact, et il faut un IFormatProvider...

Il fonctionne en saisissant null, mais que fait-il exactement ?

3 votes

Duplicata possible de Pourquoi DateTime.ParseExact(String, String, IFormatProvider) a-t-il besoin de l'IFormatProvider ? . Je vote pour conclure avec un plus récent parce qu'il est mieux formulé et a une meilleure réponse.

70voto

Andrei Rînea Points 7554

En plus de la réponse de Ian Boyd :

Aussi CultureInfo implémente cette interface et peut être utilisé dans votre cas. Ainsi, vous pourriez analyser une chaîne de date française par exemple ; vous pourriez utiliser

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

4 votes

Il ne semble plus y avoir de surcharge correspondant à votre exemple dans le .NET Framework 4.6. Vous devez utiliser DateTime.ParseExact(string, string, IFormatProvider) plutôt, je crois - comme tel : DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)

1 votes

Dans .NET Framework 4.6.2, il n'y a pas de paramètres d'entrée comme vous l'indiquez. J'en utilise seulement deux et cela fonctionne bien DateTime dt = DateTime.Parse(yourDateInputString, ci); Veuillez réviser votre réponse.

2 votes

Désolé les gars, une mise à jour attendue depuis longtemps a été faite à ma réponse.

53voto

Ian Boyd Points 50743

El IFormatProvider est normalement implémentée pour vous par une CultureInfo classe, par exemple :

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

L'interface est une passerelle permettant à une fonction d'obtenir un ensemble de données spécifiques à une culture. Les deux objets de culture communément disponibles qu'une IFormatProvider peuvent être interrogés sont :

Normalement, vous devez demander à l'équipe de la IFormatProvider pour vous donner un DateTimeFormatInfo objet :

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

Il y a aussi une connaissance interne que tout IFormatProvider est probablement implémentée par une classe qui descend de l'interface CultureInfo ou descend de DateTimeFormatInfo Vous pouvez donc lancer l'interface directement :

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

Mais ne faites pas ça.

Tout ce travail difficile a déjà été écrit pour vous :

Pour obtenir un DateTimeFormatInfo d'un IFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

Pour obtenir un NumberFormatInfo d'un IFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

La valeur de IFormatProvider est que vous créez vos propres objets culturels. Tant qu'ils mettent en œuvre IFormatProvider et renvoient les objets qui leur sont demandés, vous pouvez contourner les cultures intégrées.

Vous pouvez également utiliser IFormatProvider pour un moyen de faire passer des objets culturels arbitraires - par le biais de la IFormatProvider . Par exemple, le nom de Dieu dans différentes cultures.

  • dieu
  • Dieu
  • Jehova
  • Yahwe

Cela permet à vos LordsNameFormatInfo de la classe à l'intérieur d'un IFormatProvider et vous pouvez préserver l'idiome.

En réalité, vous n'aurez jamais besoin d'appeler GetFormat méthode de IFormatProvider vous-même.

Chaque fois que vous avez besoin d'un IFormatProvider vous pouvez passer un CultureInfo objet :

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

Nota : Tout code est libéré dans le domaine public. Aucune attribution n'est requise.

20voto

Jim Points 2316

Le passage de null comme IFormatProvider n'est pas la bonne façon de procéder. Si l'utilisateur a un format de date et d'heure personnalisé sur son PC, vous aurez des problèmes d'analyse et de conversion en chaîne. Je viens de corriger un bug où quelqu'un avait passé null comme IFormatProvider lors de la conversion en chaîne de caractères.

Vous devriez plutôt utiliser CultureInfo.InvariantCulture

Faux :

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

Correct :

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

2 votes

Y a-t-il une raison pour laquelle nous devrions utiliser CultureInfo.InvariantCulture au lieu de CultureInfo.CurrentCulture ?

5 votes

InvariantCulture est une culture spéciale qui est garantie d'exister toujours sur n'importe quelle machine et qui convertira et analysera toujours les mêmes valeurs. CurrentCulture est la culture du thread actuel. Elle peut varier et si vous n'utilisez pas la même culture pour convertir en chaîne et analyser, vous obtiendrez des erreurs de format...

5 votes

@StephenBooher qui passe à l'action null sera par défaut CultureInfo.CurrentCulture . Voir l'appel dans le source de référence si vous suivez la chaîne d'appels, le null est finalement remplacé par DateTimeFormatInfo.CurrentInfo ce qui est équivalent à ce que CultureInfo.CurrentCulture sorties.

5voto

Raithlin Points 1625

IFormatProvider fournit des informations sur la culture de la méthode en question. DateTimeFormatInfo implémente IFormatProvider, et vous permet de spécifier le format dans lequel vous souhaitez que votre date/heure soit affichée. Vous trouverez des exemples sur les pages MSDN correspondantes.

4voto

Aamir Points 8357

Vous pouvez voir ici http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx

Voir la section Remarques et exemples à ce sujet.

12 votes

Ironiquement, l'exemple de code pour IFormatProvider n'utilise pas IFormatProvider .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X