首先,请注意new Date(year,1,1) 指的是2 月 1 日,而不是 1 月。 Javascript,遵循 UNIX time_t 约定,从 0 开始编号月份,其想法是您将使用月份编号来索引月份名称数组,而不是直接使用它。所以要构造一个引用 1 月 1 日的 Date 对象,你应该调用new Date(year,0,1)。
其次,取整数天数的差值并转换为年数永远不会得到整数。你应该首先让 Moment 给出年份的差异:
> moment(new Date(2013,0,1)).diff(moment(new Date(2012,0,1)),'year');
1
如果您希望结果包含一年的小数部分而不是截断为整数,请向diff 添加一个真实的第三个参数。这里我们从 7 月算到 1 月:
> moment(new Date(2013,0,1)).diff(moment(new Date(2012,6,1)),'year',true)
0.5
您的方法不起作用,因为日历年不是固定的秒数;要么是 365 天,即 31,536,000 秒,要么是 366 天,即 31,622,400 秒。由于闰年通常每四年发生一次,因此平均日历年为 365.25 天,即 31,557,600 秒;事实上,光年的定义是光在该精确秒数内传播的距离。
但在现代公历中,闰世纪规则意味着一年的平均长度(您必须花费 400 多年才能获得一个完整的周期)实际上要短一些:365.2425 天或 31,556,952 秒。这是 Moment 使用的值,但它仅作为平均值起作用;任何不是 400 年精确倍数的周年纪念日都不会给出整数结果。相反,正如您所发现的,普通年将计为 31,536,000 / 31,556,952 = 0.99933605755085028689843... 一年,而闰年将计为 31,622,400 / 31,556,952 = 1.00207396455779...6 年。>
在您的上一个示例中,您得到了共同年份值,因为您要求的是从 2015 年到 2016 年的年份长度 - 这是 2015 年的长度。如果从 2016 年到 2017 年计算,您会得到预期的飞跃年值:
> moment.duration(moment(new Date(2017,0,1)).diff(moment(new Date(2016,0,1)))).asYears()
1.0020739645577939
更具体地说,只要间隔包括 2 月 29 日,您就会得到闰年长度。因此,如果您要测量连续年份同一日期之间的增量,如果您从闰年前一年的 3 月 1 日到闰年本身的 2 月 28 日之间的任何日期开始,您将得到 366 天。如果从 2 月 29 日开始计算,那当然没有次年的 2 月 29 日;如果您数到 2 月 28 日,您将获得 365 天,如果您数到 3 月 1 日,您将获得 366 天。从闰年的 3 月 1 日开始,到同一日期重复的时间回到 365 天:
> moment.duration(moment(new Date(2016,1,28)).diff(moment(new Date(2015,1,28)))).asYears()
0.9993360575508053
> moment.duration(moment(new Date(2016,2,1)).diff(moment(new Date(2015,2,1)))).asYears()
1.0020739645577939
> moment.duration(moment(new Date(2017,1,28)).diff(moment(new Date(2016,1,28)))).asYears()
1.0020739645577939
> moment.duration(moment(new Date(2017,2,1)).diff(moment(new Date(2016,2,1)))).asYears()
0.9993360575508053