¿Qué hace IFormatProvider?

Respuestas:

61

Además de la respuesta de Ian Boyd:

También CultureInfoimplementa esta interfaz y se puede utilizar en su caso. Por lo tanto, podría analizar una cadena de fecha francesa, por ejemplo; podrías usar

var ci = new CultureInfo("fr-FR");
DateTime dt = DateTime.ParseExact(yourDateInputString, yourFormatString, ci);
Andrei Rînea
fuente
2
Ya no parece haber una sobrecarga que coincida con su ejemplo en .NET Framework 4.6. Debe usar DateTime.ParseExact(string, string, IFormatProvider)en su lugar, creo, como tal: DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
James King
1
En .NET Framework 4.6.2 no hay parámetros de entrada como señala. Solo uso dos y funciona bien. DateTime dt = DateTime.Parse(yourDateInputString, ci);Revise su respuesta.
Desarrollador
1
Lo siento muchachos, se ha realizado una actualización a mi respuesta hace mucho tiempo.
Andrei Rînea
49

La IFormatProviderinterfaz normalmente la implementa una CultureInfoclase, por ejemplo:

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

La interfaz es una puerta de entrada para que una función obtenga un conjunto de datos específicos de una cultura de una cultura. Los dos objetos de referencia cultural comúnmente disponibles que IFormatProviderse pueden consultar son:

La forma en que normalmente funcionaría es pedirle IFormatProvideral DateTimeFormatInfoobjeto que le dé un objeto:

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

También existe el conocimiento interno de que IFormatProvideres probable que cualquier interfaz esté siendo implementada por una clase que desciende CultureInfoo desciende DateTimeFormatInfo, por lo que puede transmitir la interfaz directamente:

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

Pero no hagas eso

Todo ese arduo trabajo ya ha sido escrito para ti:

Para obtener un DateTimeFormatInfode unIFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

Para obtener un NumberFormatInfode unIFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

El valor de IFormatProvideres que usted crea sus propios objetos de cultura. Siempre que implementen IFormatProvidery devuelvan los objetos que se les solicitan, puede omitir las culturas integradas.

También puede utilizarlo IFormatProvidercomo una forma de pasar objetos culturales arbitrarios, a través de IFormatProvider. Por ejemplo, el nombre de dios en diferentes culturas.

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

Esto permite que su LordsNameFormatInfoclase personalizada viaje dentro de un IFormatProvider, y puede preservar el idioma.

En realidad, nunca necesitarás llamar a GetFormatmétodo de IFormatProviderti mismo.

Siempre que lo necesite IFormatProvider, puede pasar un CultureInfoobjeto:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

Nota : Cualquier código se libera al dominio público. No se requiere atribución.

Ian Boyd
fuente
18

Pasar un valor nulo como IFormatProviderno es la forma correcta de hacer esto. Si el usuario tiene un formato de fecha / hora personalizado en su PC, tendrá problemas para analizar y convertir a cadena. Acabo de corregir un error en el que alguien había pasado nulo como IFormatProvider al convertir a una cadena.

En su lugar, deberías usar CultureInfo.InvariantCulture

Incorrecto:

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

Correcto:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", CultureInfo.InvariantCulture);
Tim
fuente
2
¿Hay alguna razón por la que deberíamos usar en CultureInfo.InvariantCulturelugar de CultureInfo.CurrentCulture?
Stephen Booher
5
InvariantCulture es una cultura especial que está garantizada para existir siempre en cualquier máquina y siempre convertirá y analizará de nuevo a los mismos valores. CurrentCulture es la cultura del hilo actual. Esto puede variar y si no usa la misma cultura para convertir a cadena y analizar, obtendrá errores de formato ...
Tim
5
@StephenBooher nullpasará por defecto a CultureInfo.CurrentCulture. Vea la llamada en la fuente de referencia , si sigue la cadena de llamadas, el nulo finalmente se reemplaza con lo DateTimeFormatInfo.CurrentInfoque es equivalente a las CultureInfo.CurrentCulturesalidas.
Scott Chamberlain
InvariantCulture es lo que estaba buscando. Gracias
Chicowitz
5

IFormatProvider proporciona información cultural al método en cuestión. DateTimeFormatInfo implementa IFormatProvider y le permite especificar el formato en el que desea que se muestre su fecha / hora. Se pueden encontrar ejemplos en las páginas relevantes de MSDN.

Raithlin
fuente
2

Por MSDN

.NET Framework incluye las siguientes tres implementaciones de IFormatProvider predefinidas para proporcionar información específica de la cultura que se utiliza para formatear o analizar valores numéricos y de fecha y hora:

  1. La NumberFormatInfoclase, que proporciona información que se usa para dar formato a números, como la moneda, el separador de miles y los símbolos de separador decimal para una cultura particular. Para obtener información sobre las cadenas de formato predefinidas reconocidas por un NumberFormatInfoobjeto y utilizadas en operaciones de formato numérico, consulte Cadenas de formato numérico estándar y Cadenas de formato numérico personalizado.
  2. La DateTimeFormatInfoclase, que proporciona información que se utiliza para dar formato a fechas y horas, como los símbolos separadores de fecha y hora para una cultura en particular o el orden y formato de los componentes de año, mes y día de una fecha. Para obtener información sobre las cadenas de formato predefinidas reconocidas porDateTimeFormatInfo objeto y utilizadas en operaciones de formato numérico, consulte Cadenas de formato de fecha y hora estándar y Cadenas de formato de fecha y hora personalizadas.
  3. La CultureInfoclase, que representa una cultura particular. Su GetFormatmétodo devuelve un objeto NumberFormatInfoo una cultura específica DateTimeFormatInfo, dependiendo de si el CultureInfoobjeto se usa en una operación de formato o análisis que involucra números o fechas y horas.

.NET Framework también es compatible con el formato personalizado. Esto normalmente implica la creación de una clase de formato que implementa IFormatProvider e ICustomFormatter. Luego, una instancia de esta clase se pasa como parámetro a un método que realiza una operación de formateo personalizada, como String.Format(IFormatProvider, String, Object[]).

Ojos grandes
fuente
1

los clase DateTimeFormatInfo implementa esta interfaz, por lo que le permite controlar el formato de sus cadenas DateTime.

Gerrie Schenck
fuente