Moment: Controle sobre o comportamento de exclusividade / exclusividade da isBetween

Criado em 16 jan. 2015  ·  28Comentários  ·  Fonte: moment/moment

O método isBetween verifica se um momento está entre dois outros, mas não se é igual a algum dos tempos de comparação. Acho que precisamos de um argumento inclusivo, embora com o terceiro argumento sendo atualmente as unidades, pode ser melhor criar um método isBetweenInclusive separado.

Obrigado

Enhancement Up-For-Grabs

Comentários muito úteis

Este foi um ótimo recurso e absolutamente necessário !!!!

Todos 28 comentários

Eu também gostaria disso.

Eu concordo, esse seria um recurso incrivelmente útil. Ser capaz de escolher entre inclusivo e exclusivo isBetween, ou passar a inclusão como um argumento booleano seria fantástico.

Na verdade, é preciso pensar um pouco mais nessa função do que o que é oferecido atualmente ou o que está sendo proposto.

Em cenários do mundo real, o valor inicial é sempre inclusivo, mas o valor final é inclusivo ou exclusivo _dependendo da granularidade_. Especificamente, se o valor inclui um componente de tempo, o valor final deve ser exclusivo. Se não incluir um componente de tempo, deve ser _inclusive_.

Pense nisso desta maneira. Se eu perguntar quantos dias existem entre 1º de janeiro e 3 de janeiro - a resposta é três dias . Mas se eu perguntar quantas horas faltam entre 1h e 3h, a resposta é duas horas . Os humanos fazem isso naturalmente. Tem um impacto na forma como medimos as durações entre os intervalos (como com moment#diff ) e como testamos um valor para ver se está dentro do intervalo (como com moment#inBetween ).

O comportamento atual de moment#isBetween é totalmente exclusivo, independentemente da granularidade. Isso não é muito útil.

O comportamento atual de moment#diff é inclusivo no início e exclusivo no final, novamente, independentemente da granularidade. Isso é válido por tempo, bug inválido por dias. Na verdade, o exemplo nos documentos é:

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

Quando, na realidade, a maioria das pessoas espera que o resultado seja de 2 dias.

O problema final é que um objeto moment é uma unidade de tempo discreta, mas em muitos casos tentamos tratá-lo como uma data em um calendário, e é aí que os efeitos colaterais começam a se tornar visíveis.

Pense nisso desta maneira. Se eu perguntar quantos dias existem entre 1º de janeiro e 3 de janeiro - a resposta é três dias. Mas se eu perguntar quantas horas faltam entre 1h e 3h, a resposta é duas horas.

Acho que a resposta lógica (e para mim, esperada) é "2" ao perguntar a uma biblioteca de datas a quantidade de dias entre "1º de janeiro" e "3 de janeiro". O motivo é que, sem um horário especificado, eu esperaria que funcionasse entre "1º de janeiro às 00:00" e "3 de janeiro às 00:00". Como os humanos resolvem a diferença no mundo real realmente depende do contexto, mas não acho que isso tenha algo a ver com como as coisas funcionam no mundo da programação.

Veja como isso é feito para Carbon do PHP e eu nunca achei isso um problema: https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Carbon.php#L1070 -1092

O segundo que fundimos é. Eu sabia que algumas pessoas vão querer especificar um comportamento diferente para os intervalos, mas ainda não vi uma boa proposta. Em última análise, ambas as extremidades seriam configuráveis ​​separadamente (sejam elas inclusivas / exclusivas).

Também deve ser compatível com a versão atual.

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

Não consigo pensar em um cenário do mundo real para excluir o início, então poderia ser apenas uma sinalização booleana para excluir ou não o fim.

Porém - eu meio que gosto da proposta 1, pois está próxima da notação de intervalo ISO 31-11 adequada

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

Eu realmente não gosto da proposta 2. (sem ofensa)

: +1: para a proposta um.

Sinceramente, não consigo ver nenhum cenário em que você queira excluir explicitamente uma das extremidades, mas não ambas. Mesmo se você estivesse tentando ver "até este dia", você poderia usar o momento (data) .endOf ("dia") como a data de término, o que lhe daria 23h59,59.

Acho que deveria haver apenas um sinalizador booleano para torná-lo inclusivo / exclusivo, assim como um intervalo "normal" na maioria das linguagens de programação. Mantenha-o simples para evitar confusão - se você quiser um horário _apenas antes_ de um horário de término, há outras maneiras de obtê-lo.

@mckinnsb - Essa abordagem geralmente é evitada por dois motivos:

  1. A precisão se torna importante. Em JavaScript, a última hora possível de um dia padrão seria 23:59:59.999 , mas em outros idiomas poderia ser 23:59:59 ou 23:59:59.9999999 . Interagimos com valores de outras fontes por meio de análise e formatação de strings, portanto, isso é importante.
  2. Se você definir um intervalo de 00:00:00.000 a 23:59:59.999 - você não pode determinar facilmente a duração do intervalo. Em vez de apenas duration = end - start , agora você precisa fazer algo como duration = end - start + epsilon , onde épsilon é a precisão mínima, conforme discutido acima.

Também rejeitarei sua declaração de que existe um intervalo "normal" na maioria das linguagens de programação. Na realidade, muitos intervalos de programação não têm tipos de intervalo embutidos. Quando o fazem, seu comportamento é específico do idioma. Não existe "normal".

Veja também esta postagem do quora sobre a função range em Python.

+1 para a proposta 1, torna as coisas flexíveis.
Minha primeira expectativa era a mesma de que os limites superior e inferior seriam incluídos, assim como eu faria no SQL, X entre A AND B,
Atualmente trabalhando nisso por este x.isBetween(a, b) || x.isSame(a) || x.isSame(b)

+1

+1

+1 proposta 1

+1

+1

+1

@ mj1856 O comportamento padrão não é '()' ?

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 já tem um terceiro parâmetro opcional. Atualmente o método é definido como function isBetween (from, to, units) onde units é opcional. Esta proposta resulta em um 4º parâmetro opcional, então uma implementação terá que lidar com duas terceiras opções possíveis (exclusivas / inclusivas vs unidades) ou todas as quatro.

Algumas soluções alternativas (não testadas):

() = x.isBetween (start, end) // totalmente exclusivo - a implementação padrão neste momento
(] = x.isAfter (início) && x.isSameOrBefore (fim) // exclusivo à esquerda, inclusivo à direita
[) = x.isSameOrAfter (início) && x.isBefore (fim) // inclusivo à esquerda, exclusivo à direita
[] =! (x.isBefore (a) || x.isAfter (b)) // totalmente inclusivo

Soluções alternativas mais fáceis de ler são as seguintes:

() = x.está Entre (a, b)
(] = x.isEntre (a, b) || x.isSame (b)
[) = x.isSame (a) || x.está entre (a, b)
[] = x.está entre (a, b) || x.isSame (a) || x.isSame (b) // mesmo que! (x.isBefore (a) || x.isAfter (b))

Uma vez que o terceiro e o quarto parâmetros serão opcionais, pode ser bom passar um objeto

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

Onde as unidades padrão são milissegundos e o padrão inclusivo é () .

Merda .. vocês estão certos. Desculpe. Reescrevendo ...

Marcando isso para ganhar. O uso esperado seria conforme a proposta 1 acima, que deve permitir um _quarto_ parâmetro opcional passado para isBetween , contendo um de '[]' , '[)' , '()' , '(]' . Deve incluir testes para todos os quatro. O padrão quando não passado deve ser o mesmo que '()' , que também é o comportamento atual.

WRT as opções - eu realmente não tenho uma preferência. Pode-se muito bem passar null no terceiro parâmetro para chegar ao quarto, ou permitir que qualquer um dos itens seja passado como o terceiro parâmetro ou o quarto parâmetro, uma vez que estamos limitados a valores conhecidos. O objeto de opções também está bom. O que quer que o implementador pense que é mais fácil - ou diabos, você pode fazer todas as opções acima.

A menos, é claro, que outra pessoa tenha uma opinião forte sobre isso. :)

Bom começo em PR # 2943. Vamos rastrear isso naquele PR. Obrigado!

+1

Eu realmente gostaria de ter usado a funcionalidade do @darrenjennings commit hoje.

Você está falando sobre isso disponibilizado na v2.13? @rbreier
https://momentjs.com/docs/#/query/is -between /

Isso é exatamente o que eu estava procurando. Muito obrigado. Eu atualizei e isso funciona perfeitamente para mim.

Este foi um ótimo recurso e absolutamente necessário !!!!

O segundo que fundimos é. Eu sabia que algumas pessoas vão querer especificar um comportamento diferente para os intervalos, mas ainda não vi uma boa proposta. Em última análise, ambas as extremidades seriam configuráveis ​​separadamente (sejam elas inclusivas / exclusivas).

Também deve ser compatível com a versão atual.

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

quando estou usando a condição acima, primeiro me ocorre o erro e, em seguida, a condição vai falhar. estou usando angular 6

Esta página foi útil?
0 / 5 - 0 avaliações