Phép trừ ngày Ruby (ví dụ: 90 ngày trước)


88

Tôi đã hơi làm hỏng API joda-time của:

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

Tôi đang cố gắng làm điều tương tự trong Ruby, nhưng tôi

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

Tuy nhiên, toán học không có ở đây (tôi thực sự đang làm việc với các ngày vào lúc nửa đêm).

Có API thân thiện để trừ ngày không?

Câu trả lời:


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

Chạy điều này thông qua bảng điều khiển IRB tôi nhận được:

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

Nếu bạn cần thời gian, bạn có thể nói now = DateTime.now


Bài đăng gốc của bạn, bản chỉnh sửa trước gần với những gì tôi cần hơn, nhưng Date.Now đã được bảo vệ. Date.today đã hoạt động. Nếu bạn thay đổi lời giới thiệu đầu tiên của mình thành dòng now = Date.today, tôi sẽ chấp nhận.
darthtrevino

3
@Matt: và làm thế nào để trừ 90 giờ thay vì số ngày?
Esteban Feldman

@EstebanFeldman Datecũng cho phép phân số để bạn có thể thực hiện Date.today - (90.0/24.0). Kết quả có thể dễ dàng được chuyển đổi to_datetimehoặc to_timequá.
jchook

15

Đối với những người sử dụng Rails, hãy kiểm tra những điều sau:

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

Nếu bạn đang sử dụng Rails hoặc không phiền khi bao gồm ActiveSupport, bạn có thể sử dụng DSL Numeric # days như sau:

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 

Vì bạn đang làm việc với ngày thay vì thời gian, bạn cũng nên bắt đầu với các phiên bản Ngày hoặc chuyển đổi các ý định DateTime của bạn bằng #to_date. Khi cộng / trừ các số khỏi các phiên bản ngày, các số này hoàn toàn là ngày.

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 hỗ trợ số học ngày tháng trong các lớp Date và DateTime , là một phần của thư viện chuẩn của Ruby. Cả hai lớp đó đều hiển thị các phương thức # +# - , các phương thức này cộng và trừ các ngày từ một ngày hoặc một thời gian.

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

Sử dụng các phương pháp # <<# >> để hoạt động theo tháng thay vì ngày. Số học theo tháng hơi khác một chút so với số học theo ngày. Sử dụng Date thay vì DateTime làm cho hiệu quả rõ ràng hơn.

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

Theo ví dụ về joda-time của bạn, bạn có thể viết một cái gì đó như thế này trong Ruby.

now =  DateTime.now
ninety_days_ago = now - 90

hoặc có thể chỉ

ninety_days_ago = DateTime.now - 90

5

Đây là một bài đăng siêu cũ, nhưng nếu bạn muốn giữ lại một Timeđối tượng, như đã được hỏi ban đầu, thay vì chuyển sang một Dateđối tượng mà bạn có thể muốn xem xét sử dụng Ruby Facets.

Ruby Facets là một thư viện mở rộng được chuẩn hóa cho các lớp Ruby lõi.

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

Bằng cách yêu cầu các Facets, bạn có thể thực hiện như sau với các đối tượng Thời gian.

Time.now.less(90, :days)


Dự án này đã không được cập nhật trong hai năm và đã mở ra các vấn đề với một nhận xét duy nhất. Nó đã chết rồi.
user4674453 07/07/18

@ user4674453 Bản cập nhật cuối cùng là sáu tháng trước. Đó là một thư viện ổn định vẫn hoạt động với phiên bản mới nhất của Ruby. Không phải tất cả các cơ sở mã cần được cập nhật hàng ngày để không bị coi là "chết".
bigtunacan

5

sử dụng số giây:

Time.now - 90*24*60*60

-1

Giải pháp đơn giản:

days90_ago = 90.days.ago.to_date.to_s

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

Điều này đang sử dụng ActiveSupport (Rails).
Espen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.