Calculate the exact differences between 2 given dates

TimeSpan supports only up to Days.

How best to get the exact differences between 2 dates in years, months, and days I searched online and most methods only provide the average by assuming number of months or numbers of years and such.



Answer this question

Calculate the exact differences between 2 given dates

  • Vikasumit

    Like so. For both the first and the second year (or whatever largest scale you choose), subtract off the number of ticks from its minor units to the first occurrence of that largest scale value. In my case, subtract off the number of ticks from its minor units to midnight January 1 of that year. Compare the two values, and if the last value is smaller than the first, you should decrement the resultant largest scale by 1.

    protected float GrowthRate(float dtStartYrOA, float dtEndYrOA, float fCompoundedRate)
    {
    float retVal = 1;

    DateTime dtStartYr = DateTime.FromOADate(dtStartYrOA);
    DateTime dtEndYr = DateTime.FromOADate(dtEndYrOA);

    ushort iStartYr = 0, iEndYr = 0;
    if (
    dtEndYr - new DateTime(iEndYr = (ushort)dtEndYr.Year, 1, 1, 0, 0, 0)
    < dtStartYr - new DateTime(iStartYr = (ushort)dtStartYr.Year, 1, 1, 0, 0, 0)
    )
    --iEndYr;

    for (ushort i = (ushort)iStartYr; i <= iEndYr; ++i) retVal += retVal * fCompoundedRate;
    return retVal;
    }


  • jcarlos.net

    DateDiff won't work, because according to the documentation:

    When comparing December 31 to January 1 of the immediately succeeding year, DateDiff for Year ("yyyy") returns 1 even though only a day has elapsed.

    Try this function. It could be faster, but it seems to work for the tests I have made for it (it assumes y comes after x):

    Public Sub DateSpace(ByVal x As Date, ByVal y As Date, ByRef years As Integer, ByRef months As Integer, ByRef days As Integer)
    x = x.Date
    y = y.Date

    years = y.Year - x.Year
    x = x.AddYears(years)
    If x > y Then
    x = x.AddYears(-1)
    years -= 1
    End If

    months = 0
    Do
    x = x.AddMonths(1)
    months += 1
    Loop While x <= y

    months -= 1
    x = x.AddMonths(-1)

    days = 0
    Do
    x = x.AddDays(1)
    days += 1
    Loop While x <= y

    days -= 1
    End Sub

    Example use:

    Public Sub Main()

    Dim y As Integer = 0, m As Integer = 0, d As Integer = 0

    DateSpace(#2/2/2000#, #1/1/2001#, y, m, d)
    Console.WriteLine("{0}y {1}m {2}d", y, m, d)

    DateSpace(#2/1/2000#, #1/1/2001#, y, m, d)
    Console.WriteLine("{0}y {1}m {2}d", y, m, d)

    DateSpace(#11/1/2000#, #1/1/2001#, y, m, d)
    Console.WriteLine("{0}y {1}m {2}d", y, m, d)

    DateSpace(#12/31/2000#, #1/1/2001#, y, m, d)
    Console.WriteLine("{0}y {1}m {2}d", y, m, d)

    DateSpace(#12/31/2000#, #12/31/2000#, y, m, d)
    Console.WriteLine("{0}y {1}m {2}d", y, m, d)

    DateSpace(#2/29/2000#, #3/1/2001#, y, m, d)
    Console.WriteLine("{0}y {1}m {2}d", y, m, d)

    Console.ReadKey()
    End Sub


  • pvulcan

    Why make it so complicated Simply use: dtStartYr.AddTicks((dtEndYr - dtStartYr).Ticks)

  • Abhishekbhadouria

    no idea if this would work, just a suggestion, when calculated your TimeSpan value, why dont you take the ticks and place that in the constructor of a new dateTime object Example:

    Dim dateTime1 as DateTime = DateTime.Now

    Dim dateTime2 as DateTime = DateTime.Now.AddYears(3)

    Dim diff as TimeSpan = dateTime2 - dateTime1

    Dim dateTimeDiff as new DateTime(diff.Ticks)



  • Nep23

    Thanks for the advice! I will make changes right away. Also which code should I use in terms of performance... wise...
  • madsurfman

    Thank you for a very useful post through I haven't tried it yet. Actually with the answers and all the research I done, I decided to write my own code and this is what I came up with:

    sDay = oDateTime.Day

    eDay = Now.Day

    sMonth = oDateTime.Month

    eMonth = Now.Month

    sYear = oDateTime.Year

    eYear = Now.Year

    tYears = eYear - sYear

    If eMonth >= sMonth Then

    tMonths = eMonth - sMonth

    Else

    tYears -= 1

    tMonths = (12 - sMonth) + eMonth

    End If

    If eDay >= sDay Then

    tDays = eDay - sDay

    Else

    tMonths -= 1

    tDays = (DateTime.DaysInMonth(sYear, sMonth) - sDay) + eDay

    End If

    Through, I don't know if it works for all cases. May be someone can give a say on that. (By the way it just compares between now and the given time)


  • Mike Strobel

    This may not be of concern, but if this were to execute while the current month changed, you would be in trouble, because eDay would be 30 while eMonth would be 12, even though it's only Midnight on 12/1. Try this:

    With Now ' grab a copy of "Now" so we ignore any changes that happen

    eDay = .Day

    eMonth = .Month

    eYear = .Year

    End With


  • canadian_coder

    Try using the built in function to calculate the difference!

    DateAndTime.DateDiff (DateInterval, DateTime, DateTime, FirstDayOfWeek, FirstWeekOfYear)


  • Angel David Lara

    ahmedilyas wrote:

    no idea if this would work, just a suggestion, when calculated your TimeSpan value, why dont you take the ticks and place that in the constructor of a new dateTime object Example:

    Dim dateTime1 as DateTime = DateTime.Now

    Dim dateTime2 as DateTime = DateTime.Now.AddYears(3)

    Dim diff as TimeSpan = dateTime2 - dateTime1

    Dim dateTimeDiff as new DateTime(diff.Ticks)

    First time I saw something like this! Thanks. I tried it and it seems to work as long as I subtract 1 from Year, Month, and Day!!

    Thanks again!


  • Repi3

    Ti, yours is better because it doesn't have any loops.
  • programmer01

    Try the "DateDiff" function. Look it up in Help. It should cover your need.


  • danadanny

    I implemented it and tested it. This method will not get the exact differences because with the Ticks, it contains no information about the months and the years in between so when converted back to datetime it would not be accurate.

    I tried today when getting the differences between 11/26/2006 and 9/26/2006, it would returns 2 months 2 days. The margin of error is too large.

    I need a way to get pretty much "exact" differences taken into account leapyears, different no. of days in months, and such.


  • Devin

    If it does, I probably not posting this but it doesn't because it would return in either totaldays, total... whatever not separately as I am looking for.

    Unless you tell me it can returns x years x months x days ....

    I think they should consider adding DateSpan or something like that


  • PeterVrenken

    This stuff really helped, I've used it and I have a bug fix too...

    Take a From date of "05 Dec 2006 17:00" and a To date of "7 Dec 2006 05:00". The code as you currently have it gives 2 days. However if you look closer at the time it is only 1 day and 12 hrs. My fix is this if statement after days are calculated

    if (this.toDate.Hour < this.fromDate.Hour)

    {

    // Not a full day so subtract fom the calculated days

    this.calculatedWholeDays--;

    }

    HTH

    Pat


  • Calculate the exact differences between 2 given dates