JavaScript Date Difference, accounting for Leap Years

Discussion in 'Javascript' started by jamesyreid@hotmail.com, Jun 19, 2006.

  1. Guest

    Hi,

    I'm really sorry to post this as I know it must have been asked
    countless times before, but I can't find an answer anywhere.

    Does anyone have a snippet of JavaScript code I could borrow which
    calculated the difference in years and days between two dates, and
    takes leap years into account?

    I'm calculating the difference in the usual way, i.e....

    var difference = dateTo.getTime() - dateFrom.getTime();

    ....and converting this millisecond value into days by using...

    var daysDifference = (difference/1000/60/60/24);

    But how do I then display the difference in days AND years? I've tried
    the following:

    var yearsDifference = Math.floor(daysDifference/365.25);
    var daysLeft = Math.floor(daysDifference-(yearsDifference*365.25));

    ....but it gives me inaccuracies. For example, if I use my code to
    calculate the difference between 05/01/1998 and 05/01/2000 it returns 1
    year and 364 days!

    Any assistance would be gratefully received!
     
    , Jun 19, 2006
    #1
    1. Advertising

  2. writes:

    > Does anyone have a snippet of JavaScript code I could borrow which
    > calculated the difference in years and days between two dates, and
    > takes leap years into account?


    That requires a more precise description of what you want.

    > I'm calculating the difference in the usual way, i.e....
    >
    > var difference = dateTo.getTime() - dateFrom.getTime();
    >
    > ...and converting this millisecond value into days by using...
    >
    > var daysDifference = (difference/1000/60/60/24);


    This fails if the dates are using local time and the difference
    crosses a daylight saving time boundary (i.e., a day that is not
    24 hours long). At least round it to the nearest integer.

    > But how do I then display the difference in days AND years?


    How many days and years are there between
    2004-02-28 and 2005-02-28 ?
    How many days and years between
    2004-02-29 and 2005-02-28 ?
    How many days and years between
    2004-02-29 and 2005-03-01 ?

    My immediate guesses would be, respectively:
    one year, zero days
    zero years, 365 days
    one year, one day

    How come moving both the start date and the end date one day forwards
    changes the distance between them?

    And what is the day that is one year and zero days after 2004-02-29?
    If there is no day that is one year and zero days after 2004-02-29,
    how long is a year?


    The problem I'm trying to illustrate is that you are talking about
    periods of some years and some days, when years are not a fixed number
    of days.


    > I've tried the following:
    >
    > var yearsDifference = Math.floor(daysDifference/365.25);
    > var daysLeft = Math.floor(daysDifference-(yearsDifference*365.25));
    >
    > ...but it gives me inaccuracies.


    That's a matter of definition :)

    > For example, if I use my code to calculate the difference between
    > 05/01/1998 and 05/01/2000 it returns 1 year and 364 days!


    Unsurpricingly. You are defining a year to be 365.25 days. The
    exact result would be a difference of one year and 364.75 days.
    Then you decide to round the days, but "one year" is still not
    a whole number of days.

    > Any assistance would be gratefully received!


    What do you need it for?

    A quick google gives <URL:http://www.merlyn.demon.co.uk/js-date1.htm#DYD>

    A specification of an algorithm could be:

    One whole number of years after a specific date ends on the same date
    on a later year, or, if that date does not exist (i.e., it's Feb
    29th), the first following date that does (Mar 1st).

    The distance in years and days between two dates is the largest
    number of whole years after the earlier date that is still less than
    the larger date, plus the number of days from that date to the end
    date.

    So, algorithm:
    ----
    function YDDiff(years,days) {
    this.years = years;
    this.days = days;
    }
    YDDiff.prototype.toString = function() {
    return this.years + "y" + this.days +"d";
    };

    function diffYearAndDate(d1,d2) {
    // ensure d1 <= d2
    if (d1 > d2) { return diffYearAndDate(d2,d1); }

    // find n whole years later than d1 in d2's year.
    var dt = new Date(d1);
    dt.setFullYear(d2.getFullYear());
    // n whole years later > d2
    var overflow = (dt > d2);
    // max whole years later than d1 less than d2
    dt = new Date(d1);
    dt.setFullYear(d2.getFullYear() - overflow);
    // whole years from d1 to dt
    var years = dt.getFullYear() - d1.getFullYear();
    // days from dt to d2, less than whole year from dt
    var days = Math.round((d2 - dt)/864e5);
    return new YDDiff(years,days);
    }
    ----

    Now you'll just have to see if that is what you really need :)

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
     
    Lasse Reichstein Nielsen, Jun 19, 2006
    #2
    1. Advertising

  3. JRS: In article <>
    , dated Mon, 19 Jun 2006 08:06:17 remote, seen in
    news:comp.lang.javascript, posted :

    >I'm really sorry to post this as I know it must have been asked
    >countless times before, but I can't find an answer anywhere.


    Then you are an unskilful looker.

    >Does anyone have a snippet of JavaScript code I could borrow which
    >calculated the difference in years and days between two dates, and
    >takes leap years into account?
    >
    >I'm calculating the difference in the usual way, i.e....
    >
    >var difference = dateTo.getTime() - dateFrom.getTime();


    Usual? but nowadays many people know better. That gives the difference
    in absolute time (ignoring Leap Seconds).

    >...and converting this millisecond value into days by using...
    >
    >var daysDifference = (difference/1000/60/60/24);


    864e5 is easier to write than 1000/60/60/24. However, one cannot rely
    on civil days all being of that length.

    >But how do I then display the difference in days AND years? I've tried
    >the following:
    >
    >var yearsDifference = Math.floor(daysDifference/365.25);
    >var daysLeft = Math.floor(daysDifference-(yearsDifference*365.25));
    >
    >...but it gives me inaccuracies. For example, if I use my code to
    >calculate the difference between 05/01/1998 and 05/01/2000 it returns 1
    >year and 364 days!


    But what are those dates? This is an international newsgroup, and dates
    need to be presented unambiguously. Generally, the daycount difference
    for those dates is 730 days; but where FFF is used it is 731 days.

    >Any assistance would be gratefully received!


    You should have read the newsgroup FAQ before asking. Be aware that
    Google did not invent newsgroups, which was done long before the Web
    appeared; they merely provide an inferior interface, and do not give
    adequate guidance in the established use of News.


    Since the number of days in a year is not constant, there can be no one
    correct answer. One can count the full years in the interval from the
    beginning, and see how many days are left. Or one can do it in reverse.
    Or one can determine the daycount difference, and do some approximation
    to a rounded div/mod 365.25 or 365.2425. Or ...? The different methods
    will, for at least some date combinations, give different answers. One
    method is in js-date1.htm on my site.

    If this is coursework, then, if the instructor is intelligent (one
    cannot rely on that), the point of interest should be how thoughtfully
    you treat the difficulties.

    But if it is a real-world application, the originators of the situation
    should have given an unambiguous indication of how the results should be
    obtained.

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
    <URL:http://www.jibbering.com/faq/>? JL/RC: FAQ of news:comp.lang.javascript
    <URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
    <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
     
    Dr John Stockton, Jun 19, 2006
    #3
  4. JRS: In article <>, dated Mon, 19 Jun 2006
    20:46:04 remote, seen in news:comp.lang.javascript, Lasse Reichstein
    Nielsen <> posted :

    > function diffYearAndDate(d1,d2) {
    > // ensure d1 <= d2
    > if (d1 > d2) { return diffYearAndDate(d2,d1); }
    >
    > // find n whole years later than d1 in d2's year.
    > var dt = new Date(d1);
    > dt.setFullYear(d2.getFullYear());
    > // n whole years later > d2
    > var overflow = (dt > d2);
    > // max whole years later than d1 less than d2
    > dt = new Date(d1);
    > dt.setFullYear(d2.getFullYear() - overflow);
    > // whole years from d1 to dt
    > var years = dt.getFullYear() - d1.getFullYear();
    > // days from dt to d2, less than whole year from dt
    > var days = Math.round((d2 - dt)/864e5);
    > return new YDDiff(years,days);
    > }



    Using dt = new Date(d1) does not always give an Object dt
    representing the same date as d1, since 1900 years may be added.

    I think it noticeably slower than dt = new Date(+d1)
    but dt = new Date(d1.valueOf()) has seemed slightly faster still.


    When using Date Objects, one must be careful of Time :

    diffYearAndDate(new Date(2000, 1, 1, 07), new Date(2001, 1, 1, 12))
    -> 1y0d
    diffYearAndDate(new Date(2000, 1, 1, 17), new Date(2001, 1, 1, 12))
    -> 0y366d

    though it is at least arguable that the calculation *should* do that,
    the difference might be unexpected.

    I've put a version of that in
    <URL:http://www.merlyn.demon.co.uk/js-date1.htm#DYD> and have as yet
    found no disagreement with the existing code which starts with date
    strings and makes less use of Date Objects (the test is flawed (at least
    in IE4) for years 0..69 AD).

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
    Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
    PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
    Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.
     
    Dr John Stockton, Jun 20, 2006
    #4
  5. Dr John Stockton <> writes:

    > Using dt = new Date(d1) does not always give an Object dt
    > representing the same date as d1, since 1900 years may be added.


    Indeed. My mistake was assuming the conversion to a primitive
    value would become a number, not a string. After checking, I
    can see that is not the case.

    > I think it noticeably slower than dt = new Date(+d1)
    > but dt = new Date(d1.valueOf()) has seemed slightly faster still.


    The latter is also a little more readable.

    > When using Date Objects, one must be careful of Time :
    >
    > diffYearAndDate(new Date(2000, 1, 1, 07), new Date(2001, 1, 1, 12))
    > -> 1y0d
    > diffYearAndDate(new Date(2000, 1, 1, 17), new Date(2001, 1, 1, 12))
    > -> 0y366d
    >
    > though it is at least arguable that the calculation *should* do that,
    > the difference might be unexpected.


    True. A more reasonable behavior would be to ignore time by doing
    setHours(0,0,0,0) on the dates before starting the calculation.

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
     
    Lasse Reichstein Nielsen, Jun 20, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hai Nguyen

    Date Validation Expression and Leap Year

    Hai Nguyen, Feb 26, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    3,327
    Hans Kesting
    Feb 27, 2004
  2. Peter Grison

    Date, date date date....

    Peter Grison, May 28, 2004, in forum: Java
    Replies:
    10
    Views:
    3,301
    Michael Borgwardt
    May 30, 2004
  3. Shiloh Madsen
    Replies:
    8
    Views:
    143
    Peña, Botp
    Nov 8, 2006
  4. David Woodward
    Replies:
    5
    Views:
    404
    Dr John Stockton
    Feb 2, 2004
  5. Dr John Stockton

    Leap Seconds in Javascript

    Dr John Stockton, Jan 18, 2006, in forum: Javascript
    Replies:
    2
    Views:
    111
    Dr John Stockton
    Jan 20, 2006
Loading...

Share This Page