Que fait IFormatProvider?

Réponses:

61

En plus de la réponse d'Ian Boyd:

Implémente également CultureInfocette interface et peut être utilisée dans votre cas. Ainsi, vous pouvez analyser une chaîne de date française par exemple; tu pourrais utiliser

var ci = new CultureInfo("fr-FR");
DateTime dt = DateTime.ParseExact(yourDateInputString, yourFormatString, ci);
Andrei Rînea
la source
2
Il ne semble plus y avoir de surcharge correspondant à votre exemple dans .NET Framework 4.6. Vous devez utiliser à la DateTime.ParseExact(string, string, IFormatProvider)place, je crois - en tant que tel: DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
James King
1
Dans .NET Framework 4.6.2, il n'y a pas de paramètres d'entrée lorsque vous pointez. Je n'en utilise que deux et cela fonctionne bien DateTime dt = DateTime.Parse(yourDateInputString, ci);Veuillez réviser votre réponse.
Développeur
1
Désolé les gars, une mise à jour attendue depuis longtemps a été apportée à ma réponse.
Andrei Rînea
49

L' IFormatProviderinterface est normalement implémentée pour vous par une CultureInfoclasse, 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 à partir d'une culture. Les deux objets de culture couramment disponibles pour lesquels un IFormatProviderpeut être interrogé sont:

La façon dont cela fonctionnerait normalement est de demander au IFormatProviderde vous donner un DateTimeFormatInfoobjet:

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

Il y a aussi une connaissance interne que toute IFormatProviderinterface est probablement implémentée par une classe qui descend CultureInfoou descend de DateTimeFormatInfo, vous pouvez donc convertir 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 fais pas ça

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

Pour obtenir un DateTimeFormatInfod'unIFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

Pour obtenir un NumberFormatInfod'unIFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

La valeur de IFormatProviderest que vous créez vos propres objets de culture. Tant qu'ils implémentent IFormatProvideret retournent les objets qui leur sont demandés, vous pouvez contourner les cultures intégrées.

Vous pouvez également l'utiliser IFormatProviderpour transmettre des objets de culture arbitraires - via le IFormatProvider. Par exemple, le nom de Dieu dans différentes cultures

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

Cela permet à votre LordsNameFormatInfoclasse personnalisée de circuler à l'intérieur d'un IFormatProvider, et vous pouvez préserver l'idiome.

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

Chaque fois que vous en avez besoin, IFormatProvidervous pouvez passer un CultureInfoobjet:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

Remarque : tout code est publié dans le domaine public. Aucune attribution requise.

Ian Boyd
la source
18

Passer null comme le IFormatProvidern'est pas la bonne façon de procéder. Si l'utilisateur a un format de date / heure personnalisé sur son PC, vous rencontrerez des problèmes d'analyse et de conversion en chaîne. Je viens de corriger un bogue où quelqu'un avait passé null comme IFormatProvider lors de la conversion en chaîne.

Au lieu de cela, vous devriez 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);
Tim
la source
2
Y a-t-il une raison pour laquelle nous devrions utiliser à la CultureInfo.InvariantCultureplace CultureInfo.CurrentCulture?
Stephen Booher
5
InvariantCulture est une culture spéciale qui est garantie d'exister toujours sur n'importe quelle machine et qui sera toujours convertie et analysée aux mêmes valeurs. CurrentCulture est la culture du thread actuel. Cela 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 ...
Tim
5
@StephenBooher passant nullsera par défaut CultureInfo.CurrentCulture. Voir l'appel dans la source de référence , si vous suivez la chaîne d'appels, le null est finalement remplacé par DateTimeFormatInfo.CurrentInfoce qui équivaut à quelles CultureInfo.CurrentCulturesorties.
Scott Chamberlain
InvariantCulture est ce que je recherchais. Merci
Chicowitz
5

IFormatProvider fournit des informations de culture à la méthode en question. DateTimeFormatInfo implémente IFormatProvider et vous permet de spécifier le format dans lequel vous voulez que votre date / heure soit affichée. Des exemples peuvent être trouvés sur les pages MSDN appropriées.

Raithlin
la source
2

Par MSDN

Le .NET Framework comprend les trois implémentations IFormatProvider prédéfinies suivantes pour fournir des informations spécifiques à la culture qui sont utilisées dans le formatage ou l'analyse des valeurs numériques et de date et d'heure:

  1. La NumberFormatInfoclasse, qui fournit des informations utilisées pour mettre en forme les nombres, telles que la devise, le séparateur de milliers et les symboles de séparateur décimal pour une culture particulière. Pour plus d'informations sur les chaînes de format prédéfinies reconnues par un NumberFormatInfoobjet et utilisées dans les opérations de formatage numérique, consultez Chaînes de format numérique standard et Chaînes de format numérique personnalisées.
  2. La DateTimeFormatInfoclasse, qui fournit des informations utilisées pour mettre en forme les dates et les heures, telles que les symboles de séparation de date et d'heure pour une culture particulière ou l'ordre et le format des composants année, mois et jour d'une date. Pour plus d'informations sur les chaînes de format prédéfinies reconnues par un DateTimeFormatInfoobjet et utilisées dans les opérations de formatage numérique, consultez Chaînes de format de date et d'heure standard et Chaînes de format de date et d'heure personnalisées.
  3. La CultureInfoclasse, qui représente une culture particulière. Sa GetFormatméthode renvoie un objet NumberFormatInfoou un DateTimeFormatInfoobjet propre à la culture , selon que l' CultureInfoobjet est utilisé dans une opération de mise en forme ou d'analyse qui implique des nombres ou des dates et des heures.

Le .NET Framework prend également en charge la mise en forme personnalisée. Cela implique généralement la création d'une classe de mise en forme qui implémente à la fois IFormatProvider et ICustomFormatter. Une instance de cette classe est ensuite transmise en tant que paramètre à une méthode qui effectue une opération de mise en forme personnalisée, telle que String.Format(IFormatProvider, String, Object[]).

Gros yeux
la source
1

La classe DateTimeFormatInfo implémente cette interface, elle vous permet donc de contrôler la mise en forme de vos chaînes DateTime.

Gerrie Schenck
la source