Moment: isBetweenの排他性/排他性動作の制御

作成日 2015年01月16日  ·  28コメント  ·  ソース: moment/moment

isBetweenメソッドは、モーメントが他の2つの間にあるかどうかをチェックしますが、比較時間のいずれかに等しいかどうかはチェックしません。 包括的引数が必要だと思いますが、現在3番目の引数が単位であるため、別のisBetweenInclusiveメソッドを作成するのが最適な場合があります。

ありがとう

Enhancement Up-For-Grabs

最も参考になるコメント

これは素晴らしい機能であり、絶対に必要でした!!!!

全てのコメント28件

これも欲しいです。

私は同意します、これは信じられないほど便利な機能になるでしょう。 包括的または排他的isBetweenのどちらかを選択できるか、ブール引数として包含を渡すことができるのは素晴らしいことです。

実際には、現在提供されているものや提案されているものよりも、この機能に入る必要があるという考えが少しあります。

実際のシナリオでは、開始値は常に包括的ですが、終了値は_粒度に応じて_包括的または排他的です。 具体的には、値に時間コンポーネントが含まれている場合、最終値は排他的である必要があります。 時間コンポーネントが含まれていない場合は、_包括的_である必要があります。

このように考えてください。 1月1日から1月3日までの日数を尋ねると、答えは3日です。 しかし、1:00から3:00までの時間数を尋ねると、答えは2時間です。 人間は自然にこれを行います。 これは、間隔間の期間の測定方法( 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日までの日数を尋ねると、答えは3日です。 しかし、1:00から3:00までの時間数を尋ねると、答えは2時間です。

日付ライブラリに「1月1日」から「1月3日」までの日数を尋ねると、論理的な(そして私にとっては予想される)答えは「2」だと思います。 その理由は、時刻が指定されていないと、「1月1日00:00」から「1月3日00:00」の間にうまくいくと思います。 人間が現実の世界でどのように違いを理解するかは、実際には文脈に依存しますが、それはプログラミングの世界で物事がどのように機能するかとは何の関係もないと思います。

これがPHPのCarbonでどのように行われるかであり、これが問題になることは一度もありません: https

2番目にマージしたのは、間隔に対して異なる動作を指定したいという人がいることはわかっていましたが、まだ良い提案はありません。 最終的には、両端を個別に構成できます(包括的/排他的かどうか)。

また、現在のバージョンとの下位互換性も必要です。

// 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

開始を除外する実際のシナリオは考えられないので、終了を除外するかどうかのブールフラグにすぎない可能性があります。

ただし、適切なISO 31-11間隔表記に近いため、提案1が好き

// 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:提案1の場合。

正直なところ、どちらか一方を明示的に除外したいが、両方を除外したくないシナリオは見当たりません。 「この日まで」を表示しようとしても、moment(date).endOf( "day")を終了日として使用すると、午後11時59分59秒になります。

ほとんどのプログラミング言語の「通常の」範囲と同じように、包括的/排他的にするためのブールフラグが必要だと思います。 混乱を避けるために簡単にしてください。終了時刻の_直前_が必要な場合は、他の方法で取得できます。

@ mckinnsb-このアプローチは通常、次の2つの理由で回避されます。

  1. 精度が重要になります。 JavaScriptでは、標準日の最後の可能な時間は23:59:59.999ですが、他の言語では23:59:59または23:59:59.9999999ます。 文字列の解析とフォーマットを介して他のソースからの値とやり取りするため、これは重要です。
  2. 00:00:00.000から23:59:59.999までの範囲を定義する場合、範囲の期間を簡単に決定することはできません。 duration = end - startだけでなく、 duration = end - start + epsilonようなことをする必要があります。ここで、上記のように、イプシロンは最小の精度です。

また、ほとんどのプログラミング言語には「通常の」範囲があるというあなたの声明を拒否します。 実際には、多くのプログラミング範囲には組み込みの範囲タイプがありません。 その場合、その動作は言語固有です。 「正常」はありません。

Pythonのrange関数については、このクォーラの投稿も参照してください。

提案1の+1は、物事を柔軟にします。
私の最初の期待は、SQLで行うのと同じように、上限と下限が含まれることと同じでした。XAと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は、すでに3番目のオプションのパラメーターがあります。 現在、このメソッドはfunction isBetween (from, to, units)として定義されていますが、 unitsはオプションです。 この提案は4番目のオプションのパラメーターになるため、実装は2つの可能な3番目のオプション(排他的/包括的vsユニット)または4つすべてを処理する必要があります。

いくつかの回避策(テストされていません):

()= 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))と同じ

3番目と4番目のパラメーターはどちらもオプションであるため、オブジェクトを渡すとよい場合があります

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

デフォルトの単位はミリ秒で、デフォルトの単位は()です。

クラップ..あなたたちは正しいです。 ごめん。 言い換えれば...

これをグラブ用にマークアップします。 予想される使用法は、上記の提案1のようになります。これにより、 '[]''[)''()' 、のいずれかを含む_fourth_オプションパラメータをisBetweenに渡すことができます。 '(]' 。 4つすべてのテストを含める必要があります。 渡されない場合のデフォルトは'()'と同じである必要があります。これは、現在の動作でもあります。

WRTオプション-私は本当に好みがありません。 既知の値に制限されているため、3番目のパラメーターでnullを渡して4番目のパラメーターを取得するか、いずれかの項目を3番目のパラメーターまたは4番目のパラメーターとして渡すことを許可することもできます。 オプションオブジェクトも問題ありません。 実装者が最も簡単だと思うものは何でも-または一体、あなたは上記のすべてを行うことができます。

もちろん、他の誰かがそれについて強い意見を持っていない限り。 :)

PR#2943で良いスタートを切る。 そのPRでこれを追跡します。 ありがとう!

+1

今日@darrenjenningscommitの機能を使用し

これがv2.13で利用可能になることについて話しているのですか? @rbreier
https://momentjs.com/docs/#/query/is -between /

それがまさに私が探していたものです。 どうもありがとう。 私は更新しました、そしてこれは私にとって完全に機能します。

これは素晴らしい機能であり、絶対に必要でした!!!!

2番目にマージしたのは、間隔に対して異なる動作を指定したいという人がいることはわかっていましたが、まだ良い提案はありません。 最終的には、両端を個別に構成できます(包括的/排他的かどうか)。

また、現在のバージョンとの下位互換性も必要です。

// 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'、 "+"));

上記の条件を使用している場合、最初のエラーが発生し、次に条件が失敗します。 私はAngular6を使用しています

このページは役に立ちましたか?
0 / 5 - 0 評価