Moment: Control sobre el comportamiento de exclusividad / exclusividad de isBetween

Creado en 16 ene. 2015  ·  28Comentarios  ·  Fuente: moment/moment

El método isBetween comprueba si un momento está entre otros dos, pero no si es igual a cualquiera de los tiempos de comparación. Creo que necesitamos un argumento inclusivo, aunque con el tercer argumento actualmente siendo las unidades, puede ser mejor crear un método isBetweenInclusive separado.

Gracias

Enhancement Up-For-Grabs

Comentario más útil

¡Esta fue una gran característica y absolutamente necesaria!

Todos 28 comentarios

También me gustaría esto.

Estoy de acuerdo, esta sería una característica increíblemente útil. Sería fantástico poder elegir entre isBetween inclusivo y exclusivo, o pasar la inclusión como un argumento booleano.

En realidad, hay que pensar un poco más en esta función que lo que se ofrece actualmente o lo que se propone.

En escenarios del mundo real, el valor inicial es siempre inclusivo, pero el valor final es inclusivo o exclusivo _dependiendo de la granularidad_. Específicamente, si el valor incluye un componente de tiempo, el valor final debe ser exclusivo. Si no incluye un componente de tiempo, entonces debería ser _inclusivo_.

Piensa en ello de esta manera. Si le pregunto cuántos días hay entre el 1 de enero y el 3 de enero, la respuesta es tres días . Pero si les pregunto cuántas horas hay entre la 1:00 y las 3:00, la respuesta es dos horas . Los humanos, naturalmente, hacen esto. Tiene un impacto en cómo medimos las duraciones entre intervalos (como con moment#diff ) y cómo probamos un valor para ver si está dentro del rango (como con moment#inBetween ).

El comportamiento actual de moment#isBetween es completamente exclusivo, independientemente de la granularidad. Esto no es muy útil.

El comportamiento actual de moment#diff es inclusivo al principio y exclusivo al final, nuevamente, independientemente de la granularidad. Esto es válido por tiempo, error no válido por días. De hecho, el ejemplo en los documentos es:

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') // 1

Cuando en realidad, la mayoría de la gente espera que el resultado sea de 2 días.

El problema final es que un objeto moment es una unidad de tiempo discreta, pero en muchos casos tratamos de tratarlo como una fecha en un calendario, y aquí es donde los efectos secundarios comienzan a hacerse visibles.

Piensa en ello de esta manera. Si le pregunto cuántos días hay entre el 1 de enero y el 3 de enero, la respuesta es tres días. Pero si les pregunto cuántas horas hay entre la 1:00 y las 3:00, la respuesta es dos horas.

Creo que la respuesta lógica (y para mí, esperada) es "2" cuando se pregunta a una biblioteca de fechas la cantidad de días entre el "1 de enero" y el "3 de enero". La razón es que sin un tiempo especificado, esperaría que funcione entre el "1 de enero a las 00:00" y el "3 de enero a las 00:00". La forma en que los humanos resuelven la diferencia en el mundo real realmente depende del contexto, pero no creo que eso tenga nada que ver con cómo funcionan las cosas en el mundo de la programación.

Así es como se hace para Carbon de PHP y nunca he encontrado que esto sea un problema: https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Carbon.php#L1070 -1092

El segundo en el que nos fusionamos es. Sabía que algunas personas querrían especificar un comportamiento diferente para los intervalos, pero todavía no veo una buena propuesta. En última instancia, ambos extremos serían configurables por separado (ya sean inclusivos / exclusivos).

También debería ser compatible con la versión actual.

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

No puedo pensar en un escenario del mundo real para excluir el inicio, por lo que podría ser solo una bandera booleana para excluir o no el final.

Sin embargo, me gusta la propuesta 1, ya que está cerca de la notación de intervalo ISO 31-11 adecuada

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

Realmente no me gusta la propuesta 2. (sin ofender)

: +1: para la propuesta uno.

Honestamente, no puedo ver ningún escenario en el que desee excluir explícitamente uno de los extremos, pero no ambos. Incluso si intentaba ver "hasta el día de hoy", podría usar moment (date) .endOf ("day") como fecha de finalización, lo que le daría las 11: 59.59 p. M.

Creo que debería haber una bandera booleana para hacerlo inclusivo / exclusivo, como un rango "normal" en la mayoría de los lenguajes de programación. Manténgalo simple para evitar confusiones: si desea una hora _justo antes_ de la hora de finalización, hay otras formas de obtenerla.

@mckinnsb : ese enfoque generalmente se evita por dos razones:

  1. La precisión se vuelve importante. En JavaScript, la última hora posible de un día estándar sería 23:59:59.999 , pero en otros idiomas podría ser 23:59:59 , o 23:59:59.9999999 . Interactuamos con valores de otras fuentes mediante el formato y el análisis de cadenas, por lo que esto es importante.
  2. Si define un rango de 00:00:00.000 a 23:59:59.999 , no puede determinar fácilmente la duración del rango. En lugar de solo duration = end - start , ahora tiene que hacer algo como duration = end - start + epsilon , donde épsilon es la precisión mínima, como se discutió anteriormente.

También rechazaré su afirmación de que existe un rango "normal" en la mayoría de los lenguajes de programación. En realidad, muchos rangos de programación no tienen tipos de rango incorporados. Cuando lo hacen, su comportamiento es específico del idioma. No hay "normalidad".

Vea también esta publicación de quora sobre la función range en Python.

+1 para la propuesta 1, flexibiliza las cosas.
Mi primera expectativa fue la misma de que se incluirían los límites superior e inferior, al igual que lo haría en SQL, X entre AY B,
Actualmente trabajando con esto x.isBetween(a, b) || x.isSame(a) || x.isSame(b)

+1

+1

+1 propuesta 1

+1

+1

+1

@ mj1856 ¿No es el comportamiento predeterminado '()' ?

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 ya tiene un tercer parámetro opcional. Actualmente, el método se define como function isBetween (from, to, units) donde units es opcional. Esta propuesta da como resultado un cuarto parámetro opcional, por lo que una implementación tendrá que manejar dos posibles terceras opciones (exclusivo / inclusivo vs unidades) o las cuatro.

Algunas soluciones (no probadas):

() = x.isBetween (inicio, final) // completamente exclusivo: la implementación predeterminada en este momento
(] = x.isAfter (inicio) && x.isSameOrBefore (end) // izquierda exclusiva, derecha inclusiva
[) = x.isSameOrAfter (inicio) && x.isBefore (final) // izquierda inclusiva, derecha exclusiva
[] =! (x.isBefore (a) || x.isAfter (b)) // totalmente inclusivo

Quizás las soluciones alternativas más fáciles de leer son las siguientes:

() = x.isEntre (a, b)
(] = x.isEntre (a, b) || x.ismisma (b)
[) = x.isSame (a) || x.isEntre (a, b)
[] = x.isEntre (a, b) || x.isSame (a) || x.isSame (b) // igual que! (x.isBefore (a) || x.isAfter (b))

Dado que el tercer y cuarto parámetro serán ambos opcionales, podría ser bueno pasar un objeto

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

Donde las unidades predeterminadas son milisegundos y el inclusivo predeterminado es () .

Mierda ... ustedes tienen razón. Lo siento. Redacción ...

Marcando esto en juego. El uso esperado sería el de la propuesta 1 anterior, que debería permitir un _ cuarto_ parámetro opcional pasado a isBetween , que contiene uno de '[]' , '[)' , '()' , '(]' . Debe incluir pruebas para los cuatro. El valor predeterminado cuando no se aprueba debe ser el mismo que '()' , que también es el comportamiento actual.

WRT las opciones - Realmente no tengo ninguna preferencia. También se podría pasar null en el tercer parámetro para llegar al cuarto, o permitir que cualquiera de los elementos se pase como el tercer parámetro o el cuarto parámetro, ya que estamos limitados a valores conocidos. El objeto de opciones también está bien. Lo que el implementador crea que es más fácil, o diablos, puede hacer todo lo anterior.

A menos, por supuesto, que alguien más tenga una opinión firme al respecto. :)

Buen comienzo en PR # 2943. Seguiremos esto en ese PR. ¡Gracias!

+1

Me hubiera gustado REALMENTE haber usado la funcionalidad en el compromiso de @darrenjennings hoy.

¿Estás hablando de esto disponible en v2.13? @rbreier
https://momentjs.com/docs/#/query/is -between /

Eso es exactamente lo que estaba buscando. Muchas gracias. Actualicé y esto funciona perfectamente para mí.

¡Esta fue una gran característica y absolutamente necesaria!

El segundo en el que nos fusionamos es. Sabía que algunas personas querrían especificar un comportamiento diferente para los intervalos, pero todavía no veo una buena propuesta. En última instancia, ambos extremos serían configurables por separado (ya sean inclusivos / exclusivos).

También debería ser compatible con la versión actual.

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

cuando estoy usando la condición anterior, me da el primer error y luego la condición fallará. estoy usando angular 6

¿Fue útil esta página
0 / 5 - 0 calificaciones