Ruby / Rails: konwertowanie daty na znacznik czasu UNIX

202

Jak uzyskać znacznik czasu UNIX (liczba sekund od 1970 GMT) z obiektu Date w aplikacji Rails?

Wiem, że Time#to_izwraca znacznik czasu, ale zrobienie Date#to_timei otrzymanie znacznika czasu powoduje coś, co jest wyłączone o około miesiąc (nie jestem pewien, dlaczego ...).

Jakakolwiek pomoc się przyda, dzięki!

Edycja: OK, chyba to wymyśliłem - przetwarzałem datę kilka razy w pętli i za każdym razem data była nieco przesuwana z powodu niedopasowania strefy czasowej, co ostatecznie doprowadziło do tego, że mój znacznik czasu był miesiącem wolnym. Mimo to chciałbym wiedzieć, czy można to zrobić bez polegania na tym Date#to_time.

igul222
źródło

Odpowiedzi:

350

Kod date.to_time.to_ipowinien działać poprawnie. Poniższa sesja konsoli Rails pokazuje przykład:

>> Date.new(2009,11,26).to_time
=> Thu Nov 26 00:00:00 -0800 2009
>> Date.new(2009,11,26).to_time.to_i
=> 1259222400
>> Time.at(1259222400)
=> Thu Nov 26 00:00:00 -0800 2009

Zauważ, że pośredni obiekt DateTime znajduje się w czasie lokalnym, więc znacznik czasu może być o kilka godzin wolny od tego, czego oczekujesz. Jeśli chcesz pracować w czasie UTC, możesz użyć metody DateTime „to_utc”.

David Grayson
źródło
3
DateTime nie mato_utc
Zielony
12
date.to_time.utcprawdopodobnie to miał na myśli.
Adam Eberlin,
3
W Railsach za pośrednictwem ActiveSupport instancja DateTime ma metodę utc () (również aliasy do getutc)
Gokul
71

Gdy próbuję, otrzymuję następujące informacje:

>> Date.today.to_time.to_i
=> 1259244000
>> Time.now.to_i
=> 1259275709

Różnica między tymi dwiema liczbami wynika z faktu, że Datenie przechowują godzin, minut ani sekund bieżącego czasu. Konwersja a Datena a Timespowoduje, że tego dnia będzie północ.

Ryan Bigg
źródło
9

Sugerowane opcje użycia to_utclub utcustawienia lokalnego przesunięcia czasu nie działają. Dla mnie stwierdziłem, że używanie Time.utc()działa poprawnie, a kod wymaga mniej kroków:

> Time.utc(2016, 12, 25).to_i
=> 1482624000 # correct

vs

> Date.new(2016, 12, 25).to_time.utc.to_i
=> 1482584400 # incorrect

Oto, co dzieje się, gdy wywołujesz utc po użyciu Date....

> Date.new(2016, 12, 25).to_time
=> 2016-12-25 00:00:00 +1100 # This will use your system's time offset
> Date.new(2016, 12, 25).to_time.utc
=> 2016-12-24 13:00:00 UTC

... więc wyraźne wywołanie to_ida niewłaściwy znacznik czasu.

Gerry
źródło
8

Rozwiązanie dla Ruby 1.8, gdy masz dowolny obiekt DateTime:

1.8.7-p374 :001 > require 'date'
 => true 
1.8.7-p374 :002 > DateTime.new(2012, 1, 15).strftime('%s')
 => "1326585600"
Nowaker
źródło
4
DateTime.new(2012, 1, 15).to_time.to_i
niebo wang
źródło