Il blog di Giuseppe Marchi - SharePoint MVP
NAVIGATION - SEARCH

Metodo DateDiff in C#, corretto

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
blog comments powered by Disqus