Moment: Контроль эксклюзивности / эксклюзивности isBetween

Созданный на 16 янв. 2015  ·  28Комментарии  ·  Источник: moment/moment

Метод isBetween проверяет, находится ли момент между двумя другими, но не равен ли он какому-либо из значений времени сравнения. Я думаю, что нам нужен инклюзивный аргумент, хотя, поскольку третий аргумент в настоящее время является единицами, может быть лучше создать отдельный метод isBetweenInclusive.

Спасибо

Enhancement Up-For-Grabs

Самый полезный комментарий

Это была отличная функция и она была абсолютно необходима !!!!

Все 28 Комментарий

Я бы тоже этого хотел.

Я согласен, это была бы невероятно полезная функция. Было бы фантастически иметь возможность выбирать между включающим и исключающим isBetween или передавать включение в качестве логического аргумента.

На самом деле, нужно подумать над этой функцией немного больше, чем то, что предлагается в настоящее время или что предлагается.

В реальных сценариях начальное значение всегда включающее, но конечное значение либо включающее, либо исключающее _ в зависимости от степени детализации_. В частности, если значение включает компонент времени, конечное значение должно быть исключительным. Если он не включает компонент времени, он должен быть _inclusive_.

Подумайте об этом таким образом. Если я спрошу вас, сколько дней осталось с 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 по 3 января, ответ - три дня. Но если я спрошу вас, сколько часов между 1:00 и 3:00, ответ будет два часа.

Я думаю, что логичным (и для меня ожидаемым) ответом будет «2», когда вы задаете в библиотеке дат количество дней между «1 января» и «3 января». Причина в том, что без указания времени, я ожидаю, что он будет работать между «1 января 00:00» и «3 января в 00:00». То, как люди воспринимают разницу в реальном мире, действительно зависит от контекста, но я не думаю, что это имеет какое-либо отношение к тому, как все работает в мире программирования.

Вот как это делается для PHP Carbon, и я никогда не считал, что это проблема: https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Carbon.php#L1070 -1092

Второй, который мы объединили, - это Между собой. Я знал, что некоторые люди захотят указать другое поведение для интервалов, но я еще не видел хорошего предложения. В конечном итоге оба конца будут настраиваться отдельно (независимо от того, являются ли они включающими / исключающими).

Он также должен быть обратно совместим с текущей версией.

// 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: за предложение первое.

Честно говоря, я не вижу сценариев, в которых вы явно хотели бы исключить одну из сторон, но не обе сразу. Даже если вы пытаетесь увидеть «до этого дня», вы можете использовать момент (дата) .endOf («день») в качестве даты окончания, что даст вам 23:59:59.

Я думаю, что должен быть просто логический флаг, чтобы сделать его включающим / исключающим, как "нормальный" диапазон в большинстве языков программирования. Делайте это просто, чтобы избежать путаницы - если вы хотите узнать время, _перед_ времени конца, есть другие способы получить его.

@mckinnsb - этого подхода обычно избегают по двум причинам:

  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 , где epsilon - минимальная точность, как обсуждалось выше.

Я также отклоню ваше утверждение о том, что в большинстве языков программирования существует «нормальный» диапазон. На самом деле, многие диапазоны программирования не имеют встроенных типов диапазонов. Когда они это делают, их поведение зависит от языка. Нет "нормального".

См. Также этот пост о функции range в Python.

+1 за предложение 1, делает вещи гибкими.
Мое первое ожидание было таким же, что будут включены верхний и нижний пределы, точно так же, как я бы сделал в SQL, X между A и 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 является необязательным. Это предложение приводит к 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 (а, б)
[] = 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 , содержащий одно из '[]' , '[)' , '()' , '(]' . Он должен включать тесты для всех четырех. Значение по умолчанию, если оно не передано, должно быть таким же, как '()' , что также является текущим поведением.

НАПИШИТЕ варианты - я действительно не предпочитаю. Можно также передать null в третьем параметре, чтобы получить четвертый, или разрешить передачу любого элемента в качестве третьего или четвертого параметра, поскольку мы ограничены известными значениями. Объект параметров тоже в порядке. Независимо от того, что разработчик считает самым простым - или, черт возьми, вы могли бы сделать все вышеперечисленное.

Если, конечно, кто-то другой не имеет твердого мнения по этому поводу. :)

Хороший старт в PR №2943. Мы проследим это в том PR. Спасибо!

+1

Мне ДЕЙСТВИТЕЛЬНО хотелось бы использовать функциональность в коммите @darrenjennings сегодня.

Вы говорите об этом, доступном в 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 рейтинги