Resta de fecha rubí (por ejemplo, hace 90 días)

89

Me ha estropeado un poco la API joda-time de:

DateTime now = new DateTime();
DateTime ninetyDaysAgo = now.minusDays(90);

Estoy tratando de hacer algo similar en Ruby, pero estoy

now = Time.now
ninetyDaysAgo = now - (90*24)

Sin embargo, las matemáticas están fuera de lugar (realmente estoy trabajando con fechas a la medianoche).

¿Existe una API amigable para la resta de fechas?

darthtrevino
fuente

Respuestas:

105
require 'date'
now = Date.today
ninety_days_ago = (now - 90)

Al ejecutar esto a través de la consola IRB, obtengo:

>>require 'date'
now = Date.today
ninety_days_ago = (now - 90)

require 'date'
=> false
now = Date.today
=> #<Date: 2011-03-02 (4911245/2,0,2299161)>
ninety_days_ago = (now - 90)
=> #<Date: 2010-12-02 (4911065/2,0,2299161)>

Si necesitas el tiempo, solo puedes decir now = DateTime.now

Mate
fuente
Tu publicación original, la preedición estaba más cerca de lo que necesitaba, pero Date.Now estaba protegido. Fecha.hoy trabajado. Si cambia su primera propaganda para tener la línea ahora = Fecha.today, la aceptaré.
Darthtrevino
3
@Matt: ¿y cómo restar 90 horas en lugar de días?
Esteban Feldman
@EstebanFeldman Datetambién permite fracciones para que usted pueda hacerlo Date.today - (90.0/24.0). El resultado se puede convertir fácilmente to_datetimeo to_timetambién.
jchook
15

Para aquellos que usan Rails, consulte lo siguiente:

DateTime.now - 10.days
=> Sat, 04 May 2013 12:12:07 +0300

20.days.ago - 10.days
=> Sun, 14 Apr 2013 09:12:13 UTC +00:00
Abdo
fuente
10

Si está usando Rails o no le importa incluir ActiveSupport, puede usar el DSL numérico de # días de la siguiente manera:

ruby-1.9.2-p136 :002 > Date.today
 => Wed, 02 Mar 2011 
ruby-1.9.2-p136 :003 > Date.today - 90.days
 => Thu, 02 Dec 2010 

Como está trabajando con fechas en lugar de horas, también debe comenzar con instancias de fecha o convertir sus intanzas de fecha y hora con #to_date. Al sumar / restar números de instancias de fecha, los números son implícitamente días.

ruby-1.9.2-p136 :016 > DateTime.now.to_date
 => #<Date: 2011-03-02 (4911245/2,0,2299161)> 
ruby-1.9.2-p136 :017 > DateTime.now.to_date - 90
 => #<Date: 2010-12-02 (4911065/2,0,2299161)> 
Gabe Martin-Dempesy
fuente
8

Ruby admite aritmética de fechas en las clases Date y DateTime , que forman parte de la biblioteca estándar de Ruby. Ambas clases exponen los métodos # + y # - , que suman y restan días de una fecha o una hora.

$ irb
 > require 'date'
 => true 
 > (DateTime.new(2015,4,1) - 90).to_s  # Apr 1, 2015 - 90 days
 => "2015-01-01T00:00:00+00:00"
 > (DateTime.new(2015,4,1) - 1).to_s   # Apr 1, 2015 - 1 day
 => "2015-03-31T00:00:00+00:00" 

Utilice los métodos # << y # >> para operar en meses en lugar de días. La aritmética en meses es un poco diferente a la aritmética en días. Usar Date en lugar de DateTime hace que el efecto sea más obvio.

 > (Date.new(2015, 5, 31) << 3).to_s  # May 31 - 3 months; 92 days diff
 => "2015-02-28" 

Siguiendo tu ejemplo de joda-time, podrías escribir algo como esto en Ruby.

now =  DateTime.now
ninety_days_ago = now - 90

o tal vez solo

ninety_days_ago = DateTime.now - 90
Mike Sherrill 'Cat Recall'
fuente
5

Esta es una publicación muy antigua, pero si desea mantener un Timeobjeto, como se preguntó originalmente, en lugar de cambiar a un Dateobjeto, es posible que desee considerar usar Ruby Facets.

Ruby Facets es una biblioteca estandarizada de extensiones para las clases principales de Ruby.

http://rubyworks.github.io/facets/

Al requerir Facetas, puede hacer lo siguiente con los objetos Time.

Time.now.less(90, :days)

bigtunacan
fuente
Este proyecto no se ha actualizado durante dos años y ha abierto problemas con un solo comentario. Está muerto.
user4674453
@ user4674453 La última actualización fue hace seis meses. Es una biblioteca estable que todavía funciona con la última versión de Ruby. No todas las bases de código necesitan actualizarse diariamente para que no se consideren "muertas".
bigtunacan
5

usa el número de segundos:

Time.now - 90*24*60*60
Rubí
fuente
-1

Solución simple:

days90_ago = 90.days.ago.to_date.to_s

OUTPUT:
puts 90_days_ago
=> "2019-10-09" # considering cur_date: 2020-01-07
Ravistm
fuente
Esto está utilizando ActiveSupport (Rails).
Espen