Moment: É uma maneira de valores float .add () ou .subtract ()?

Criado em 20 jun. 2015  ·  3Comentários  ·  Fonte: moment/moment

moment().add(1, "months") // >> Mon Jul 20 2015 13:36:12 GMT+0200
moment().add(1.9, "months") // >> Mon Jul 20 2015 13:36:12 GMT+0200
// Excpected: Mon Aug 17 2015 09:34:37 GMT+0200

Por enquanto, tenho que fazer:

var duration = moment.duration(1.9, "months"); 
var ms = duration.asMilliseconds();
var date = moment().add(ms, "ms");

Por que esses métodos não podem adicionar ou subtrair valores flutuantes?

Comentários muito úteis

Isso ocorre por design, mas provavelmente poderia ser explicado melhor na documentação.

Você pode usar decimais ao adicionar ou subtrair horas, minutos, segundos ou milissegundos, mas não pode subdividir dias ou componentes maiores.

A razão é que há uma diferença lógica entre a matemática do tempo e a matemática da data.

A matemática do tempo assume uma escala de tempo linear, apenas aumentando ou diminuindo o carimbo de data / hora baseado em UTC. Isso lida com as transições do horário de verão em tempo real. Por exemplo, para a maioria dos lugares nos Estados Unidos, 2015-03-08T01:00:00 mais uma hora seria 2015-03-08T03:00:00 porque a hora das 2h às 3h foi ignorada para a transição do horário de verão.

A matemática de datas não usa uma escala de tempo linear, mas sim as datas do calendário. Usando o mesmo exemplo, 2015-03-08T01:00:00 mais um _dia_ seria 2015-03-09T01:00:00 , embora apenas 23 horas tenham se passado. Portanto, um "dia" neste contexto não é uma quantidade fixa de tempo e, portanto, subdividi-lo seria absurdo. (Metade do dia seria 12 horas depois ou 11,5 horas mais tarde neste dia?)

Mesmo sem o horário de verão, considere que nem todos os meses são 30 dias e nem todos os anos são 365 dias. "Adicionar" um ano não significa realmente "adicionar 365 dias", significa "avançar a posição no calendário para o mesmo mês e dia do próximo ano". Isso cria certas ambigüidades, como adicionar um ano a 29 de fevereiro em um ano bissexto e terminar em um ano não bissexto. Escolhemos pousar em 28 de fevereiro, mas pousar em 1º de março seria igualmente válido.

Como outro exemplo, considere que 31 de agosto mais um mês, menos um mês, é 30 de agosto.

Visto que a matemática de datas não segue as regras normais de adição e subtração da matemática, ela também não pode lidar com operações de divisão ou multiplicação e, portanto, você não pode adicionar 1,9 meses.

Pensando de outra forma, qual seria o resultado da meia-noite de 15 de junho + 1,5 mês? Qualquer uma das seguintes ações pode ser realizada por um humano:

  • 2015-06-15T00:00 + (0,5 * 30 dias em junho) = 2015-06-30T00:00 + (1 mês = 30 dias) = 2015-07-30T00:00
  • 2015-06-15T00:00 + (0,5 * 30 dias em junho) = 2015-06-30T00:00 + (1 mês = 31 dias) = 2015-07-31T00:00
  • 2015-06-15T00:00 + 1 mês = 2015-07-15T00:00 + (0,5 * 31 dias em julho) = 2015-07-30T12:00
  • 2015-06-15T00:00 + [(61 dias em junho e julho / 2 = 30,5 dias médios nesses meses) * 1,5 meses = 45,75 dias] = 2015-07-30T18:00

Portanto, aqui estão quatro respostas diferentes que são resultados lógicos - é por isso que você não pode subdividir unidades ao fazer cálculos de data.

Todos 3 comentários

Isso ocorre por design, mas provavelmente poderia ser explicado melhor na documentação.

Você pode usar decimais ao adicionar ou subtrair horas, minutos, segundos ou milissegundos, mas não pode subdividir dias ou componentes maiores.

A razão é que há uma diferença lógica entre a matemática do tempo e a matemática da data.

A matemática do tempo assume uma escala de tempo linear, apenas aumentando ou diminuindo o carimbo de data / hora baseado em UTC. Isso lida com as transições do horário de verão em tempo real. Por exemplo, para a maioria dos lugares nos Estados Unidos, 2015-03-08T01:00:00 mais uma hora seria 2015-03-08T03:00:00 porque a hora das 2h às 3h foi ignorada para a transição do horário de verão.

A matemática de datas não usa uma escala de tempo linear, mas sim as datas do calendário. Usando o mesmo exemplo, 2015-03-08T01:00:00 mais um _dia_ seria 2015-03-09T01:00:00 , embora apenas 23 horas tenham se passado. Portanto, um "dia" neste contexto não é uma quantidade fixa de tempo e, portanto, subdividi-lo seria absurdo. (Metade do dia seria 12 horas depois ou 11,5 horas mais tarde neste dia?)

Mesmo sem o horário de verão, considere que nem todos os meses são 30 dias e nem todos os anos são 365 dias. "Adicionar" um ano não significa realmente "adicionar 365 dias", significa "avançar a posição no calendário para o mesmo mês e dia do próximo ano". Isso cria certas ambigüidades, como adicionar um ano a 29 de fevereiro em um ano bissexto e terminar em um ano não bissexto. Escolhemos pousar em 28 de fevereiro, mas pousar em 1º de março seria igualmente válido.

Como outro exemplo, considere que 31 de agosto mais um mês, menos um mês, é 30 de agosto.

Visto que a matemática de datas não segue as regras normais de adição e subtração da matemática, ela também não pode lidar com operações de divisão ou multiplicação e, portanto, você não pode adicionar 1,9 meses.

Pensando de outra forma, qual seria o resultado da meia-noite de 15 de junho + 1,5 mês? Qualquer uma das seguintes ações pode ser realizada por um humano:

  • 2015-06-15T00:00 + (0,5 * 30 dias em junho) = 2015-06-30T00:00 + (1 mês = 30 dias) = 2015-07-30T00:00
  • 2015-06-15T00:00 + (0,5 * 30 dias em junho) = 2015-06-30T00:00 + (1 mês = 31 dias) = 2015-07-31T00:00
  • 2015-06-15T00:00 + 1 mês = 2015-07-15T00:00 + (0,5 * 31 dias em julho) = 2015-07-30T12:00
  • 2015-06-15T00:00 + [(61 dias em junho e julho / 2 = 30,5 dias médios nesses meses) * 1,5 meses = 45,75 dias] = 2015-07-30T18:00

Portanto, aqui estão quatro respostas diferentes que são resultados lógicos - é por isso que você não pode subdividir unidades ao fazer cálculos de data.

Muito obrigado por escrever esta resposta tão detalhada. Eu entendo melhor a lógica por trás da operação dessas funções.

Não pude resistir a mim mesma por agradecer ao Matt, cruzei com o mesmo problema que Delgan experimentou, e cara! sua resposta é tão completa, obrigado.

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