2012-04-07 42 views
21

Tôi muốn tạo một cá thể DateTime nằm trong 20 phút và 10 giây trong tương lai. Tôi đã thử với Time và DateTime trong irb, nhưng dường như không thể tìm ra một cách thực sự có ý nghĩa. Tôi chỉ có thể thêm ngày vào đối tượng DateTime và chỉ thêm giây vào đối tượng Thời gian.Thao tác thời gian trong ruby ​​

Không có cách nào tốt hơn là luôn luôn chuyển đổi thời gian tôi muốn thêm vào giây?

Trả lời

46

A Time là số giây ce một thời đại trong khi một DateTime là một số ngày kể từ một kỷ nguyên đó là lý do tại sao thêm 1 vào một số DateTime thêm cả ngày. Tuy nhiên bạn có thể thêm các phần phân đoạn của một ngày, ví dụ

d = DateTime.now 
d + Rational(10, 86400) 

Sẽ thêm 10 giây để d (kể từ khi có 86400 giây trong một ngày).

Nếu bạn đang sử dụng Rails, ActiveSupport thêm một số phương pháp helper và bạn có thể làm

d + 20.minutes + 10.seconds 

Mà sẽ làm điều đúng là d là một DateTime hoặc một Time. Bạn có thể sử dụng ActiveSupport một mình, và những ngày này bạn có thể lấy chỉ những bit bạn cần. Tôi dường như nhớ lại rằng công cụ này là trong activesupport/duration. Tôi tin rằng có một số đá quý khác cung cấp trợ giúp với xử lý thời gian quá.

+5

Cá nhân tôi thích viết ra '60 * 60 * 24' để làm cho nó rõ ràng hơn một chút khi số ma thuật xuất phát, mặc dù nó rõ ràng sẽ chậm hơn một chút khi chạy. –

+0

@AndrewMarshall Đồng ý, và trừ khi một người thực hiện thao tác 'DateTime' này hàng triệu lần sau hàng triệu lần, hai phép nhân khác không đáng giá * tối ưu hóa vi *. Thậm chí không nghĩ về nó cho đến khi bạn gặp phải vấn đề về hiệu suất.Thậm chí tốt hơn, làm thế nào về chỉ tuyên bố một hằng số ở đầu mã? 'SECONDS_PER_DAY = 60 * 60 * 24' và sử dụng. Tương tự có thể được thực hiện cho 'MINUTERS_PER_DAY = 60 * 24' và' HOURS_PER_DAY = 24', mặc dù có thể điều cuối cùng không cần thiết, nhưng tốt nhất là nhất quán và chỉ liệt kê tất cả. –

2

Vâng, giao diện rất đơn giản và dễ hiểu:

t = Time.now 
t + (20 * 60 + 10) 

Nếu bạn muốn có một cái gì đó thuận tiện, bạn có thể thêm phương thức cho lớp Time:

class Time 
    def add_minutes(m) 
    self + (60 * m) 
    end 
end 

Nhưng tôi không nghĩ rằng điều này đơn giản hơn:

t = Time.now 
t.add_minutes(20) + 10 
+4

OP muốn Ngày giờ, không phải Thời gian. – steenslag

2

Giả sử bạn đã yêu cầu ActiveSupport hoặc bạn đang làm việc trong dự án Rails. Một rất đơn giản một cách có thể đọc được để làm điều này trong ruby ​​là:

DateTime + 5.minutes 
Time + 5.minutes 

Cũng làm việc với .seconds, .hours, .days, .weeks, .month, .years

+16

Xin lưu ý rằng điều này giả định bạn có ActiveSupport hoặc Rails. –

+0

cảm ơn thông tin - tôi nghĩ đây là hành vi tiêu chuẩn ruby – alex

2

Chỉ cần sử dụng các phần mở rộng thời gian hỗ trợ tích cực. Họ rất thuận tiện và ít bị lỗi hơn là cố gắng làm điều này bằng tay. Bạn có thể nhập chỉ module bạn cần:

# gem 'activesupport' 
require 'active_support/core_ext/numeric/time.rb' 
DateTime.now + 20.minutes 

NB: Vâng, đây đi ngược lại đường lối của đảng StackOverflow của tránh xa thư viện của bên thứ 3, nhưng bạn không nên tránh sử dụng các thư viện khi họ đang có thực tế tiêu chuẩn, giảm nguy cơ đáng kể, và cung cấp mã rõ ràng hơn.