¿Por qué es Date.today – 6.months + 6.months! = Date.today?

En Ruby, en Halloween:

Date.today - 6.months + 6.months != Date.today 

¿Necesitamos actualizar la implementación de la fecha de Ruby? ¿Otros idiomas tienen el mismo problema?

Esto sucede si lo hace en cualquier mes que no tenga 31 días (es decir, 3 meses funcionarán bien, pero 1 mes, o 6, u 8 harán que esto suceda).

Si lo hace Date.today - 1.month , parece que Rails ve que el 31/9/2011 no es una fecha válida, por lo que lo hace retroceder un día adicional para que sea una fecha válida. Sin embargo, cuando se adelanta un mes a partir de finales de septiembre, lo dejará el 30/10/2011, ya que es una fecha válida. Básicamente, Rails solo intenta incrementar (o disminuir) el campo del mes y siempre que sea una fecha válida, no ajustará el campo del día.

Una forma de .end_of_month esto es usar el .end_of_month (o .beginning_of_month ) en un objeto Date en Rails para asegurarse de que siempre esté llegando al final o al principio de un mes.

No, esto se espera y tampoco es exclusivo de Ruby; inténtelo en SQL, por ejemplo.

(Today - 6 months) es el último día (30) de abril, porque no hay 31º. Solo estamos tratando los meses, no un número preciso de días.

Agregue 6 meses al 30 de abril y obtendrá el 30 de octubre.

Lo que, como sabéis es! = 31 de octubre.

Esta es una característica extraña de las extensiones de tiempo ActiveSupport.

 > 6.months == 180.days => true 

pero cuando salgas con Matemáticas con meses, se consideran meses calendario, no períodos de 30 días. Mira esto:

 > Date.today - 180.days + 180.days => Mon, 31 Oct 2011 

Consulte https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/time/calculations.rb#L277 y continúe investigando desde allí.