Віднімання дати Рубіну (наприклад, 90 днів тому)


89

Мене трохи розпестив joda-time API:

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

Я намагаюся зробити подібне в Ruby, але я

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

Однак тут математика не працює (я справді працюю з датами опівночі).

Чи існує зручний API для віднімання дати?

Відповіді:


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

Запускаючи цю консоль IRB, я отримую:

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

Якщо вам потрібен час, ви можете просто сказати now = DateTime.now


Ваша оригінальна публікація, попередня редакція, була ближчою до того, що мені потрібно, але Date.Now була захищена. Date.today спрацював. Якщо ви змінили свій перший розмиток на рядок зараз = Date.today, я прийму його.
darthtrevino 02.03.11

3
@Matt: а як відняти 90 годин замість днів?
Естебан Фельдман

@EstebanFeldman Dateтакож дозволяє дроби, щоб ви могли це робити Date.today - (90.0/24.0). Результат може бути легко перетворений to_datetimeабо to_timeтеж.
jchook

15

Для тих, хто використовує Rails, перевірте наступне:

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

Якщо ви використовуєте Rails або не проти включити ActiveSupport, ви можете використовувати цифровий DSL # днів таким чином:

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 

Оскільки ви працюєте з датами, а не з часом, вам слід також почати з екземплярів Date, або перетворити дати DateTime у відстані за допомогою #to_date. Під час додавання / віднімання чисел від екземплярів дати, числа неявно є днями.

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 підтримує арифметику дати в класах Date та DateTime , які є частиною стандартної бібліотеки Ruby. Обидва ці класи надають методи # + та # - , які додають і віднімають дні від дати чи часу.

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

Використовуйте методи # << і # >>, щоб оперувати місяцями, а не днями. Арифметика за місяцями трохи відрізняється від арифметики за днями. Використання Date замість DateTime робить ефект більш очевидним.

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

Наслідуючи приклад joda-time, ви можете написати щось подібне на Ruby.

now =  DateTime.now
ninety_days_ago = now - 90

а може просто

ninety_days_ago = DateTime.now - 90

5

Це надзвичайно стара публікація, але якщо ви хочете зберегти Timeоб’єкт, як спочатку запитували, а не переходити на Dateоб’єкт, який, можливо, вам варто розглянутиRuby Facets .

Ruby Facets - це стандартизована бібліотека розширень для основних класів Ruby.

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

Потрібні грані, ви можете зробити наступне з об’єктами Time.

Time.now.less(90, :days)


Цей проект не оновлювався протягом двох років і відкрив питання одним коментарем. Це мертве.
user4674453 07

@ user4674453 Останнє оновлення було півроку тому. Це стабільна бібліотека, яка досі працює з останньою версією Ruby. Не всі бази кодів потрібно оновлювати щодня, щоб не вважати їх «мертвими».
bigtunacan


-1

Просте рішення:

days90_ago = 90.days.ago.to_date.to_s

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

Це використовує ActiveSupport (Rails).
Еспен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.