2011-12-18 10 views
20

Jestem nieco zdezorientowany między datą, datetime i czasem w Ruby. Co więcej, moja aplikacja jest wrażliwa na strefy czasowe i nie jestem pewien, jak przekonwertować te trzy elementy, będąc jednocześnie odpornym na strefy czasowe.Sprawdź, czy dwa znaczniki czasu są tego samego dnia w Ruby

Jak mogę sprawdzić, czy dwa znaczniki uniksowe (sekundy od epoki) reprezentują ten sam dzień? (Właściwie to nie mam nic przeciwko, jeśli używa czasu lokalnego lub czasu UTC, podczas gdy ja wolałbym czas lokalny, o ile jest spójny, mogę to zaprojektować).

Odpowiedz

37

Korzystanie standard biblioteka, przekonwertuj obiekt czasu na datę.

require 'date' 

Time.at(x).to_date === Time.at(y).to_date 

Date ma metodę === który będzie prawdziwe, jeśli dwa obiekty data reprezentują ten sam dzień.

+0

Czy to jest w UTC? – chimeracoder

+0

Daty i godziny w Ruby są strefami czasowymi. Jeśli więc utworzysz obiekt Date za pomocą UTC, wówczas tak będzie w UTC. Jeśli utworzysz je przy użyciu innej strefy, będą one znajdować się w tej strefie. – Anurag

+2

eh, dlaczego to zostało odrzucone? – Anurag

5

ActiveSupport definiuje klasę to_date method dla klasy. Tak to wygląda:

class Time 
    def to_date 
    ::Date.new(year, month, day) 
    end 
end 

Używając go można porównać znaczniki czasu tak:

Time.at(ts1).to_date === Time.at(ts2).to_date 

i tutaj jest mniej kontrowersyjny sposób bez rozszerzania Time Klasa:

t1 = Time.at(ts1) # local time corresponding to given unix timestamp ts1 
t2 = Time.at(ts2) 
Date.new(t1.year, t1.month, t1.day) === Date.new(t2.year, t2.month, t2.day) 
+0

To pytanie jest oznaczone jako "Ruby"; Nie sądzę, aby było słuszne założenie, że używa Rails. –

+0

Tak, nie używam Rails. Ponadto, Time.at (1324196871) .to_date == Time.at (1324253810) .to_date zwraca dla mnie wartość false ... czy automatycznie przekonwertuje sygnaturę czasową na czas lokalny? – chimeracoder

+0

Ale sam może zdefiniować tę metodę pomocy. Kod jest dostępny. :-) –

2
Time.at(ts1).day == Time.at(ts2).day && (ts1 - ts2).abs <= 86400 

Albo

t1 = Time.at(ts1) 
t2 = Time.at(ts2) 
t1.yday == t2.yday && t1.year == t2.year 

W pierwszym przypadku mamy pewność, że znaczniki czasu są nie więcej niż dzień siebie (bo #day zwraca dzień miesiąca i bez tego dodatkowego czeku 01 kwietnia będzie równa maja 1)

Alternatywą jest wziąć dzień w roku i upewnić się, że są tego samego roku.

Metody te działają równie dobrze zarówno w 1.8 i 1.9 :-)

1

Możemy użyć beginning_of_day czasu i porównać je: t1.beginning_of_day == t2.beginning_of_day ten sposób nie zostaną naruszone stref czasowych.

Powiązane problemy