CodeGym /Corsi /C# SELF /Calcoli e classi di supporto per date e orari

Calcoli e classi di supporto per date e orari

C# SELF
Livello 15, Lezione 4
Disponibile

1. Compiti principali quando lavori con date e orari

Lavorare con date e orari spesso fa venire un po' di panico (a volte anche tanto) anche agli sviluppatori esperti. Devi confrontare date, calcolare intervalli, aggiungere o sottrarre giorni/mesi/anni, calcolare l'età, determinare il giorno della settimana e molto altro.

Tutto questo sono compiti tipici per task tracker e calendari, gestione di abbonamenti o sottoscrizioni, calcoli finanziari, report statistici e ovviamente per le domande ai colloqui (tipo "calcola il numero di giorni lavorativi tra due date").

In C# e .NET per questi compiti ci sono classi e metodi già pronti. E la cosa più importante — la maggior parte dei calcoli si fa tramite un API object-oriented, super sicura e chiara.

2. Struttura TimeSpan — misuriamo intervalli di tempo

Tutto parte dalla struttura TimeSpan. È un "pezzo" di tempo: tipo 5 giorni, 3 ore, 7 minuti e 21 secondi.

Come creare un TimeSpan?

Puoi "sottrarre" due date, oppure crearlo direttamente:

// La differenza tra due date è sempre TimeSpan!
DateTime start = new DateTime(2025, 5, 1, 7, 0, 0);
DateTime end = new DateTime(2025, 5, 2, 11, 30, 0);

TimeSpan duration = end - start; // Magia pura!
Console.WriteLine(duration); // 1.04:30:00 (1 giorno, 4 ore, 30 minuti)

Puoi creare TimeSpan direttamente passando i parametri al costruttore:

TimeSpan span = new TimeSpan(2, 14, 18, 0); // 2 giorni, 14 ore, 18 minuti, 0 secondi
Console.WriteLine(span); // 2.14:18:00

Un altro modo — tramite metodi statici, spesso più leggibili:

TimeSpan fiveMinutes = TimeSpan.FromMinutes(5);
TimeSpan twoHours = TimeSpan.FromHours(2);
TimeSpan oneWeek = TimeSpan.FromDays(7);

Quali proprietà ha TimeSpan?

Proprietà Descrizione
Days
Numero intero di giorni
Hours
Parte delle ore
Minutes
Parte dei minuti
Seconds
Parte dei secondi
TotalDays
Tempo in giorni (decimale)
TotalHours
Tempo in ore (decimale)
TotalMinutes
Tempo in minuti (decimale)
TotalSeconds
Tempo in secondi (decimale)
Console.WriteLine($"Giorni: {duration.Days}, Ore totali: {duration.TotalHours}");

Come aggiungere/sottrarre TimeSpan da una data?

DateTime now = DateTime.Now;
DateTime future = now.Add(duration); // Aggiunto duration a now
DateTime past = now.Subtract(TimeSpan.FromDays(10)); // Meno 10 giorni

Console.WriteLine(future);
Console.WriteLine(past);

3. Calcolatrice delle date: calcolare la differenza tra date

Una skill che ti servirà praticamente sempre. Tipo, qualcuno vuole sapere quanto manca alle vacanze, qualcun altro — quando finisce il periodo gratuito.

DateTime today = DateTime.Today;
DateTime vacation = new DateTime(2025, 8, 1);
TimeSpan untilVacation = vacation - today;

Console.WriteLine($"Alle vacanze mancano {untilVacation.Days} giorni!");

Nota: se nella sottrazione ci sono solo "date" senza orario (usando DateTime.Date o DateTime.Today), il risultato è sempre un numero intero di giorni. Ma se almeno una data ha anche l'orario, la differenza sarà decimale.


int days = (vacation - today).TotalDays; // Errore di compilazione! TotalDays è double

Se ti serve un intero — usa .Days oppure fai il cast a intero con (int)TotalDays.

4. Aggiunta e sottrazione di tempo: metodi AddDays, AddMonths, AddHours, ...

C# non ti fa contare a mano i giorni di ogni mese, gli anni bisestili e tutte quelle rotture. Basta usare:

DateTime orderDate = new DateTime(2024, 4, 20);
DateTime deliveryDate = orderDate.AddDays(14); // Tra 2 settimane

Console.WriteLine($"Il prodotto sarà consegnato il {deliveryDate.ToShortDateString()}");
Metodo Cosa aggiunge (o sottrae se il numero è negativo)
AddDays(double)
Giorni (supporta i decimali, tipo 1,5 giorni)
AddMonths(int)
Mesi (gestisce automaticamente la lunghezza del mese)
AddYears(int)
Anni (anche considerando i bisestili)
AddHours(double)
Ore
AddMinutes(double)
Minuti
AddSeconds(double)
Secondi
DateTime birthday = new DateTime(2000, 2, 29);
DateTime nextYear = birthday.AddYears(1); // 2001-02-28 (non il 29, perché il 2001 non è bisestile)
Console.WriteLine(nextYear.ToShortDateString()); // 28.02.2001

Non dimenticare: tutti i metodi restituiscono una nuova istanza della data, la data originale non cambia!

var dt = DateTime.Now;
dt.AddDays(5); // Questo NON cambia dt!
dt = dt.AddDays(5); // Ora sì che cambia

5. Metodi di supporto per i calcoli

Calcolo del giorno della settimana

Nella maggior parte dei casi puoi usare la proprietà .DayOfWeek:

DateTime examDate = new DateTime(2025, 6, 19);
DayOfWeek day = examDate.DayOfWeek;
Console.WriteLine(day); // Wednesday

Puoi convertirlo in numero intero:

int number = (int)day; // Sunday == 0, Monday == 1, e così via

Controllo "oggi", "ieri", "domani"

Confronti semplicissimi:

DateTime date = new DateTime(2025, 6, 18);

if (date.Date == DateTime.Today)
    Console.WriteLine("Oggi!");
else if (date.Date == DateTime.Today.AddDays(-1))
    Console.WriteLine("Ieri!");
else if (date.Date == DateTime.Today.AddDays(1))
    Console.WriteLine("Domani!");

Calcolo dell'età

Uno dei compiti più frequenti — calcolare l'età di una persona in modo corretto. Semplicemente sottrarre gli anni non funziona sempre:

public static int CalculateAge(DateTime birthDate, DateTime currentDate)
{
    int age = currentDate.Year - birthDate.Year;
    
    // Se il compleanno non è ancora arrivato quest'anno
    if (currentDate.Month < birthDate.Month || 
        (currentDate.Month == birthDate.Month && currentDate.Day < birthDate.Day))
    {
        age--;
    }
    
    return age;
}

// Uso
DateTime birth = new DateTime(1990, 8, 15);
DateTime today = DateTime.Today;
int age = CalculateAge(birth, today);
Console.WriteLine($"Età: {age} anni");

Lavorare con i giorni lavorativi

Spesso devi calcolare il numero di giorni lavorativi tra due date, escludendo i weekend:

public static int CountWorkingDays(DateTime startDate, DateTime endDate)
{
    int workingDays = 0;
    DateTime current = startDate;
    
    while (current <= endDate)
    {
        if (current.DayOfWeek != DayOfWeek.Saturday && 
            current.DayOfWeek != DayOfWeek.Sunday)
        {
            workingDays++;
        }
        current = current.AddDays(1);
    }
    
    return workingDays;
}

6. Come sono collegati le classi principali

graph TD
    A(DateTime) --sottrazione--> B(TimeSpan)
    A2(DateTime) --AddDays, AddMonths--> A
    A --ToLocalTime/ToUniversalTime--> C(DateTimeOffset)
    D(DateOnly) --ToDateTime--> A
    E(TimeOnly) --ToTimeSpan--> B
    A --DayOfWeek, Day, Month, Year--> F(Proprietà numeriche)
    B(TimeSpan) --TotalDays, TotalHours, ...--> G(Proprietà durata)

7. Guida rapida: cosa fare se...

Compito Cosa usare Esempio
Scoprire la differenza tra date
TimeSpan duration = d2 - d1
(d2 - d1).Days
Aggiungere 2 settimane a una data
date.AddDays(14)
date.AddDays(14)
Calcolare l'età Formula con
.Year
e controllo mese/giorno
Vedi sezione sopra
Ottenere/impostare solo la data
DateOnly
DateOnly.FromDateTime(DateTime.Now)
Ottenere/impostare solo l'orario
TimeOnly
TimeOnly.FromDateTime(DateTime.Now)
Confrontare date Operatori
<
,
>
,
==
,
.CompareTo()
if (d1 < d2) ...
Convertire in un altro fuso orario
DateTimeOffset + ToOffset
dto.ToOffset(TimeSpan.FromHours(3))
Scoprire il numero della settimana nell'anno
Calendar.GetWeekOfYear()
vedi documentazione
Scoprire il giorno della settimana
date.DayOfWeek
Contare i giorni lavorativi Ciclo con controllo
DayOfWeek
Vedi sezione sopra
2
Compito
C# SELF, livello 15, lezione 4
Bloccato
Differenza tra le date
Differenza tra le date
2
Compito
C# SELF, livello 15, lezione 4
Bloccato
Giorno della settimana
Giorno della settimana
1
Sondaggio/quiz
Lavorare con le date, livello 15, lezione 4
Non disponibile
Lavorare con le date
Lavorare con date, orari e fusi orari
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION