1. Formattazione delle date
Se pensi che l’output 2025-06-19T17:30:00 sia piuttosto figo, prova a mostrare questo formato a tua nonna o a un contabile. Probabilmente preferiranno qualcosa di più semplice: 19.06.2025 17:30. I colleghi anglofoni invece si aspettano 06/19/2025 5:30 PM. I devops e le macchine amano 2025-06-19T17:30:00Z. Quindi un solo DateTime in memoria può essere rappresentato in decine di formati diversi sullo schermo.
Anche il problema opposto è classico: l’utente inserisce una data in un campo di input ("19.06.2025"), e noi dobbiamo riconoscerla in un oggetto C# senza confonderci tra giorno e mese. Automazione, integrazioni, report — ovunque serve interpretare correttamente le date testuali.
Formattazione base
C# ti permette di convertire un oggetto data/orario (DateTime, DateOnly, TimeOnly, DateTimeOffset) in una stringa usando il metodo .ToString():
DateTime now = DateTime.Now;
Console.WriteLine(now.ToString()); // Output: 19.06.2025 17:30:25
Se chiami .ToString() senza parametri — verrà usato il formato tipico della cultura attuale del sistema (ad esempio, Windows tedesco mostrerà un formato, quello americano un altro).
Stringhe di formato standard
Puoi specificare esplicitamente il formato di output usando le cosiddette stringhe di formato standard per data e ora:
| Formato | Descrizione | Esempio di output |
|---|---|---|
|
Data breve | 19.06.2025 |
|
Data completa | 19 giugno 2025 |
|
Data completa + ora breve | 19 giugno 2025 17:30 |
|
Data completa + ora completa | 19 giugno 2025 17:30:25 |
|
Data e ora brevi | 19.06.2025 17:30 |
|
Data breve + ora completa | 19.06.2025 17:30:25 |
|
Ora breve | 17:30 |
|
Ora completa | 17:30:25 |
|
Mese e giorno | 19 giugno |
|
Anno e mese | giugno 2025 |
|
ISO 8601 (round trip) | 2025-06-19T17:30:25.0000000 |
Console.WriteLine(now.ToString("d")); // 19.06.2025
Console.WriteLine(now.ToString("F")); // 19 giugno 2025 17:30:25
Console.WriteLine(now.ToString("O")); // 2025-06-19T17:30:25.0000000
Template personalizzati (custom)
Se ti servono formati più specifici, puoi usare i tuoi template:
| Simbolo | Significato |
|---|---|
| yyyy | Anno, 4 cifre |
| yy | Anno, 2 cifre |
| MM | Mese, 2 cifre |
| MMMM | Nome del mese |
| dd | Giorno, 2 cifre |
| d | Giorno, 1-2 cifre |
| HH | Ora (24h) |
| mm | Minuti |
| ss | Secondi |
| tt | AM/PM |
Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm")); // 2025-06-19 17:30
Console.WriteLine(now.ToString("dd.MM.yyyy")); // 19.06.2025
Console.WriteLine(now.ToString("dddd, MMMM d")); // mercoledì, giugno 19
Differenze culturali nella formattazione
Se vuoi ottenere un risultato nello stile di un altro paese o lingua, usa l’overload ToString(string, IFormatProvider):
var enUS = new System.Globalization.CultureInfo("en-US");
Console.WriteLine(now.ToString("D", enUS)); // June 19, 2025
- Se imposti rigidamente un template come "MM/dd/yyyy", indipendentemente dalla cultura otterrai sempre "06/19/2025".
- Ma se usi solo "d" o "D" — il formato dipende dalla cultura!
Punti importanti nella formattazione
Quando lavori con la formattazione delle date è importante capire la differenza tra formati standard e custom. I formati standard (come "d", "F", "G") si adattano automaticamente alla cultura del sistema, il che è comodo per l’interfaccia utente, ma può creare problemi nello scambio dati tra sistemi. I formati custom ti danno il pieno controllo sull’output, ma richiedono più attenzione.
Fai attenzione al formato "O" (o "o") — è il cosiddetto formato "round-trip", che garantisce che la data convertita in stringa e poi di nuovo in oggetto rimanga identica. Questo formato è fondamentale per la serializzazione o la trasmissione dati in rete.
2. Parsing di date e orari: come ottenere un oggetto da una stringa
Parsing più semplice: DateTime.Parse
DateTime.Parse — metodo che prova a riconoscere una stringa come data tenendo conto della cultura del sistema.
string input = "19.06.2025";
DateTime parsed = DateTime.Parse(input);
Console.WriteLine(parsed); // 19.06.2025 00:00:00
Se la stringa non è valida — il programma crasha con un’eccezione (nessuno è al sicuro!).
Specificare la cultura
string input = "06/19/2025";
var enUS = new System.Globalization.CultureInfo("en-US");
DateTime dt = DateTime.Parse(input, enUS);
Console.WriteLine(dt); // 19.06.2025 00:00:00
Parsing sicuro: TryParse
string input = "data non valida";
bool ok = DateTime.TryParse(input, out DateTime safeDate);
if (!ok)
Console.WriteLine("Errore: impossibile riconoscere la data!");
Specificare rigidamente il formato: ParseExact e TryParseExact
var culture = System.Globalization.CultureInfo.InvariantCulture;
string dateStr = "2025-06-19";
DateTime d = DateTime.ParseExact(dateStr, "yyyy-MM-dd", culture);
Console.WriteLine(d); // 19.06.2025 00:00:00
bool parsedOk = DateTime.TryParseExact(
"19.06.2025",
"dd.MM.yyyy",
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None,
out DateTime myDate);
Tabella dei formati più usati
| Stringa | Formato | Oggetto finale |
|---|---|---|
| "2025-06-19" | "yyyy-MM-dd" | 19 giugno 2025 |
| "19.06.2025" | "dd.MM.yyyy" | 19 giugno 2025 |
| "06/19/2025" | "MM/dd/yyyy" | 19 giugno 2025 |
| "2025-06-19T14:15:16" | "s" | 19 giugno 2025 14:15:16 |
Lavorare con DateTimeStyles
Durante il parsing puoi controllare il comportamento tramite il parametro DateTimeStyles. Questo enum ti permette di configurare come il parser deve interpretare i dati in input. Ad esempio, DateTimeStyles.AssumeUniversal fa sì che il parser consideri l’orario come UTC se lo shift non è specificato. DateTimeStyles.AllowWhiteSpaces permette di ignorare spazi extra nella stringa. Queste impostazioni sono utilissime quando lavori con dati da fonti esterne, dove il formato può essere imprevedibile.
3. Formattazione e parsing di DateOnly, TimeOnly
I nuovi tipi DateOnly e TimeOnly sono ormai spesso usati per salvare date/orari senza dettagli inutili.
Formattazione
DateOnly birthday = new DateOnly(2000, 6, 19);
Console.WriteLine(birthday.ToString("dd MMMM yyyy")); // 19 giugno 2000
Parsing
var d = DateOnly.ParseExact("19.06.2000", "dd.MM.yyyy");
Console.WriteLine(d.Day); // 19
Funzionano allo stesso modo anche i metodi per TimeOnly (solo che i template riguardano solo ore/minuti/secondi):
TimeOnly t = TimeOnly.ParseExact("23:59", "HH:mm");
Console.WriteLine(t.Hour); // 23
Vantaggi di DateOnly e TimeOnly
Usare DateOnly e TimeOnly invece di DateTime ha diversi vantaggi. Primo, chiarezza semantica — se ti serve solo la data senza ora (tipo la data di nascita), DateOnly lo rende chiaro. Secondo, aiuta a evitare problemi con i fusi orari che possono capitare con DateTime. Terzo, questi tipi occupano meno memoria e spazio nei database.
Formattazione e parsing con fusi orari
Se salvi l’orario con info sullo shift — usa DateTimeOffset. È fondamentale per sistemi internazionali e distribuiti. Tutti i metodi di formattazione e parsing sono simili, solo che ora puoi gestire anche lo shift:
DateTimeOffset meeting = new DateTimeOffset(2025, 6, 19, 17, 30, 0, TimeSpan.FromHours(3));
Console.WriteLine(meeting.ToString("o")); // 2025-06-19T17:30:00.0000000+03:00
string input = "2025-06-19T17:30:00+03:00";
var parsedOffset = DateTimeOffset.Parse(input);
Console.WriteLine(parsedOffset.Offset); // 03:00:00
4. Note pratiche ed errori tipici
Una delle trappole — confondere "giorno" e "mese" quando si fa il parsing di formati internazionali. Ad esempio, la stringa "01/02/2025" negli USA è 2 gennaio, mentre in gran parte d’Europa è 1 febbraio (sorpresa!).
Spesso ci si dimentica anche dell’influenza della cultura: se l’app gira su un server in Germania ma gli utenti sono di vari paesi, il formato della data dal database può essere interpretato diversamente su ogni server.
Un errore comune è usare .ToString() senza specificare cultura/formato per log e file di scambio: il risultato può cambiare dopo una migrazione su un altro OS o se l’app gira con un altro utente Windows.
Consigli per lavorare con le date
- Per la memorizzazione interna e lo scambio dati usa sempre la cultura invariante (CultureInfo.InvariantCulture) o formati esplicitamente specificati.
- Per l’interfaccia utente usa la cultura dell’utente o lascia scegliere il formato preferito.
- Quando lavori con API e database preferisci il formato ISO 8601, che è lo standard internazionale.
- Valida sempre i dati in input: controlla che la data esista, che sia nel range e che i valori abbiano senso.
Lavorare con fonti dati diverse
Quando integri sistemi esterni spesso devi gestire date in vari formati. Alcuni sistemi possono inviare date come Unix timestamp (secondi dal 1 gennaio 1970), altri come stringhe in formati nazionali. È importante accordarsi prima sul formato di scambio e controllare sempre la correttezza del parsing.
Ricorda anche che alcuni formati possono essere ambigui. Ad esempio, "12/13/2025" è chiaramente 13 dicembre 2025, ma "12/11/2025" può essere sia 12 novembre che 11 dicembre a seconda della cultura. In questi casi è meglio usare formati meno ambigui o specificare chiaramente la cultura di parsing.
GO TO FULL VERSION