Giorni fa, il mio mentore, mi ha fatto notare una cosa riguardo il metodo DateDiff da me scritto. L'obbiezione riguardava il calcolo dei mesi di differenza tra una data e l'altra, che secondo lui, dava un risultato errato facendo la differenza tra il 31 gennaio e il 1 marzo di un anno non bisestile.
Chiaramente aveva ragione, perchè cosi' com'era scritto prima, ritornava un bel 0 ! E non 2, come correttamente fa il DateDiff di Visual Basic.
Dove sbagliavo ?
Sicuramente nel fare direttamente la divisione per 30 del numero di giorni (che in quel specifico caso sono 29), sia nel tralasciare la culture del thread corrente, in modo tale da poter gestire gli anni bisestili e non.
Ecco quindi il risultato:

public static long DateDiff(DateInterval interval, DateTime startDate, DateTime endDate)

{
long dateDiffVal = 0;
Calendar cal = Thread.CurrentThread.CurrentCulture.Calendar;
TimeSpan ts = new TimeSpan(endDate.Ticks - startDate.Ticks);
switch (interval)
{
case DateInterval.Day:
dateDiffVal = (long)ts.TotalDays;
break;
case DateInterval.Hour:
dateDiffVal = (long)ts.TotalHours;
break;
case DateInterval.Millisecond:
dateDiffVal = (long)ts.TotalMilliseconds;
break;
case DateInterval.Minute:
dateDiffVal = (long)ts.TotalMinutes;
break;
case DateInterval.Month:
dateDiffVal = (long)(((cal.GetYear(endDate)
- cal.GetYear(startDate)) * 12
+ cal.GetMonth(endDate))
- cal.GetMonth(startDate));
break;
case DateInterval.Quarter:
dateDiffVal = (long)((((cal.GetYear(endDate)
- cal.GetYear(startDate)) * 4)
+ ((cal.GetMonth(endDate) - 1) / 3))
- ((cal.GetMonth(startDate) - 1) / 3));
break;
case DateInterval.Second:
dateDiffVal = (long)ts.TotalSeconds;
break;
case DateInterval.Week:
dateDiffVal = (long)(ts.TotalDays / 7);
break;
case DateInterval.Year:
dateDiffVal = (long)(cal.GetYear(endDate) - cal.GetYear(startDate));
break;
}
return dateDiffVal;
}

Oltre a questo mi ha fatto notare anche che il metodo DateDiff di VB, lo possiamo utilizzare semplicemente importanto il namespace Microsoft.VisualBasic. Vero anche questo... ma cosi' però ci perdo il gusto :D
Commenti(7) - Posted @ 12/3/2005 1:07:53 AM - Categoria: Useful methods - Permalink - Share on twitter | facebook


COMMENTI
Autore: luca - scritto il 7/17/2007 4:37:00 PM
bello, bravo, tutto bene ... però quando scriviamo del codice con reference strane mettiamole
dov'è? il Thread?

Autore: Straygor - scritto il 9/7/2007 3:28:23 PM
però adesso, se tu fai una differenza tra due date come "anno", la risposta non tiene conto del giorno/mese.
Ovvero se fai 20/09/1977 e 01/09/2007 il risultato è 30.. invece di 29!

Autore: Sergio - scritto il 1/12/2009 3:34:50 PM
DateTime dtThen = new DateTime(anno, mese, giorno);
DateTime dtNow = DateTime.Now;
TimeSpan ts = dtThen - dtNow;

Autore: Sergio - scritto il 1/12/2009 3:35:30 PM
Semplice e funziona sempre !

Autore: Andrea - scritto il 10/7/2009 1:44:12 PM
x Sergio

Non funziona come il DateDiff di VB, TimeSpan calcola i giorni, non gli anni, i mesi di differenza... e non è banale risalirvi con i bisestili in mezzo avendo solo i giorni... Vb è troppo avanti! :)

Autore: Marco - scritto il 3/14/2011 3:38:21 PM
proprio inutile

Autore: Domenico - scritto il 3/26/2011 11:47:37 AM
Marco è molto utile invece.
Se vuoi sapere quanti anni e mesi sono 3284293 giorni come fai?

INSERISCI UN COMMENTO

Nome *
Indirizzo e-mail
(non verrà pubblicato)
Commento *