在Javascript中计算年龄(+闰年)?

时间:2013-05-08 08:30:06

标签: javascript math datetime

我已经阅读了这篇question,但有很多评论说有些人认为这是准确的,有些人说它不准确。

无论如何,我在Javascript中使用此代码计算人的年龄:

 function calculateDiffYearByString(date)
    {
        var cur = new Date();
        var diff = (cur.getTime() - new Date(date)) / (60 * 60 * 24 * 1000);
        return diff / 365.242;
    }

现在, 此部分var diff = (cur.getTime() - new Date(date)) / (60 * 60 * 24 * 1000); 确实考虑从开始日期到结束日期的所有实际天数(24小时),包括闰年考虑因素。

它只计算24小时的小组数。 我的问题是关于/ 365.242;

当我问谷歌时,它说:

enter image description here

这就是我将其与365.242分开的原因。

但我认为我错了。因为.242部分是关于闰年的。所以我觉得我恐怕在整体计算中考虑闰年两次 ..

我错了吗?我的计算是100%正确吗?

3 个答案:

答案 0 :(得分:4)

计算不正确,因为假设一年是365.242天。

一年平均为365.242天,但实际年份为365.242天。一年正好是365天或366天(忽略了有些年份有闰秒的小细节。)

要将年龄精确计算为分数年,您必须计算截至上一个生日的整个年数,然后根据当前年份的天数计算当前年份的分数。


您可以使用此类代码计算年内的确切年龄:

function isLeapYear(year) {
    var d = new Date(year, 1, 28);
    d.setDate(d.getDate() + 1);
    return d.getMonth() == 1;
}

function getAge(date) {
    var d = new Date(date), now = new Date();
    var years = now.getFullYear() - d.getFullYear();
    d.setFullYear(d.getFullYear() + years);
    if (d > now) {
        years--;
        d.setFullYear(d.getFullYear() - 1);
    }
    var days = (now.getTime() - d.getTime()) / (3600 * 24 * 1000);
    return years + days / (isLeapYear(now.getFullYear()) ? 366 : 365);
}

var date = '1685-03-21';

alert(getAge(date) + ' years');

演示:http://jsfiddle.net/Guffa/yMxck/

(注意:天数也是一个小数值,所以它会将年龄计算到精确的毫秒。如果你想要整天,你可以在{{1}的计算周围添加Math.floor变量。)

答案 1 :(得分:2)

您的diff计算将为您提供两个日期之间的天数。它将考虑到闰年,因此在4年内它将产生(365 * 4) + 1天。

它也会计算部分天数,所以如果date参数是昨天中午,今天是早上6点那么diff将是0.75

您如何将天数转换为年份取决于您。每年使用365,365.242或365.25天都是合理的。但是,由于你是根据他们的生日计算人们的年龄,我会这样做http://jsfiddle.net/OldPro/hKyBM/

function noon(date) {
    // normalize date to noon that day
    return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 12, 0, 0, 0);
}

// Takes a Date
function getAge(date) {
    var now = noon(new Date()),
        birthday = noon(date),
        thisBirthday = new Date(birthday),
        prevBirthday,
        nextBirthday,
        years,
        partYear,
        msInYear;
    thisBirthday.setFullYear(now.getFullYear());

    if (thisBirthday > now) { // not reached birthday this year
        nextBirthday = thisBirthday;
        prevBirthday = new Date(thisBirthday);
        prevBirthday.setFullYear(now.getFullYear() - 1);
    }
    else {
        nextBirthday = new Date(thisBirthday);
        nextBirthday.setFullYear(now.getFullYear() + 1);
        prevBirthday = thisBirthday;
    }
    years = prevBirthday.getFullYear() - birthday.getFullYear();
    msInYear = nextBirthday - prevBirthday;
    partYear = (now - prevBirthday) / msInYear;

    return years + partYear
}

换句话说,我将分数年计算为自上次生日以来的天数除以上一个生日与下一个生日之间的天数。我想这就是大多数人对生日和岁月的看法。

注意:将日期字符串转换为日期时,您可能会遇到时区问题。像“2013-05-14”这样的短ISO 8601日期被解释为午夜UTC,这使得该日期为5月13日,而不是美国的5月14日以及其他具有负UTC偏移的其他日期。所以要小心。

答案 2 :(得分:1)

你计算太多日期之间的差异的方式会在几天内给你一个结果,并且它确实考虑了闰年。

但是,你的功能是要以年为单位返回一个值,所以你需要将你的单位从几天转换成几年,这个转换需要.242才能准确,所以看起来你的逻辑是合理的。

编辑:为了获得类似于年龄计算器的预期回报,您必须获得两个日期的日期,月份和年份,请使用日期和月份来检查日期是在另一个日期之后还是之前date,然后减去年份并可选择添加1,例如:

function getAge(dateStr) {
  var cur = new Date();
  var tar = new Date(dateStr);

  // Get difference of year
  var age = cur.getFullYear() - tar.getFullYear();

  // If current month is > than birth month he already had a birthday
  if (cur.getMonth() > tar.getMonth()) {
     age ++;
  } 
  // If months are the same but current day is >= than birth day same thing happened 
  else if (cur.getMonth() == tar.getMonth() && cur.getDate() >= tar.getDate()) {
     age ++;
  }

  return age;
}

您可以使用> =或比较小时数来获得更详细的信息,但这对于大多数年龄计算要求来说应该足够了。

基本上,使用.242会从科学的角度给出更精确的结果,但从社会的角度来看年龄计算并不准确。