This article has been localized into Italian by the community.
Lavorare con Date & Ore
C# è provvisto di uno struct grandioso per lavorare con date e orari: è chiamato DateTime. Non è effettivamente un tipo di dato, ma è stato incluso in questo capitolo perché ci si troverà spesso a lavorare con date e/o orari utilizzando lo struct DateTime, talvolta tanto quanto si lavora con stringhe e numeri.
Iniziamo istanziando un nuovo oggetto DateTime:
DateTime dt = new DateTime();
Console.WriteLine(dt.ToString());
Il risultato è piuttosto noioso però: 01-01-0001 00:00:00. Questo corrisponde alla proprietà DateTime.MinValue, ma DateTime ha altre utili proprietà, la più interessante è DateTime.Now:
DateTime dt = DateTime.Now;
Console.WriteLine(dt.ToString());
Questa ci restituisce la data e ora correnti, che è spesso molto pertinente, come vedremo in alcuni dei prossimi esempi. Tuttavia, in molte situazioni, si cercherà probabilmente di rappresentare una specifica data e ora. Fortunatamente per noi, DateTime ha diversi costruttori che ci aiutano proprio in questo. Ecco un esempio:
DateTime dt = new DateTime(2042, 12, 24);
Console.WriteLine(dt.ToString());
L'ordine dei parametri in questo costruttore è Anno, Mese, Giorno, così otteniamo un oggetto con una data corrispondente alla vigilia di Natale nell'anno 2042.
DateTime - con o senza orario?
Ma che ne è dell'orario? Beh, se non se ne specifica uno, il predefinito è 00:00:00, come si può vedere dall'esempio precedente. Si può però facilmente specificare anche un orario:
DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
Console.WriteLine(dt.ToString());
Ora, DateTime ha anche un'orario, in questo caso alle 18:42. Va notato che le ore vanno specificate come un numero tra 0 e 23, poiché si usa il formato a 24 ore per l'inserimento, ma non ci si deve preoccupare se lo si vuole in formato 12 ore con AM/PM: questo si può fare facilmente in uscita, come spiegheremo più avanti.
Ci rimane una domanda: cosa fare se si è interessati solo alla parte della data? La risposta ovvia sarebbe di usare la classe Date invece di DateTime, ma effettivamente, non ne esiste una. Invece, la classe DateTime ha una proprietà Date:
DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
DateTime date = dt.Date;
Console.WriteLine(date.ToString());
Comunque come si vede, anche la proprietà Date è un oggetto DateTime, dove la parte dell'orario è impostata a 00:00:00. Questo può sembrare un po' confuso, ma ha perfettamente senso, perché DateTime dovrebbe sempre solo servire da contenitore, che contiene il dato da mostrare all'utente in diversi modi e forme. Abbiamo già usato il metodo di base ToString(), ma ci sono molti altri modi di fare uscire un oggetto DateTime
L'output di DateTime
Ottenere l'output di un DateTime è uno degli aspetti più importanti, ma può anche essere un compito complicato. Dipende da ciò di cui si ha bisogno. Finora abbiamo visto la versione base dell'output: la semplice chiamata al metodo ToString(). Questa ritorna data e ora basati sulla cultura attuale dell'applicazione, che in modo predefinito è basata sulle impostazioni di sistema. Questo significa che se si chiama il metodo ToString(), la data e ora saranno mostrati all'utente in una maniera che ha senso per lui, indipendentemente da che parte del mondo si trova, perché, come saprete, il formato dell'orario e, specialmente, quello della data variano MOLTO da regione a regione.
Se si cerca di avere maggiore controllo dell'output, ci sono diversi modi per farlo. Il modo più rapido è di usare uno dei metodi To*, per esempio, il metodo ToShortDateString():
Console.WriteLine(DateTime.Now.ToShortDateString());
Questo ritornerà una versione abbreviata della data, omettendo completamente la parte dell'orario. Si può anche usare il metodo ToLongDateString():
Console.WriteLine(DateTime.Now.ToLongDateString());
L'output varierà in base alle impostazioni regionali, ma, di solito, una data estesa include una rappresentazione testuale del mese invece della rappresentazione numerica.
Se si cerca un maggiore controllo, forse perché si vuole adattare la data/ora ad una specifica regione, si può usare uno dei sovraccarichi del metodo ToString(), per esempio, specificando esattamente quale cultura/regione si vuole ottenere:
var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine(DateTime.Now.ToString(usCulture.DateTimeFormat));
La classe CultureInfo permette di avere un intero set di informazioni riguardo un linguaggio, per esempio, come si scrivono le date e gli orari (la classe CultureInfo verrà trattata più avanti in questo tutorial). Possiamo poi passare queste informazioni alla classe DateTime, per farle sapere che si vuole una rappresentazione visuale della data e ora corrispondenti a questo linguaggio. Ma se si volesse essere ancora più specifici riguardo l'output?
Formati di Date & Orari Standard
Per avere ulteriore controllo dell'output, si possono usare i formati data & ora standard forniti dal framework .NET. Si tratta di una singola lettera, che rappresenta un modo di mostrare la data e/o l'ora. Per una lista completa, suggeriamo di dare un'occhiata alla documentazione, ma per ora, ecco un paio di esempi:
DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
Console.WriteLine("Short date pattern (d): " + dt.ToString("d"));
Console.WriteLine("Long date pattern (D): " + dt.ToString("D"));
Console.WriteLine("Full date/time pattern (F): " + dt.ToString("F"));
Console.WriteLine("Year/month pattern (y): " + dt.ToString("y"));
L'output sarà come questo:
Short date pattern (d): 24-12-2042
Long date pattern (D): 24. december 2042
Full date/time pattern (F): 24. december 2042 18:42:00
Year/month pattern (y): december 2042
Questo lascia un po' più di controllo dell'output, ma a volte non è abbastanza. In questi casi, si avrà bisogno di un formato personalizzato.
Formati Data & Orario Personalizzati
Per il controllo completo, ci sono i formati personalizzati. Sono una combinazione di lettere e caratteri speciali che si possono passare al metodo ToString(), per mostrare l'esatto formato che si vuole per la data e/o ora. Questo include dove si vogliono le parti data/ora, come le si vuole e che tipo di separatori si desiderano usare. Ovviamente questo ci lascia parecchie opzioni, per cui verifica la documentazione per la lista completa degli specificatori di formato, ma vediamo subito come funziona:
DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
Console.WriteLine(dt.ToString("MM'/'dd yyyy"));
Console.WriteLine(dt.ToString("dd.MM.yyyy"));
Console.WriteLine(dt.ToString("MM.dd.yyyy HH:mm"));
Console.WriteLine(dt.ToString("dddd, MMMM (yyyy): HH:mm:ss"));
Console.WriteLine(dt.ToString("dddd @ hh:mm tt", System.Globalization.CultureInfo.InvariantCulture));
L'output sarà simile a questo:
12/24 2042
24.12.2042
12.24.2042 18:42
onsdag, december (2042): 18:42:00
Wednesday @ 06:42 PM
Generalmente, una o più d ti daranno una qualche versione del giorno, una o più M ti daranno il mese (la m in minuscolo è per i minuti) e un numero di y ti daranno l'anno. Per capire pienamente cosa fanno questi specificatori di formato, continuo a consigliarti di dare un'occhiata alla documentazione, ma spero che l'esempio sopra ti abbia dato una buona idea di quanto potenti siano le stringhe con formato personalizzato.
Analizzare le date
Finora, abbiamo lavorato con le date definite direttamente nel codice, ma probabilmente incorrerai presto in una situazione in cui avrai bisogno di lavorare con una data specificata dall'utente. Questo è, sorprendentemente, un problema complicato perché ci sono tantissimi modi di scrivere una data. Il framework .NET ti può aiutare, perché supporta tutte le culture, come illustrato negli esempi precedenti, ma hai comunque bisogno di aiutare l'utente a specificare la data nel formato che ti aspetti. Dopo questo, puoi usare il metodo Parse() per trasformare una stringa specificata dall'utente in un oggetto DateTime, in questo modo:
var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine("Please specify a date. Format: " + usCulture.DateTimeFormat.ShortDatePattern);
string dateString = Console.ReadLine();
DateTime userDate = DateTime.Parse(dateString, usCulture.DateTimeFormat);
Console.WriteLine("Date entered (long date format):" + userDate.ToLongDateString());
Questo esempio è effettivamente interessante perché mostra quanto il framework .NET ci può aiutare, finché abbiamo una istanza della classe CultureInfo che vogliamo usare (US English in questo caso - ma niente paura, discuteremo della classe CultureInfo im maggior dettaglio più avanti). Finché è disponibile, la usiamo per far sapere all'utente quale formato di data ci aspettiamo. Poi la usiamo ancora nella quarta linea per analizzare concretamente l'input. Nell'ultima linea, mostriamo la data data inserita dall'utente, questa volta con il formato impostato dal sistema.
Tuttavia, va detto che il metodo Parse() è molto rigoroso: se l'utente non inserisce la data nell'esatto formato richiesto, sarà generata un'eccezione. Per questo, di solito è una buona idea usare invece il metodo TryParse(). Fa la stessa cosa, ma ci permette di verificare se la data può essere analizzata o altrimenti generare un'eccezione. Di seguito una versione rivista dell'esempio precedente:
var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine("Please specify a date. Format: " + usCulture.DateTimeFormat.ShortDatePattern);
string dateString = Console.ReadLine();
DateTime userDate;
if (DateTime.TryParse(dateString, usCulture.DateTimeFormat, System.Globalization.DateTimeStyles.None, out userDate))
Console.WriteLine("Valid date entered (long date format):" + userDate.ToLongDateString());
else
Console.WriteLine("Invalid date specified!");
Riepilogo
Lavorare con le date e gli orari è molto importante ma anche molto complesso. Fortunatamente per noi, il framework .NET è lì per aiutarci in quasi tutte le situazioni con la geniale classe DateTime