Moment: 它是 .add() 或 .subtract() 浮点值的一种方法吗?

创建于 2015-06-20  ·  3评论  ·  资料来源: moment/moment

moment().add(1, "months") // >> Mon Jul 20 2015 13:36:12 GMT+0200
moment().add(1.9, "months") // >> Mon Jul 20 2015 13:36:12 GMT+0200
// Excpected: Mon Aug 17 2015 09:34:37 GMT+0200

现在,我必须这样做:

var duration = moment.duration(1.9, "months"); 
var ms = duration.asMilliseconds();
var date = moment().add(ms, "ms");

为什么这些方法不能添加或减去浮点值?

最有用的评论

这是设计使然,但可能可以在文档中更好地解释。

在加减小时、分钟、秒或毫秒时可以使用小数,但不能细分天或更大的分量。

原因是时间数学和日期数学之间存在逻辑差异。

时间数学假设一个线性时间尺度,只是增加或减少基于 UTC 的时间戳。 这会实时处理 DST 转换。 例如,对于美国的大多数地方, 2015-03-08T01:00:00加上一小时将是2015-03-08T03:00:00因为 DST 转换跳过了从 2:00 到 3:00 的小时。

日期数学不使用线性时间刻度,而是使用日历上的日期。 使用相同的示例, 2015-03-08T01:00:00加上一个 _day_ 将是2015-03-09T01:00:00 ,即使只过去了 23 小时。 因此,“一天”是这个上下文不是固定的时间量,因此细分它是无意义的。 (半天是12小时后,还是11.5小时后这一天?)

即使没有 DST,请考虑并非所有月份都是 30 天,也不是所有年份都是 365 天。 “加”一年,并不是真正的“加365天”,它的意思是“将日历上的位置提前到下一年的同一个月和同一天”。 这会产生某些歧义,例如在闰年中将一年添加到 2 月 29 日并以非闰年结束。 我们选择 2 月 28 日登陆,但 3 月 1 日登陆同样有效。

再举一个例子,假设 8 月 31 日加上一个月,再减去一个月,就是 8 月 30 日。

由于日期数学不遵循数学的正常加减法规则,它也无法处理除法或乘法运算,因此不能将 1.9 个月相加。

换一种方式思考,您预计 6 月 15 日午夜 + 1.5 个月的结果是什么? 以下任何一项都可以由人类完成:

  • 2015-06-15T00:00 +(0.5 * 6 月 30 天)= 2015-06-30T00:00 +(1 个月 = 30 天)= 2015-07-30T00:00
  • 2015-06-15T00:00 +(0.5 * 6 月 30 天)= 2015-06-30T00:00 +(1 个月 = 31 天)= 2015-07-31T00:00
  • 2015-06-15T00:00 + 1 个月 = 2015-07-15T00:00 +(0.5 * 7 月的 31 天)= 2015-07-30T12:00
  • 2015-06-15T00:00 + [(6 月和 7 月的 61 天 / 2 = 这几个月平均 30.5 天)* 1.5 个月 = 45.75 天] = 2015-07-30T18:00

所以这里有四个不同的答案,它们都是合乎逻辑的结果——这就是为什么在做日期数学时你不能细分单位。

所有3条评论

这是设计使然,但可能可以在文档中更好地解释。

在加减小时、分钟、秒或毫秒时可以使用小数,但不能细分天或更大的分量。

原因是时间数学和日期数学之间存在逻辑差异。

时间数学假设一个线性时间尺度,只是增加或减少基于 UTC 的时间戳。 这会实时处理 DST 转换。 例如,对于美国的大多数地方, 2015-03-08T01:00:00加上一小时将是2015-03-08T03:00:00因为 DST 转换跳过了从 2:00 到 3:00 的小时。

日期数学不使用线性时间刻度,而是使用日历上的日期。 使用相同的示例, 2015-03-08T01:00:00加上一个 _day_ 将是2015-03-09T01:00:00 ,即使只过去了 23 小时。 因此,“一天”是这个上下文不是固定的时间量,因此细分它是无意义的。 (半天是12小时后,还是11.5小时后这一天?)

即使没有 DST,请考虑并非所有月份都是 30 天,也不是所有年份都是 365 天。 “加”一年,并不是真正的“加365天”,它的意思是“将日历上的位置提前到下一年的同一个月和同一天”。 这会产生某些歧义,例如在闰年中将一年添加到 2 月 29 日并以非闰年结束。 我们选择 2 月 28 日登陆,但 3 月 1 日登陆同样有效。

再举一个例子,假设 8 月 31 日加上一个月,再减去一个月,就是 8 月 30 日。

由于日期数学不遵循数学的正常加减法规则,它也无法处理除法或乘法运算,因此不能将 1.9 个月相加。

换一种方式思考,您预计 6 月 15 日午夜 + 1.5 个月的结果是什么? 以下任何一项都可以由人类完成:

  • 2015-06-15T00:00 +(0.5 * 6 月 30 天)= 2015-06-30T00:00 +(1 个月 = 30 天)= 2015-07-30T00:00
  • 2015-06-15T00:00 +(0.5 * 6 月 30 天)= 2015-06-30T00:00 +(1 个月 = 31 天)= 2015-07-31T00:00
  • 2015-06-15T00:00 + 1 个月 = 2015-07-15T00:00 +(0.5 * 7 月的 31 天)= 2015-07-30T12:00
  • 2015-06-15T00:00 + [(6 月和 7 月的 61 天 / 2 = 这几个月平均 30.5 天)* 1.5 个月 = 45.75 天] = 2015-07-30T18:00

所以这里有四个不同的答案,它们都是合乎逻辑的结果——这就是为什么在做日期数学时你不能细分单位。

非常感谢您花时间写出这个非常详细的答案。 我更好地理解了这些功能运行背后的逻辑。

我无法抗拒自己对马特的感谢,我遇到了德尔根遇到的同样问题,伙计! 你的回答太完整了,谢谢。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

RobinvanderVliet picture RobinvanderVliet  ·  3评论

IbraheemAlSaady picture IbraheemAlSaady  ·  3评论

dogukankotan picture dogukankotan  ·  3评论

Shoroh picture Shoroh  ·  3评论

vbullinger picture vbullinger  ·  3评论