7

我读过这个问题,但有很多评论,有些人说它是准确的,有些人说它不准确。

无论如何,我有这段代码可以在 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;

当我问谷歌时,它说:

在此处输入图像描述

这就是为什么我用 365.242 来划分它。

但我认为我错了。因为(恕我直言)这.242部分是关于闰年的。所以我想我担心闰年在整体计算中被考虑了两次..

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

4

3 回答 3

8

计算不正确,因为假设一年是 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/

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

于 2013-05-08T08:56:11.380 回答
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 偏移量的地方。所以要小心。

于 2013-05-14T18:56:25.517 回答
1

您计算日期之间差异的方式将以天为单位给出结果,并且确实考虑了闰年。

但是,您的函数旨在以年为单位返回一个值,因此您需要将单位从天转换为年,此转换需要 .242 才能准确,因此您的逻辑似乎是合理的。

编辑:为了获得类似于年龄计算器预期的回报,您必须获取两个日期的日、月和年,使用日和月来检查日期是在另一个日期之后还是之前,并且然后减去年份并可选择加 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 会给你一个更准确的结果,但是从社会的角度来看,年龄计算并不准确。

于 2013-05-08T08:47:49.963 回答