Usar plantillas y patrones para dar formato a fechas y horas

Use clases en el espacio de nombres Windows.Globalization.DateTimeFormatting con plantillas y patrones personalizados para mostrar fechas y horas exactamente en el formato que desee.

Introducción

La clase DateTimeFormatter proporciona varias maneras de dar formato a fechas y horas correctamente para idiomas y regiones de todo el mundo. Puede usar formatos estándar para año, mes, día, etc. O bien, puede pasar una plantilla de formato al argumento formatTemplate del constructor DateTimeFormatter, como "longdate" o "month day".

Pero si desea tener aún más control sobre el orden y el formato de los componentes del objeto DateTime que desea mostrar, puede pasar un patrón de formato al argumento formatTemplate del constructor. Un patrón de formato usa una sintaxis especial, que permite obtener componentes individuales de un objeto DateTime, solo el nombre del mes o solo el valor del año, por ejemplo, para mostrarlos en cualquier formato personalizado que elija. Además, el patrón se puede localizar para adaptarse a otros idiomas y regiones.

Nota Esta es solo una introducción a los patrones de formato. Para obtener una explicación más completa de las plantillas de formato y los patrones de formato, vea la sección Comentarios de la clase DateTimeFormatter.

La diferencia entre las plantillas de formato y los patrones de formato

Una plantilla de formato es una cadena de formato independiente de la referencia cultural. Por lo tanto, si crea un DateTimeFormatter con una plantilla de formato, el formateador muestra los componentes de formato en el orden correcto para el idioma actual. Por el contrario, un patrón de formato es específico de la referencia cultural. Si crea un DateTimeFormatter con un patrón de formato, el formateador usará el patrón exactamente como se indica. Por lo tanto, un patrón no es necesariamente válido en todas las referencias culturales.

Vamos a ilustrar esta distinción con un ejemplo. Pasaremos una plantilla de formato simple (no un patrón) al constructor DateTimeFormatter. Esta es la plantilla de formato "month day".

var dateFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("month day");

Esto crea un formateador basado en el valor de idioma y región del contexto actual. El orden de los componentes en una plantilla de formato no importa; el formateador los muestra en el orden correcto para el idioma actual. Por lo tanto, muestra "January 1" para inglés (Estados Unidos), "1 janvier" para francés (Francia) y "1月1日" para japonés.

Por otro lado, un patrón de formato es específico de la referencia cultural. Vamos a acceder al patrón de formato de nuestra plantilla de formato.

IReadOnlyList<string> monthDayPatterns = dateFormatter.Patterns;

Esto produce resultados diferentes en función del lenguaje en runtime y la región. Las distintas regiones pueden usar distintos componentes, en diferentes órdenes, con o sin caracteres adicionales y espaciado.

En-US: "{month.full} {day.integer}"
Fr-FR: "{day.integer} {month.full}"
Ja-JP: "{month.integer}月{day.integer}日"

En el ejemplo anterior, se ha introducido una cadena de formato independiente de la referencia cultural y se ha devuelto una cadena de formato específica de la referencia cultural (que era una función del lenguaje y la región que tenía efecto cuando llamamos a dateFormatter.Patterns). Por lo tanto, si crea un DateTimeFormatter a partir de un patrón de formato específico de la referencia cultural, solo será válido para lenguajes o regiones específicos.

var dateFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("{month.full} {day.integer}");

El formateador anterior devuelve valores específicos de la referencia cultural para los componentes individuales dentro de los corchetes {}. Pero el orden de los componentes en un patrón de formato es invariable. Usted obtiene exactamente lo que pide, que puede o no ser culturalmente apropiado. Este formateador es válido para inglés (Estados Unidos), pero no para francés (Francia) ni para japonés.

En-US: January 1
Fr-FR: janvier 1 (inappropriate for France; non-standard order)
Ja-JP: 1月1 (inappropriate for Japan; the day symbol 日 is missing)

Además, es posible que un patrón correcto hoy no sea correcto en el futuro. Los países o regiones pueden cambiar sus sistemas de calendario, lo que modifica una plantilla de formato. Windows actualiza la salida de formateadores en función de las plantillas de formato para dar cabida a dichos cambios. Por lo tanto, solo debe usar la sintaxis de patrón en una o varias de estas condiciones.

  • No depende de una salida determinada para un formato.
  • No necesita el formato para seguir algún estándar específico de la referencia cultural.
  • En concreto, pretende que el patrón sea invariable en todas las referencias culturales.
  • Tiene previsto localizar la propia cadena de patrón de formato real.

Este es un resumen de la distinción entre las plantillas de formato y los patrones de formato.

Dar formato a plantillas, como "month day"

  • Representación abstracta de un formato DateTime que incluye valores para el mes, el día, etc., en cualquier orden.
  • Se garantiza que devuelva un formato estándar válido en todos los valores de región de idioma admitidos por Windows.
  • Se garantiza que obtendrá una cadena con formato culturalmente adecuada para la región-lenguiaje especificado.
  • No todas las combinaciones de componentes son válidas. Por ejemplo, "dayofweek day" no es válido.

Patrones de formato, como "{month.full} {day.integer}"

  • Cadena ordenada explícitamente que expresa el nombre completo del mes, seguido de un espacio, seguido del entero de día, en ese orden, o cualquier patrón de formato específico que especifique.
  • Es posible que no se corresponda con un formato estándar válido para cualquier par lenguaje-región.
  • No se garantiza que sea culturalmente apropiado.
  • Se puede especificar cualquier combinación de componentes, en cualquier orden.

Ejemplos

Supongamos que desea mostrar el mes y el día actuales junto con la hora actual, en un formato específico. Por ejemplo, desea que los usuarios en inglés de EE. UU. vean algo parecido a esto:

June 25 | 1:38 PM

La parte de fecha corresponde a la plantilla de formato "month day" y la parte de hora corresponde a la plantilla de formato "hour minute". Por lo tanto, puede construir formateadores para las plantillas de formato de fecha y hora pertinentes y, a continuación, concatenar su salida conjuntamente mediante una cadena de formato localizable.

var dateToFormat = System.DateTime.Now;
var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

var dateFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("month day");
var timeFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("hour minute");

var date = dateFormatter.Format(dateToFormat);
var time = timeFormatter.Format(dateToFormat);

string output = string.Format(resourceLoader.GetString("CustomDateTimeFormatString"), date, time);

CustomDateTimeFormatString es un identificador de recurso que hace referencia a un recurso localizable en un archivo de recursos (.resw). Para un idioma predeterminado del inglés (Estados Unidos), se establecería en un valor de "{0} | {1}" junto con un comentario que indica que "{0}" es la fecha y "{1}" es la hora. De este modo, los traductores pueden ajustar los elementos de formato según sea necesario. Por ejemplo, pueden cambiar el orden de los elementos si parece más natural en algún lenguaje o región para tener la hora precedida de la fecha. O bien, pueden reemplazar "|" por algún otro carácter separador.

Otra manera de implementar este ejemplo es consultar los dos formateadores para sus patrones de formato, concatenarlos juntos y, a continuación, construir un tercer formateador a partir del patrón de formato resultante.

var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

var dateFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("month day");
var timeFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("hour minute");

string dateFormatterPattern = dateFormatter.Patterns[0];
string timeFormatterPattern = timeFormatter.Patterns[0];

string pattern = string.Format(resourceLoader.GetString("CustomDateTimeFormatString"), dateFormatterPattern, timeFormatterPattern);

var patternFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter(pattern);

string output = patternFormatter.Format(System.DateTime.Now);

API importantes