以 YYYYMMDD 格式计算给定出生日期的年龄

IT技术 javascript date
2021-01-10 03:38:10

给定格式 YYYYMMDD 的出生日期,如何计算以年为单位的年龄?是否可以使用该Date()功能?

我正在寻找比我现在使用的更好的解决方案:

var dob = '19800810';
var year = Number(dob.substr(0, 4));
var month = Number(dob.substr(4, 2)) - 1;
var day = Number(dob.substr(6, 2));
var today = new Date();
var age = today.getFullYear() - year;
if (today.getMonth() < month || (today.getMonth() == month && today.getDate() < day)) {
  age--;
}
alert(age);

6个回答

尝试这个。

function getAge(dateString) {
    var today = new Date();
    var birthDate = new Date(dateString);
    var age = today.getFullYear() - birthDate.getFullYear();
    var m = today.getMonth() - birthDate.getMonth();
    if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
        age--;
    }
    return age;
}

我相信您的代码中唯一看起来粗糙的就是substr零件。

小提琴http : //jsfiddle.net/codeandcloud/n33RJ/

@Dr.G:对我来说,它是63。jsfiddle.net/codeandcloud/o86au3dn请仔细检查你的代码
2021-03-17 03:38:10
你能举一个使用例子吗?如果不修改函数以采用 3 个单独的参数,我就无法让它工作,例如:getAge(y,m,d)。例如:jsbin.com/ehaqiw/1/edit
2021-03-22 03:38:10
@RobG:当leaplings“庆祝”(常见问题的答案其实只是似乎是:“周末最接近实际日期”)在其出生天的不同根据上下文,包括:地理区域(简单的英文:你住的地方),法律(不要小看那个),宗教和个人喜好(包括群体行为):一些原因:“我出生在二月”,其他原因:“我出生在 2 月 28 日的后一天” (最常见的是 3 月 1 日)en.wikipedia.org/wiki/February_29对于以上所有情况,这个算法是正确的,如果 3 月 1 日是人们需要的闰年结果
2021-03-25 03:38:10
@RobG:“加上 x 个月”的粪坑与人类的年龄概念无关。人类的普遍观念是,当日历具有相同的月份#和日期#(与开始日期相比)时,年龄(InYears)-计数器每天都会增加(不考虑时间):因此 2000-02-28 到 2001-02 -27 = 0 年,2000-02-28 到 2001-02-28 = 1 年。将“常识”扩展到跨越:2000-02-29(2000-02-28之后的第二天)到 2001-02-28 =零年我的评论只是指出,如果人们期望/同意这种跳跃逻辑,那么回答的算法总是会给出“正确”的人类答案
2021-03-29 03:38:10
@RobG:我从来没有说过我或答案是普遍正确的(TM)。我包括了上下文/管辖权/观点的概念。我的两个评论都清楚地包含一个大写的IF(针对异常跳跃的处理)。事实上,我的第一条评论准确地表达了我的意思,从未包含任何关于对错的判断。实际上,我的评论澄清了从这个答案中可以期待什么和不期待什么(以及为什么)(正如你所说的“突出问题”)。Ps:2月31日?!?
2021-03-31 03:38:10

我会去提高可读性:

function _calculateAge(birthday) { // birthday is a date
    var ageDifMs = Date.now() - birthday.getTime();
    var ageDate = new Date(ageDifMs); // miliseconds from epoch
    return Math.abs(ageDate.getUTCFullYear() - 1970);
}

免责声明:这也存在精度问题,因此也不能完全信任。它可能会关闭几个小时、几年或在夏令时(取决于时区)。

相反,如果精度非常重要,我会建议为此使用一个库。此外@Naveens post, , 可能是最准确的,因为它不依赖于一天中的时间。


@RobG 我认为从 2000 年 2 月 29 日到 2001 年 2 月 28 日从技术上讲还没有过去一整年,这使您的答案无效。没有意义,2000-02-28 到 2001-02-28 是一年,所以 2000-02-29 到 2001-02-28,肯定是不到一年。
2021-03-10 03:38:10
您没有详细说明“不精确”的含义,我认为其他信息可能会有所帮助。您可以考虑修复问题或删除答案。
2021-03-11 03:38:10
可爱的回答@AndréSnedeHansen 并且速度也很快,因为您没有我的回答中出现的那种疯狂的划分;-) +1 以提高可读性和速度。
2021-03-22 03:38:10
@RobG 其实我做到了。我还指出了比我自己更好的解决方案。我的解决方案以一种易于阅读的方式解决了这个问题,但精度问题很小,但在其目的范围内。
2021-04-01 03:38:10
对于 2000-02-29 到 2001-02-28 之类的日期,这将返回 0 年,而此时它可能应该返回 1。
2021-04-09 03:38:10

重要提示:此答案不能提供 100% 准确的答案,根据日期的不同,它会延迟大约 10-20 小时。

没有更好的解决方案(无论如何不在这些答案中)。- 天真

我当然无法抗拒接受挑战并制作比当前公认的解决方案更快、更短的生日计算器的冲动。我的解决方案的要点是数学很快,所以不是使用分支,而是 javascript 提供的日期模型来计算我们使用美妙的数学的解决方案

答案看起来像这样,运行速度比 naveen 快 65%,而且它更短:

function calcAge(dateString) {
  var birthday = +new Date(dateString);
  return ~~((Date.now() - birthday) / (31557600000));
}

神奇的数字:31557600000 是 24 * 3600 * 365.25 * 1000 这是一年的长度,一年的长度是 365 天和 6 小时是 0.25 天。最后,我给出了最终年龄的结果。

这是基准:http : //jsperf.com/birthday-calculation

要支持 OP 的数据格式,您可以替换+new Date(dateString);
+new Date(d.substr(0, 4), d.substr(4, 2)-1, d.substr(6, 2));

如果你能想出更好的解决方案,请分享!:-)

@FrankJensen 嗨,弗兰克,我也很好奇并找到了这个答案:double tilde converts float to integer Greetings
2021-03-20 03:38:10
这是一个非常酷的解决方案。我看到的唯一问题是dateString参数恰好适合 Date() 构造函数正确解析它。例如,采用YYYYMMDD我在问题中给出格式,它将失败。
2021-03-21 03:38:10
这个答案有一个错误。将您的时钟设置为上午 12:01。在上午 12:01,如果您计算 calcAge('2012-03-27')(今天的日期),您将得到零的答案,即使它应该等于 1。这个错误在整个上午 12:00 都存在。这是由于一年有 365.25 天的错误陈述。它不是。我们处理的是日历年,而不是地球轨道的长度(更准确地说是 365.256363 天)。一年有 365 天,闰年有 366 天。除此之外,在这样的事情上表现是没有意义的。可维护性要重要得多。
2021-03-25 03:38:10
感谢您的解决方案克里斯托弗。我可以问 +new 与 new 相比有什么作用,还有返回中的两个波浪号 (~) 吗?
2021-03-25 03:38:10
@FrankJensen 本质上,波浪号会反转数字(二进制​​值),同时将浮点数转换为整数(落地),因此,两个波浪号为您提供了四舍五入的数字。new Date() 前面的 + 将对象转换为日期对象的整数表示,这也可以用于数字字符串,例如 +'21' === 21
2021-03-29 03:38:10

使用momentjs:

/* The difference, in years, between NOW and 2012-05-07 */
moment().diff(moment('20120507', 'YYYYMMDD'), 'years')
@RicardoPontual 这需要 momentjs,所以不能成为最佳答案。
2021-03-12 03:38:10
@itzmukeshy7 确实,要使答案成为最好的答案,它至少应该需要 jQuery ;)
2021-03-18 03:38:10
@thomaux 我知道这是个玩笑;)
2021-03-26 03:38:10
@thomaux 这完全取决于开发环境!
2021-03-31 03:38:10
@itzmukeshy7 放松,这是个笑话;) 见:meta.stackexchange.com/a/19492/173875
2021-04-02 03:38:10

使用 ES6 清洁单衬溶液:

const getAge = birthDate => Math.floor((new Date() - new Date(birthDate).getTime()) / 3.15576e+10)

// today is 2018-06-13
getAge('1994-06-14') // 23
getAge('1994-06-13') // 24

我使用的年份为 365.25 天(由于闰年为 0.25),分别为 3.15576e+10 毫秒(365.25 * 24 * 60 * 60 * 1000)。

它有几个小时的余量,因此根据用例,它可能不是最佳选择。

非常整洁 - 你能详细说明 3.15576e+10 是什么意思吗?
2021-03-14 03:38:10
是的,最好在函数之前添加以下行: const yearInMs = 3.15576e+10 // Using a year of 365.25 days (because leap years)
2021-04-05 03:38:10
效果很好,但有几个小时的误差。18明天转向的用户实际上是 18 today我知道我不应该提到图书馆,但Day.js工作就像魔术一样。
2021-04-06 03:38:10