Subtração de datas Ruby (por exemplo, 90 dias atrás)


88

Fiquei um pouco estragado pela API Joda-Time de:

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

Estou tentando fazer algo semelhante em Ruby, mas estou

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

No entanto, a matemática está errada aqui (estou realmente trabalhando com datas à meia-noite).

Existe uma API amigável para subtração de datas?

Respostas:


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

Executando isso através do console IRB, recebo:

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

Se precisar de tempo, você pode apenas dizer now = DateTime.now


Sua postagem original, pré-edição, estava mais perto do que eu precisava, mas Date.Now estava protegida. Date.today funcionou. Se você alterar sua primeira sinopse para a linha agora = Date.today, eu aceitarei.
darthtrevino

3
@Matt: e como subtrair 90 horas em vez de dias?
Esteban Feldman

@EstebanFeldman Datetambém permite frações para que você possa fazer Date.today - (90.0/24.0). O resultado pode ser facilmente convertido to_datetimeou to_timetambém.
jchook 01 de

15

Para aqueles que usam Rails, verifique o seguinte:

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

10

Se você estiver usando Rails ou não se importar em incluir ActiveSupport, você pode usar o DSL Numérico # dias como este:

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 você está trabalhando com datas em vez de horas, também deve começar com instâncias de Date ou converter suas intâncias de DateTime com #to_date. Ao adicionar / subtrair números de instâncias de data, os números são implicitamente dias.

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

8

Ruby suporta aritmética de data nas classes Date e DateTime , que fazem parte da biblioteca padrão do Ruby. Ambas as classes expõem os métodos # + e # - , que somam e subtraem dias de uma data ou 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" 

Use os métodos # << e # >> para operar em meses em vez de dias. A aritmética em meses é um pouco diferente da aritmética em dias. Usar Date em vez de DateTime torna o efeito mais óbvio.

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

Seguindo seu exemplo do tempo joda, você pode escrever algo assim em Ruby.

now =  DateTime.now
ninety_days_ago = now - 90

ou talvez apenas

ninety_days_ago = DateTime.now - 90

5

Este é um post muito antigo, mas se você quiser continuar com um Timeobjeto, como foi pedido originalmente, ao invés de mudar para um Dateobjeto que você pode querer considerar usar Ruby Facets.

Ruby Facets é uma biblioteca padronizada de extensões para as principais classes Ruby.

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

Ao solicitar as Facetas, você pode fazer o seguinte com os objetos Tempo.

Time.now.less(90, :days)


Este projeto não é atualizado há dois anos e abriu questões com um único comentário. Está morto.
user4674453

@ user4674453 A última atualização foi há seis meses. É uma biblioteca estável que ainda funciona com a última versão do Ruby. Nem todas as bases de código precisam ser atualizadas diariamente para não serem consideradas "mortas".
bigtunacan

5

use o número de segundos:

Time.now - 90*24*60*60

-1

Solução simples:

days90_ago = 90.days.ago.to_date.to_s

OUTPUT:
puts 90_days_ago
=> "2019-10-09" # considering cur_date: 2020-01-07

Isso está usando ActiveSupport (Rails).
Espen
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.