Moment.js: fecha entre fechas

118

Estoy tratando de detectar con Moment.js si una fecha determinada está entre dos fechas. Desde la versión 2.0.0, Tim agregó isBefore()y isAfter()para la comparación de fechas.

Como no hay un isBetween()método, pensé que esto funcionaría:

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

Estoy convencido de que debe haber una mejor manera de hacer esto. ¿Algunas ideas?

Joel A. Villarreal Bertoldi
fuente
Estoy seguro de que quería ? isBetween || isStart || isEnd
Bergi
Sí, error tipográfico, ¡lo siento!
Joel A. Villarreal Bertoldi

Respuestas:

82

Puede utilizar uno de los complementos de momento -> intervalo de momentos para tratar el intervalo de fechas:

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
fuente
1
¿cómo se incluye el complemento?
2
Debería incluir <script src = "/ javascripts / moment-range.js"> </script> después de momentjs
Lukasz Koziara
53
date.isBetween (startDate, endDate); es mucho más simple y evita la necesidad de un complemento adicional.
Brendan Nee
moment & moment-Range ofrece opciones para formatear la fecha y hora mientras se preparan los rangos y luego comparar las fechas para Contiene / Dentro / Superposiciones / Intersectar / Agregar / Restar. si alguien recupera fechas en algún formato especial, entonces uno puede preparar rangos de fechas dentro de la matriz convirtiendo esas fechas con el formato requerido y luego podemos comparar.
Sajjad Ali Khan
277

En las versiones 2.9+ hay una isBetweenfunción, pero es 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

Hay una solución inclusiva ...
x.isBetween(a, b) || x.isSame(a) || x.isSame(b)

... que es lógicamente equivalente a
!(x.isBefore(a) || x.isAfter(b))


En la versión 2.13 de la isBetweenfunción tiene un cuarto parámetro opcional, inclusivity.

Úselo así:

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

Más unidades a considerar: years, months, days, hours, minutes, seconds, milliseconds

Nota: las unidades siguen siendo opcionales. Úselo nullcomo tercer argumento para ignorar las unidades, en cuyo caso milisegundos es la granularidad predeterminada.

Visite los documentos oficiales

ThisClark
fuente
3
Tenga en cuenta que, como se indica en los documentos, isBetween es exclusivo
Joaquín L. Robles
x.isBetween(moment(a).subtract(1, 'day'), b)parece hacer el truco también.
James Donnelly
@ThisClark Esa es una buena solución; ¿Podría sugerir otro con menos llamadas a funciones:!(x.isBefore(a) || x.isAfter(b))
tavnab
¿Qué exclusivesignifica?
Batman
2
@Batman Considere la lista 1,2,3,4,5. Exclusivamente, 1 y 5 no se encuentran entre los valores de esta lista. Inclusive, 1 y 5 están entre los valores de esta lista. Izquierda inclusiva (igual que derecha exclusiva) incluye 1, pero no 5. Derecha inclusiva (igual que izquierda exclusiva) incluye 5, pero no 1.
ThisClark
16

Yo creo que

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

también funciona ...

Tiele Declercq
fuente
Este cálculo siempre ignora el año. Por ejemplo, si doy startDate = '05 -01-2019 ', endDate = '05 -31-2019' y date como '05 -21-2017 ', me dará el resultado como "Yay", aunque es falso .
Aakash Maurya
1
@AakashMaurya Estás comparando cadenas, no fechas. Asegúrese de definir su fecha de inicio / fecha de finalización como fecha de inicio = nueva fecha ("05-01-2019").
Tiele Declercq
13

Buenas noticias a todos, ¡hay una isBetweenfunción! Actualice su biblioteca;)

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

Luna
fuente
2
Verdadero pero isBetweenno incluyente
Epoc
4
La versión 2.13.0 introduce la exclusividad. Un [indica la inclusión de un valor. A (indica exclusión. Si se usa el parámetro de inclusión, se deben aprobar ambos indicadores.moment('2016-10-30').isBetween('2016-10-30', '2016-10-30', null, '[]'); //true
Ramratan Gupta
8

Utilice el cuarto parámetro de la función moment.isBetween (inclusividad). Ejemplo:

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

es lógicamente lo mismo que

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

lo que le ahorra un par de líneas de código y (en algunos casos) llamadas a métodos.

Podría ser más fácil que introducir un complemento completo si solo desea hacer esto una o dos veces.

Jamie Humphries
fuente
1

Según la documentación del momento js,

Existe el complemento Precise Range, escrito por Rob Dawson, que se puede usar para mostrar representaciones exactas y legibles por humanos de rangos de fecha / 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
fuente