CodeGym /Corsi /C# SELF /Formattazione e parsing di date e orari

Formattazione e parsing di date e orari

C# SELF
Livello 15, Lezione 3
Disponibile

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
Formattazione base di data e ora

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
"d"
Data breve 19.06.2025
"D"
Data completa 19 giugno 2025
"f"
Data completa + ora breve 19 giugno 2025 17:30
"F"
Data completa + ora completa 19 giugno 2025 17:30:25
"g"
Data e ora brevi 19.06.2025 17:30
"G"
Data breve + ora completa 19.06.2025 17:30:25
"t"
Ora breve 17:30
"T"
Ora completa 17:30:25
"M"/"m"
Mese e giorno 19 giugno
"Y"/"y"
Anno e mese giugno 2025
"O"/"o"
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.

2
Compito
C# SELF, livello 15, lezione 3
Bloccato
Formattazione base di data e ora
Formattazione base di data e ora
2
Compito
C# SELF, livello 15, lezione 3
Bloccato
Parsing sicuro della data da una stringa
Parsing sicuro della data da una stringa
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION