2012-04-07 21 views
21

Chcę utworzyć wystąpienie DateTime, które leży 20 minut i 10 sekund w przyszłości. Próbowałem z Time i DateTime w irb, ale nie wydaje się, aby znaleźć sposób, który naprawdę ma sens. Mogę dodawać tylko dni do obiektów DateTime i dodawać tylko sekundy do obiektów Time.Manipulacja czasem w rubinie

Czy nie ma lepszej metody niż konwersja czasu, który chcę dodać w kilka sekund?

Odpowiedz

46

A Time to liczba sekund grzechu Epoka, podczas gdy DateTime jest liczbą dni od epoki, dlatego dodanie 1 do DateTime dodaje cały dzień. Można jednak dodać frakcje dziennie, na przykład

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

Doda 10 sekund d (ponieważ istnieje 86400 sekund w ciągu dnia).

Jeśli używasz szyny, ActiveSupport dodaje kilka metod pomocnika i można zrobić

d + 20.minutes + 10.seconds 

Który będzie zrobić dobry uczynek jest d jest DateTime lub Time. Sam możesz korzystać z ActiveSupport, a obecnie możesz pobrać tylko te bity, których potrzebujesz. Przypominam sobie, że te rzeczy są w activesupport/duration. Sądzę, że istnieje kilka innych klejnotów, które również oferują pomoc w zarządzaniu czasem.

+5

Osobiście wolę wypisywać '60 * 60 * 24', aby było to trochę bardziej oczywiste, skąd pochodzi magiczna liczba, nawet jeśli będzie to oczywiście nieco wolniejsze w czasie wykonywania. –

+0

@AndrewMarshall Zgoda, i chyba że ktoś wykonuje miliony razy manipulacje "DateTime", dwa kolejne operacje mnożenia nie są warte * mikrooptymalizacji *. Nawet o tym nie myśl, dopóki nie napotkasz problemu z wydajnością.Nawet lepiej, a może po prostu zadeklarować stałą na początku kodu? 'SECONDS_PER_DAY = 60 * 60 * 24' i użyj tego. To samo można zrobić dla 'MINUTERS_PER_DAY = 60 * 24' i' HOURS_PER_DAY = 24', choć może ta ostatnia nie jest konieczna, ale dobrze jest być konsekwentnym i po prostu wymienić wszystkie. –

2

Dobrze, interfejs jest prosty i bezpośredni:

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

Jeśli chcesz mieć coś wygodnego, można dodać metody do klasy Time:

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

Ale nie sądzę to jest prostsze:

+4

OP chce DateTime, a nie Time. – steenslag

2

Zakładając, że masz wymagany ActiveSupport lub pracujesz w projekcie Rails. Bardzo Prosty jeden czytelny sposób, aby zrobić to w Ruby jest:

DateTime + 5.minutes 
Time + 5.minutes 

współpracuje także z .seconds, .hours, .days, .weeks, .month, .years

+16

Należy pamiętać, że zakłada to ActiveSupport lub Rails. –

+0

dzięki za informację - myślałem, że to standardowe zachowanie rubinu – alex

2

Wystarczy użyć aktywnych rozszerzeń czasowe wsparcie. Są bardzo wygodne i mniej podatne na błędy, niż próbowanie tego ręcznie. Można importować tylko moduł trzeba:

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

NB: Tak, to jest sprzeczne z linią partii StackOverflow pobytu z dala od bibliotek 3rd party, ale nie powinno się unikać używania bibliotek, gdy są one praktycznie standardowe, znacznie zmniejszają ryzyko i zapewniają lepszą klarowność kodu.