2012-03-07 24 views
20

Jak określić liczbę dni między dwiema instancjami czasu w Ruby?Liczba dni między dwoma instancjami czasu

> earlyTime = Time.at(123) 
> laterTime = Time.now 
> time_difference = laterTime - earlyTime 

Chciałbym określić liczbę dni w time_difference (I nie martwię się o ułamki dni. Zaokrąglanie w górę lub w dół jest w porządku).

+2

Czy zależy Ci na czasie letnim? – Phrogz

+1

dobre pytanie. rozliczanie czasu letniego i lat przestępnych nie jest krytyczne, ponieważ to obliczenie powoduje jedynie przypomnienie o kilku osobach. – SundayMonday

Odpowiedz

34

Różnica dwóch razy to w sekundach. Podziel go przez liczbę sekund w ciągu 24 godzin.

(t1 - t2).to_i/(24 * 60 * 60) 
+3

To nie działa w przypadku zmian czasu letniego. – ChrisInEdmonton

+0

Co to jest dobry sposób na to, aby uwzględnić DST? – Tallboy

+0

@Tallboy, co robię, to przechowuję wszystko w 'UTC' i wykonuję te obliczenia za pomocą' Time' instancji 'zone'' UTC'. Czas letni będzie odpowiednio pokazywany podczas renderowania dowolnego "Czasu" w widoku. –

5
earlyTime = Time.at(123) 
laterTime = Time.now 
time_difference = laterTime - earlyTime 
time_difference_in_days = time_difference/1.day # just divide by 1.day 
+0

Przykro mi, wspomniałeś Ruby ale nie konkretnie Ruby on Rails. Nie sądzę, że dostaniesz funkcjonalność 1.day w rubinach waniliowych. –

+1

To prawda, nie masz. Chyba, że ​​potrzebujesz odpowiedniej części active_support. –

+0

To nie działa w przypadku zmian czasu letniego. – ChrisInEdmonton

15
require 'date' 
days_between = (Date.parse(laterTime.to_s) - Date.parse(earlyTime.to_s)).round 

Edit ... albo prościej ...

require 'date' 
(laterTime.to_date - earlyTime.to_date).round 
+0

Sztywne czasy tylko po to, by je parsować, wydają mi się trochę dziwne :) –

+0

@Sergio Masz rację, to było głupie.Edytowane :) – Phrogz

4

Aby uwzględnić DST (Daylight Saving Time), trzeba się liczyć go przez dni. Zauważ, że ta zakłada mniej niż dzień liczony jest jako 1 (w zaokrągleniu):

num = 0 
cur = start_time 
while cur < end_time 
    num += 1 
    cur = cur.advance(:days => 1) 
end 
return num 
+0

zbyt wolno do ogólnego użytku –

3
[1] pry(main)> earlyTime = Time.at(123) 
=> 1970-01-01 01:02:03 +0100 
[2] pry(main)> laterTime = Time.now 
=> 2014-04-15 11:13:40 +0200 
[3] pry(main)> (laterTime.to_date - earlyTime.to_date).to_i 
=> 16175 
0

Żadna z tych odpowiedzi będzie faktycznie działać, jeśli nie chcesz, aby oszacować i chcesz wziąć pod uwagę światło dzienne oszczędność czasu. Na przykład 10 rano w środę przed zmianą zegarową i 10 w środę później, czas między nimi wynosił 1 tydzień i 1 godzinę. Wiosną będzie to 1 tydzień minus 1 godzina. W celu uzyskania dokładnego czasu można użyć następującego kodu

def self.days_between_two_dates later_time, early_time 
    days_between = (later_time.to_date-early_time.to_date).to_f 
    later_time_time_of_day_in_seconds = later_time.hour*3600+later_time.min*60+later_time.sec 
    earlier_time_time_of_day_in_seconds = early_time.hour*3600+early_time.min*60+early_time.sec 
    days_between + (later_time_time_of_day_in_seconds - early_time_time_of_day_in_seconds)/1.0.day 
end 
2

Oto prosta odpowiedź, która działa na DST:

numDays = ((laterTime - earlyTime)/(24.0*60*60)).round

60 * 60 to liczba sekund w godzina 24,0 to liczba godzin w ciągu dnia. Jest zmienny, ponieważ niektóre dni trwają nieco dłużej niż 24 godziny, a niektóre są mniejsze. Więc kiedy dzielimy przez liczbę sekund w ciągu dnia, nadal mamy float, a zaokrągla się do najbliższej liczby całkowitej najbliższej.

Więc jeśli przejdziemy przez DST, tak czy inaczej, nadal będziemy obchodzić najbliższy dzień. Nawet jeśli jesteś w jakiejś dziwnej strefie czasowej, która zmienia się o ponad godzinę dla czasu letniego.

Powiązane problemy