Moment: 控制 isBetween 的排他性/排他性行为

创建于 2015-01-16  ·  28评论  ·  资料来源: moment/moment

isBetween 方法检查一个时刻是否在两个其他时刻之间,但不检查它是否等于任一比较时间。 我认为我们需要一个包含参数,尽管当前第三个参数是单位,但最好创建一个单独的 isBetweenInclusive 方法。

谢谢

Enhancement Up-For-Grabs

最有用的评论

这是一个很棒的功能,绝对需要!!!!

所有28条评论

我也想要这个。

我同意,这将是一个令人难以置信的有用功能。 能够在包含和排除 isBetween 之间进行选择,或者将包含作为布尔参数传递会很棒。

实际上,与当前提供的内容或正在提议的内容相比,此功能需要更多的思考。

在实际场景中,起始值总是包含的,但结束值是包含或不包含的_取决于粒度_。 具体来说,如果该值包含时间分量,则结束值应该是独占的。 如果它不包含时间组件,那么它应该是_inclusive_。

这样想想。 如果我问你 1 月 1 日和 1 月 3 日之间有多少天 - 答案是三天。 但是如果我问你 1:00 到 3:00 之间有多少小时,答案是两个小时。 人类自然会这样做。 它会影响我们如何测量间隔之间的持续时间(例如使用moment#diff ),以及我们如何测试一个值以查看其是否在范围内(例如使用moment#inBetween )。

moment#isBetween的当前行为是完全排他的,与粒度无关。 这不是很有用。

moment#diff的当前行为在开始时是包容的,在结束时是排他的,同样,无论粒度如何。 这对时间有效,错误在几天内无效。 实际上,文档中的示例是:

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') // 1

在现实中,大多数人会期望结果是 2 天。

最终的问题是moment对象是一个谨慎的时间单位,但在很多情况下,我们试图将其视为日历上的日期,这就是副作用开始变得可见的地方。

这样想想。 如果我问你 1 月 1 日和 1 月 3 日之间有多少天 - 答案是三天。 但如果我问你 1:00 到 3:00 之间有多少小时,答案是两个小时。

我认为当向日期库询问“1 月 1 日”和“1 月 3 日”之间的天数时,合乎逻辑的(对我来说也是预期的)答案是“2”。 原因是没有指定时间,我希望它在“1 月 1 日 00:00”和“1 月 3 日 00:00”之间运行。 人类如何解决现实世界中的差异实际上取决于上下文,但我认为这与编程世界中的工作方式无关。

以下是 PHP 的 Carbon 的处理方式,我从未发现这是一个问题: https :

我们合并的第二个是在我知道有些人会想要为间隔指定不同的行为之间,但我还没有看到一个好的建议。 最终,两端都可以单独配置(无论它们是包含的还是不包含的)。

它也应该向后兼容当前版本。

// proposal 1
m.isBetween(a, b, "()"); // both excluded
m.isBetween(a, b, "[)"); // start included, end excluded

// proposal 2
m.isBetween(a, b, "+"); // both included
m.isBetween(a, b, "+-"); // start included, end excluded

我想不出排除开始的真实场景,因此它可能只是一个布尔标志,用于确定是否排除结束。

虽然 - 我有点喜欢建议 1,因为它接近正确的 ISO 31-11间隔符号。 . 如果我们这样做,我想在任何一方都支持这两种选择。

// these are essential
m.isBetween(a, b, "[]"); // both included
m.isBetween(a, b, "[)"); // start included, end excluded

// these would be rarely used, but complete the syntax
m.isBetween(a, b, "()"); // both excluded
m.isBetween(a, b, "(]"); // start excluded, end included

我不太喜欢建议 2。(无意冒犯)

:+1:建议一。

老实说,我看不到任何您明确希望排除任一端而不是两者的情况。 即使您试图查看“直到这一天”,您也可以使用 moment( date ).endOf( "day" ) 作为结束日期,这将为您提供 11:59.59 PM。

我认为应该只有一个布尔标志来使其包含/排除,就像大多数编程语言中的“正常”范围一样。 保持简单以防止混淆 - 如果您想要一个时间_就在_结束时间之前,还有其他方法可以获得它。

@mckinnsb - 通常避免这种方法有两个原因:

  1. 精度变得很重要。 在 JavaScript 中,标准日的最后可能时间是23:59:59.999 ,但在其他语言中可能是23:59:5923:59:59.9999999 。 我们通过字符串解析和格式化与来自其他来源的值进行交互,所以这很重要。
  2. 如果您定义从00:00:00.00023:59:59.999 - 您无法轻松确定该范围的持续时间。 而不是仅仅duration = end - start ,您现在必须执行类似duration = end - start + epsilon ,其中 epsilon 是最小精度,如上所述。

我也会拒绝你的说法,即在大多数编程语言中都有一个“正常”范围。 实际上,许多编程范围没有内置范围类型。 当他们这样做时,他们的行为是特定于语言的。 没有“正常”。

另请参阅这篇关于 Python 中range函数的quora 帖子

+1 建议 1,使事情变得灵活。
我的第一个期望是包含上限和下限,就像我在 SQL 中所做的一样,X 介于 A AND B 之间,
目前通过这个x.isBetween(a, b) || x.isSame(a) || x.isSame(b)

+1

+1

+1 提案 1

+1

+1

+1

@mj1856不是默认行为'()'吗?

Is Between 2.9.0+
"Check if a moment is between two other moments, optionally looking at unit scale (minutes, hours, days, etc). **The match is exclusive.**"

isBetween已经有第三个可选参数。 目前该方法定义为function isBetween (from, to, units) ,其中units是可选的。 该提议导致第四个可选参数,因此实现将必须处理两个可能的第三个选项(独占/包含 vs 单位)或所有四个。

一些解决方法(未测试):

() = x.isBetween(start, end) //完全独占——此时的默认实现
(] = x.isAfter(start) && x.isSameOrBefore(end) //左排,右排
[) = x.isSameOrAfter(start) && x.isBefore(end) //左包含,右排除
[] = !(x.isBefore(a) || x.isAfter(b)) //全包

也许更容易阅读的解决方法是这样的:

() = x.isBetween(a,b)
(] = x.isBetween(a,b) || x.isSame(b)
[) = x.isSame(a) || x.isBetween(a,b)
[] = x.isBetween(a, b) || x.isSame(a) || x.isSame(b) // 与 !(x.isBefore(a) || x.isAfter(b)) 相同

由于第三个和第四个参数都是可选的,因此传入一个对象可能会很好

var options = {
   units: 'milliseconds', // 'year', 'month', etc.
   inclusive: '{)' // '{}', '()', '(}', '{)'
}
m.isBetween(start, end, options)

其中默认单位是毫秒,默认包括()

废话..你们是对的。 对不起。 改写...

标记这个以供争夺。 预期的用法与上面的建议 1 相同,它应该允许将 _fourth_ 可选参数传递给isBetween ,其中包含'[]''[)''()''(]' 。 它应该包括对所有四个的测试。 未通过时的默认值应与'()' ,这也是当前行为。

WRT选项 - 我真的没有偏好。 也可以在第三个参数中传递null以获得第四个参数,或者允许将任一项目作为第三个参数或第四个参数传递,因为我们仅限于已知值。 选项对象也很好。 无论实施者认为什么最简单 - 或者见鬼,您都可以执行上述所有操作。

当然,除非其他人对此有强烈的看法。 :)

PR #2943 的良好开端。 我们将在该公关中跟踪这一点。 谢谢!

+1

我真的很想在今天使用

你是说这个在 v2.13 中可用吗? @rbreier
https://momentjs.com/docs/#/query/is -between/

这正是我正在寻找的。 太感谢了。 我更新了,这对我来说非常有用。

这是一个很棒的功能,绝对需要!!!!

我们合并的第二个是在我知道有些人会想要为间隔指定不同的行为之间,但我还没有看到一个好的建议。 最终,两端都可以单独配置(无论它们是包含的还是不包含的)。

它也应该向后兼容当前版本。

// proposal 1
m.isBetween(a, b, "()"); // both excluded
m.isBetween(a, b, "[)"); // start included, end excluded

// proposal 2
m.isBetween(a, b, "+"); // both included
m.isBetween(a, b, "+-"); // start included, end excluded

console.log('isBetweenFlag', moment('2010-10-19').isBetween('2010-10-19', '2010-10-25',"+"));

当我使用上述条件时,它让我第一个错误,然后条件将失败。 我正在使用角度 6

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

相关问题

benhathaway picture benhathaway  ·  3评论

M-Zuber picture M-Zuber  ·  3评论

4rg0n picture 4rg0n  ·  3评论

nikocraft picture nikocraft  ·  3评论

tanepiper picture tanepiper  ·  3评论