2010-11-14 13 views
13

Po prostu patrzę na ruby ​​i bawiłem się z datą/czasem.Odejmowanie dat z Rubinem

irb(main):001:0> jamis_DOB = Time.mktime(2003, 10, 22, 06, 59) 
=> Wed Oct 22 06:59:00 +0300 2003 
irb(main):002:0> age = Time.now - jamis_DOB 
=> 222934108.172989 
irb(main):005:0> age_in_years = (((age/3600)/24)/365).to_i 
=> 7 

Więc mój przykład nie jest tak dobry jak age_in_years nie będzie wiedział, czy są lata przestępne, jak te lata sumują się. Przeszedłem kilka samouczków poświęconych czasowi/dacie i nie znalazłem łatwego sposobu na odjęcie dwóch dat i zwrócenie go w formacie lat, miesięcy, dni itd. Zgaduję, że ruby ​​ma dodatek lub coś wbudowanego do tego rodzaju rzeczy. Czy ktoś może mi powiedzieć, co to jest? (Także, jakakolwiek rada, jak znaleźć odpowiedzi na tego typu rzeczy na przyszłość?)

Dzięki.

Odpowiedz

29

Chcesz Date zamiast Time:

require 'date' 

now = Date.today 
before = Date.civil(2000, 1, 1) 
difference_in_days = (now - before).to_i 

(difference_in_days/365.25).to_i 

daje różnicę w latach między dzisiaj a 1 stycznia 2000. Może to prawdopodobnie być lepsze, po prostu stosować średnią liczbę dni w roku (365,25), która da ci właściwą odpowiedź, z wyjątkiem ekstremalnych przypadków.

Można też zrobić coś takiego:

require 'date' 

years = 0 
d = Date.civil(2000, 1, 1) 
loop do 
    d = d.next_year 
    break if Date.today < d 
    years += 1 
end 

Ale Date#next_year został wprowadzony w Ruby 1.9, więc to nie będzie działać w 1.8.7.

Oczywiście, najprostszym sposobem określenia liczby lat między dwiema datami jest po prostu odjęcie liczby:

2010 - 2000 # => 10 
+0

Dzięki Theo :) 3rd sugestia zainspirowała mnie do zrobienia ... wymagać " termin” date_now = Date.today DOB = Date.civil (2003, 10, 22) jeśli date_now.month> dob.month wiek = date_now.year - dob.year elsif date_now.month == DOB .month && date_now.day> dob.day wiek = date_now.year - dob.year inny wieku = (date_now.year - dob.year) - 1 końcowego koniec print "Prawidłowe wiek jest" wiek "\ n" I Naprawdę nie mogłem zrozumieć twojej drugiej sugestii i nie mogę uzyskać 1,9 działającego na nią. – Leke

+0

Tak, masz rację, ostatni przykład oczywiście bierze pod uwagę miesiąc i dzień. Środkowy przykład to tylko jeden rok dla każdego zwrotu w pętli i liczy się zwoje. Zmieniłem go, by był trochę bardziej poprawny. – Theo

+2

Byłem bardzo zdezorientowany tym, dlaczego Ruby zawsze zwracał '/ 1' po odejmowaniu mojej daty, było ważne, aby zrobić' to_i' na wyniku, jak wspomniano powyżej, aby uzyskać wartość jako liczbę dni. – waffl