Moment.js: data entre as datas

118

Estou tentando detectar com Moment.js se uma determinada data está entre duas datas. Desde a versão 2.0.0, Tim adicionou isBefore()e isAfter()para comparação de datas.

Como não há isBetween()método, achei que isso funcionaria:

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! :("); }

Estou convencido de que deve haver uma maneira melhor de fazer isso. Alguma ideia?

Joel A. Villarreal Bertoldi
fonte
Estou confiante de que você queria ? isBetween || isStart || isEnd
Bergi
Sim, erro de digitação aí, desculpe!
Joel A. Villarreal Bertoldi

Respostas:

82

Você pode usar um plugin do momento -> intervalo de momento para lidar com o intervalo de datas:

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
Lukasz Koziara
fonte
1
como você inclui o plugin?
2
Você deve apenas incluir <script src = "/ javascripts / moment-range.js"> </script> após momentjs
Lukasz Koziara
53
date.isBetween (startDate, endDate); é muito mais simples e evita a necessidade de um plugin adicional.
Brendan Nee
momento e intervalo de momento fornece opções para formatar data e hora enquanto prepara intervalos e, em seguida, comparar as datas para Contém / Dentro de / Sobrepõe / Cruza / Adiciona / Subtrai. se alguém recupera datas em algum formato especial, então pode-se preparar intervalos de datas dentro do array, convertendo essas datas com o formato exigido e então podemos comparar.
Sajjad Ali Khan
277

Nas versões 2.9+, há uma isBetweenfunção, mas é exclusiva:

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

Existe uma solução alternativa inclusiva ...
x.isBetween(a, b) || x.isSame(a) || x.isSame(b)

... que é logicamente equivalente a
!(x.isBefore(a) || x.isAfter(b))


Na versão 2.13, a isBetweenfunção possui um quarto parâmetro opcional inclusivity,.

Use-o assim:

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

Mais unidades a serem consideradas: years, months, days, hours, minutes, seconds, milliseconds

Nota: as unidades ainda são opcionais. Use nullcomo o terceiro argumento para desconsiderar unidades, caso em que milissegundos é a granularidade padrão.

Visite a documentação oficial

ThisClark
fonte
3
tendo em mente que, conforme declarado nos documentos, isBetween é exclusivo
Joaquín L. Robles
x.isBetween(moment(a).subtract(1, 'day'), b)parece fazer o truque também.
James Donnelly
@ThisClark Essa é uma boa solução alternativa; posso sugerir outro com menos chamadas de função:!(x.isBefore(a) || x.isAfter(b))
tavnab
O que isso exclusivesignifica?
Batman
2
@Batman Considere a lista 1,2,3,4,5. Exclusivamente, 1 e 5 não estão entre os valores desta lista. Inclusive, 1 e 5 estão entre os valores desta lista. Inclusive à esquerda (igual a exclusivo à direita) inclui 1, mas não 5. Inclusivo à direita (igual a exclusivo à esquerda) inclui 5, mas não 1.
ThisClark
16

Eu acredito nisso

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

funciona tambem ...

Tiele Declercq
fonte
Este cálculo sempre ignora o ano. Por exemplo, se eu der startDate = '05 -01-2019 ', endDate = '05 -31-2019' e data como '05 -21-2017 ', o resultado será "Yay", embora seja falso .
Aakash Maurya
1
@AakashMaurya Você está comparando strings, não datas. Certifique-se de definir sua startDate / endDate como startDate = new Date ("05-01-2019").
Tiele Declercq
13

Boas notícias a todos, há uma isBetweenfunção! Atualize sua biblioteca;)

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

Luna
fonte
2
Verdadeiro, mas isBetweennão inclusivo
Epoc,
4
A versão 2.13.0 apresenta exclusividade. Um [indica a inclusão de um valor. A (indica exclusão. Se o parâmetro de inclusividade for usado, ambos os indicadores devem ser passados.moment('2016-10-30').isBetween('2016-10-30', '2016-10-30', null, '[]'); //true
Ramratan Gupta
8

Use o 4º parâmetro da função moment.isBetween (inclusividade). Exemplo:

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
Raffael Bechara Rameh
fonte
5
if (date.isBefore(endDate) 
 && date.isAfter(startDate) 
 || (date.isSame(startDate) || date.isSame(endDate))

é logicamente o mesmo que

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

o que economiza algumas linhas de código e (em alguns casos) chamadas de método.

Pode ser mais fácil do que puxar um plugin inteiro se você quiser fazer isso apenas uma ou duas vezes.

Jamie Humphries
fonte
1

Conforme a documentação do momento js,

O plugin Precise Range, escrito por Rob Dawson, pode ser usado para exibir representações exatas e legíveis de intervalos de data / hora, 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
Mohammed Safeer
fonte