Ruby Date Subtraction (zB vor 90 Tagen)

88

Ich bin ein bisschen verwöhnt von der joda-time API von:

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

Ich versuche in Ruby etwas Ähnliches zu tun, aber ich bin es

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

Allerdings ist die Mathematik hier nicht in Ordnung (ich arbeite wirklich mit Daten um Mitternacht).

Gibt es eine benutzerfreundliche API für die Datumssubtraktion?

Darthtrevino
quelle

Antworten:

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

Wenn ich dies über die IRB-Konsole starte, bekomme ich:

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

Wenn Sie die Zeit brauchen, können Sie einfach sagen now = DateTime.now

Matt
quelle
Ihr ursprünglicher Beitrag, die Vorbearbeitung, war näher an dem, was ich brauchte, aber Date.Now war geschützt. Date.today hat funktioniert. Wenn Sie Ihren ersten Klappentext so ändern, dass die Zeile jetzt = Date.today ist, werde ich das akzeptieren.
Darthtrevino
3
@Matt: und wie subtrahiere ich 90 Stunden statt Tage?
Esteban Feldman
@EstebanFeldman Dateerlaubt auch Brüche, so dass Sie tun können Date.today - (90.0/24.0). Das Ergebnis kann leicht konvertiert werden to_datetimeoder to_timeauch.
Jchook
15

Beachten Sie für Benutzer von Rails Folgendes:

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
quelle
10

Wenn Sie Rails verwenden oder ActiveSupport nicht einbeziehen möchten, können Sie das Numeric # days DSL wie folgt verwenden :

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 

Da Sie mit Datumsangaben anstelle von Uhrzeiten arbeiten, sollten Sie entweder mit Datumsinstanzen beginnen oder Ihre DateTime-Intanzen mit #to_date konvertieren. Beim Addieren / Subtrahieren von Zahlen von Datumsinstanzen sind die Zahlen implizit Tage.

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
quelle
8

Ruby unterstützt Datumsarithmetik in den Klassen Date und DateTime , die Teil der Standardbibliothek von Ruby sind. Beide Klassen legen # + und # - Methoden offen, die Tage zu einem Datum oder einer Uhrzeit addieren und von diesen subtrahieren.

$ 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" 

Verwenden Sie die Methoden # << und # >> , um Monate statt Tage zu bearbeiten. Die Arithmetik an Monaten unterscheidet sich ein wenig von der Arithmetik an Tagen. Die Verwendung von Datum anstelle von DateTime macht den Effekt deutlicher.

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

Nach Ihrem Beispiel aus der Joda-Zeit könnten Sie so etwas in Ruby schreiben.

now =  DateTime.now
ninety_days_ago = now - 90

oder vielleicht einfach nur

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

Dies ist ein super alter Beitrag, aber wenn Sie Timewie ursprünglich gefragt an einem DateObjekt festhalten möchten , anstatt zu einem Objekt zu wechseln, sollten Sie die Verwendung in Betracht ziehen Ruby Facets.

Ruby Facets ist eine standardisierte Bibliothek mit Erweiterungen für Ruby-Kernklassen.

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

Wenn Sie Facetten benötigen, können Sie mit Zeitobjekten Folgendes tun.

Time.now.less(90, :days)

Bigtunacan
quelle
Dieses Projekt wurde seit zwei Jahren nicht mehr aktualisiert und hat Probleme mit einem einzigen Kommentar geöffnet. Es ist tot.
user4674453
@ user4674453 Das letzte Update war vor sechs Monaten. Es ist eine stabile Bibliothek, die immer noch mit der neuesten Version von Ruby funktioniert. Nicht alle Codebasen müssen täglich aktualisiert werden, um nicht als "tot" zu gelten.
Bigtunacan
5

Verwenden Sie die Anzahl der Sekunden:

Time.now - 90*24*60*60
Rubin
quelle
-1

Einfache Lösung:

days90_ago = 90.days.ago.to_date.to_s

OUTPUT:
puts 90_days_ago
=> "2019-10-09" # considering cur_date: 2020-01-07
Ravistm
quelle
Dies verwendet ActiveSupport (Rails).
Espen