Usare modelli e criteri per la formattazione di date e ore

Usare le classi nello spazio dei nomi Windows.Globalization.DateTimeFormatting con template e modelli personalizzati per visualizzare date e ore esattamente nel formato desiderato.

Introduzione

La classe DateTimeFormatter offre diversi modi per formattare correttamente data e ora per lingue e aree geografiche in tutto il mondo. È possibile usare formati standard per anno, mese, giorno e così via. In alternativa, è possibile passare un modello di formato all'argomento formatTemplate del costruttore DateTimeFormatter, ad esempio "longdate" o "month day" (data estesa o mese giorno).

Tuttavia, quando si desidera un maggiore controllo sull'ordine e sul formato dei componenti dell'oggetto DateTime che si desidera visualizzare, è possibile passare un modello di formato all'argomento del costruttore formatTemplate. Un modello di formato usa una sintassi speciale, che consente di ottenere singoli componenti di un oggetto DateTime, solo il nome del mese o solo il valore dell'anno, ad esempio, per visualizzarli in qualsiasi formato personalizzato scelto. Inoltre, il modello può essere localizzato per adattarsi ad altre lingue e aree geografiche.

Nota Questa è solo una panoramica dei modelli di formato. Per una descrizione più completa dei template di formato, consultare la sezione Osservazioni della classe DateTimeFormatter.

Differenza tra template di formato e modelli di formato

Un template di formato è una stringa di formato indipendente dalla cultura. Pertanto, se si crea un DateTimeFormatter usando un template di formato, il formattatore visualizza i componenti di formato nell'ordine corretto per la lingua corrente. Al contrario, un modello di formato è specifico delle impostazioni cultura. Se si costruisce un oggetto DateTimeFormatter usando un modello di formato, il formattatore userà il modello esattamente come specificato. Di conseguenza, un modello non è necessariamente valido per culture diverse.

Di seguito viene illustrata questa distinzione con un esempio. Verrà passato un template di formato semplice (non un modello) al costruttore DateTimeFormatter. Questo è il template di formato "month day" (mese giorno).

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

In questo modo viene creato un formattatore in base al valore della lingua e dell'area geografica del contesto corrente. L'ordine dei componenti in un template di formato non è importante; il formattatore li visualizza nell'ordine corretto per la lingua corrente. Quindi, visualizza "January 1" per l'inglese (Stati Uniti), "1 janvier" per francese (Francia) e "1月1本" per il giapponese.

D'altra parte, un modello di formato è specifico per la cultura. A questo punto si accede al modello di formato per il template di formato.

IReadOnlyList<string> monthDayPatterns = dateFormatter.Patterns;

In questo modo si ottengono risultati diversi a seconda della lingua di runtime e dell'area geografica. Aree geografiche diverse possono usare componenti diversi, in ordini diversi, con o senza caratteri aggiuntivi e spaziatura.

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

Nell'esempio precedente è stata immessa una stringa di formato indipendente dalla cultura ed è stata restituita una stringa di formato specifica della cultura (una funzione della lingua e dell'area geografica che è stata applicata quando è stato chiamato dateFormatter.Patterns). Di conseguenza, se si costruisce un DateTimeFormatter da un modello di formato specifico della cultura, sarà valido solo per lingue/aree geografiche specifiche.

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

Il formattatore precedente restituisce valori specifici delle impostazioni cultura per i singoli componenti all'interno delle parentesi quadre {}. Ma l'ordine dei componenti in un modello di formato è invariante. Si ottiene esattamente ciò che si chiede, ma ciò può essere culturalmente appropriato o non può esserlo. Questo formattatore è valido per l'inglese (Stati Uniti), ma non per il francese (Francia) né per il giapponese.

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)

Inoltre, un modello corretto oggi potrebbe non essere corretto in futuro. I paesi o le aree geografiche possono modificare i sistemi di calendario, che modificano un template di formato. Windows aggiorna l'output dei formattatori in base ai template di formato per supportare tali modifiche. Pertanto, è consigliabile usare solo la sintassi del modello in una o più di queste condizioni.

  • Non si dipende da un determinato output per un formato.
  • Non è necessario il formato per seguire alcuni standard specifici della cultura.
  • Si intende specificamente che il modello sia invariante tra le culture.
  • Si intende localizzare la stringa del modello di formato effettivo.

Ecco un riepilogo della distinzione tra template di formato e modelli di formato.

Template di formato, ad esempio "month day" (mese giorno)

  • Rappresentazione astratta di un formato DateTime che include valori per il mese, il giorno e così via, in qualsiasi ordine.
  • È garantito che restituisca un formato standard valido in tutti i valori di area geografica della lingua supportati da Windows.
  • Garantisce di fornire una stringa formattata appropriata per la lingua specificata.
  • Non tutte le combinazioni di componenti sono valide. Ad esempio, "dayofweek day" non è valido.

Modelli di formato, ad esempio "{month.full} {day.integer}"

  • Stringa ordinata in modo esplicito che esprime il nome completo del mese, seguito da uno spazio, seguito dal numero intero del giorno, in quell'ordine o qualunque modello di formato specifico indicato.
  • Può non corrispondere a un formato standard valido per qualsiasi coppia di lingue.
  • Non è garantito che sia appropriato a livello culturale.
  • Qualsiasi combinazione di componenti può essere specificata, in qualsiasi ordine.

Esempi

Si supponga di voler visualizzare il mese e il giorno correnti insieme all'ora corrente, in un formato specifico. Si supponga, ad esempio, che gli utenti degli Stati Uniti visualizzino in lingua inglese un aspetto simile al seguente:

June 25 | 1:38 PM

La parte della data corrisponde al template di formato "month day" (mese giorno) e la parte dell'ora corrisponde al template di formato "hour minute". È quindi possibile costruire formattatori per i template di formato di data e ora pertinenti e quindi concatenare l'output insieme usando una stringa di formato localizzabile.

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 è un identificatore di risorsa che fa riferimento a una risorsa localizzabile in un file di risorse (.resw). Per una lingua predefinita dell'inglese (Stati Uniti), questo valore viene impostato su "{0} | {1}" insieme a un commento che indica che "{0}" è la data e "{1}" è l'ora. In questo modo, i traduttori possono modificare gli elementi di formato in base alle esigenze. Ad esempio, possono modificare l'ordine degli elementi se sembra più naturale in una lingua o un'area geografica in cui l'ora precede la data. In alternativa, possono sostituire "|" con un altro carattere separatore.

Un altro modo per implementare questo esempio consiste nell'eseguire una query sui due formattatori per i modelli di formato, concatenarli insieme e quindi costruire un terzo formattatore dal modello di formato risultante.

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 importanti