Moment.js: дата между датами

118

Я пытаюсь определить с помощью Moment.js, если заданная дата находится между двумя датами. Начиная с версии 2.0.0, Тим добавил isBefore()и isAfter()для сравнения дат.

Поскольку isBetween()метода нет , я подумал, что это сработает:

var date = moment("15/02/2013", "DD/MM/YYYY");
var startDate = moment("12/01/2013", "DD/MM/YYYY");
var endDate = moment("15/01/2013", "DD/MM/YYYY");

if (date.isBefore(endDate) && date.isAfter(startDate) || (date.isSame(startDate) || date.isSame(endDate)) ) { alert("Yay!"); } else { alert("Nay! :("); }

Я убежден, что должен быть лучший способ сделать это. Любые идеи?

Джоэл А. Вильярреал Бертольди
источник
Я уверен, что вы хотели ? isBetween || isStart || isEnd
Берги
Да, опечатка, извини!
Джоэл А. Вильярреал Бертольди

Ответы:

81

Вы можете использовать один из моментов плагина -> момента дальности дела с диапазоном дат:

var startDate = new Date(2013, 1, 12)
  , endDate   = new Date(2013, 1, 15)
  , date  = new Date(2013, 2, 15)
  , range = moment().range(startDate, endDate);

range.contains(date); // false
Лукаш Козиара
источник
1
как включить плагин?
2
Вы должны просто включить <script src = "/ javascripts / moment-range.js"> </script> после momentjs
Лукаш Козиара
54
date.isBetween (startDate, endDate); намного проще и не требует дополнительных плагинов.
Брендан Ни
moment & moment-Range предоставляет параметры для форматирования даты и времени при подготовке диапазонов, а затем сравнивает даты для Contains / Within / Overlaps / Intersect / Add / Subtract. если кто-то получает даты в каком-то специальном формате, тогда можно подготовить диапазоны дат внутри массива, преобразовав эти даты в требуемый формат, а затем мы можем сравнить.
Саджад Али Хан,
278

В версиях 2.9+ есть isBetweenфункция, но эксклюзивная:

var compareDate = moment("15/02/2013", "DD/MM/YYYY");
var startDate   = moment("12/01/2013", "DD/MM/YYYY");
var endDate     = moment("15/01/2013", "DD/MM/YYYY");

// omitting the optional third parameter, 'units'
compareDate.isBetween(startDate, endDate); //false in this case

Есть обходной путь ...
x.isBetween(a, b) || x.isSame(a) || x.isSame(b)

... что логически эквивалентно
!(x.isBefore(a) || x.isAfter(b))


В версии 2.13 у isBetweenфункции есть четвертый необязательный параметр inclusivity.

Используйте это так:

target.isBetween(start, finish, 'days', '()') // default exclusive
target.isBetween(start, finish, 'days', '(]') // right inclusive
target.isBetween(start, finish, 'days', '[)') // left inclusive
target.isBetween(start, finish, 'days', '[]') // all inclusive

Дополнительные единицы для рассмотрения: years, months, days, hours, minutes, seconds, milliseconds

Примечание: единицы измерения по-прежнему необязательны. Используйте nullв качестве третьего аргумента, чтобы игнорировать единицы измерения, и в этом случае миллисекунды являются детализацией по умолчанию.

Посетите официальные документы

ThisClark
источник
4
помните, что, как указано в документах, isBetween является эксклюзивным
Хоакин Л. Роблес
x.isBetween(moment(a).subtract(1, 'day'), b)похоже, тоже делает свое дело.
Джеймс Доннелли
@ThisClark Это хорошее решение; Могу я предложить другой !(x.isBefore(a) || x.isAfter(b))
вариант
Что exclusiveзначит?
Бэтмен,
2
@Batman Рассмотрим список 1,2,3,4,5. Исключительно, 1 и 5 не находятся между значениями этого списка. Включительно 1 и 5 находятся между значениями этого списка. Включая слева (то же, что и
исключая
27

Ты можешь использовать

moment().isSameOrBefore(Moment|String|Number|Date|Array);
moment().isSameOrAfter(Moment|String|Number|Date|Array);

или

moment().isBetween(moment-like, moment-like);

Смотрите здесь: http://momentjs.com/docs/#/query/

Виджай Махерия
источник
2
Примечание: isBetweenтребуется момент 2.13.0. momentjs.com/docs/#/query/is-between
Алекс Джонсон
16

Я верю в это

if (startDate <= date && date <= endDate) {
  alert("Yay");
} else {
  alert("Nay! :("); 
}

тоже работает ...

Тиле Деклерк
источник
Этот расчет всегда игнорирует год. Например, если я дам startDate = '05 -01-2019 ', endDate = '05 -31-2019' и дату как '05 -21-2017 ', он даст мне результат как "Yay", хотя это ложь. ,
Аакаш Маурья
1
@AakashMaurya Вы сравниваете строки, а не даты. Убедитесь, что вы определили startDate / endDate как startDate = new Date ("05-01-2019").
Tiele Declercq
13

Хорошие новости всем, есть isBetweenфункция! Обновите свою библиотеку;)

http://momentjs.com/docs/#/query/is-between/

Luna
источник
2
Верно, но isBetweenне исчерпывающе
Epoc
4
Версия 2.13.0 вводит эксклюзивность. [Указывает на включение значения. A (означает исключение. Если используется параметр инклюзивности, должны быть пройдены оба индикатора.moment('2016-10-30').isBetween('2016-10-30', '2016-10-30', null, '[]'); //true
Рамратан Гупта
8

Используйте 4-й параметр функции moment.isBetween (инклюзивность). Пример:

var startDate = moment("15/02/2013", "DD/MM/YYYY");
var endDate = moment("20/02/2013", "DD/MM/YYYY");

var testDate = moment("15/02/2013", "DD/MM/YYYY");

testDate.isBetween(startDate, endDate, 'days', true); // will return true
testDate.isBetween(startDate, endDate, 'days', false); // will return false
Рафаэль Бечара Рамех
источник
5
if (date.isBefore(endDate) 
 && date.isAfter(startDate) 
 || (date.isSame(startDate) || date.isSame(endDate))

логически то же самое, что

if (!(date.isBefore(startDate) || date.isAfter(endDate)))

что сэкономит вам пару строк кода и (в некоторых случаях) вызовы методов.

Может быть проще, чем вставлять весь плагин, если вы хотите сделать это всего один или два раза.

Джейми Хамфрис
источник
1

Согласно документации момента js,

Существует плагин Precise Range, написанный Робом Доусоном, который можно использовать для отображения точных, удобочитаемых представлений диапазонов дат / времени, URL: http://codebox.org.uk/pages/moment-date-range-plugin

moment("2014-01-01 12:00:00").preciseDiff("2015-03-04 16:05:06");
// 1 year 2 months 3 days 4 hours 5 minutes 6 seconds

moment.preciseDiff("2014-01-01 12:00:00", "2014-04-20 12:00:00");
// 3 months 19 days
Мохаммед Сафир
источник