Jakie czynniki skłoniłyby mnie do wyboru jednego lub drugiego?Jaka jest różnica między DateTime i Time w Ruby?
Odpowiedz
Nowsze wersje Ruby (2.0+) tak naprawdę nie różnią się znacząco między dwiema klasami. Niektóre biblioteki będą używać jednego z nich z powodów historycznych, ale nowy kod niekoniecznie musi być zaniepokojony. Wybór jednego dla spójności jest prawdopodobnie najlepszy, spróbuj więc dopasować to, czego oczekują twoje biblioteki. Na przykład ActiveRecord preferuje DateTime.
W wersjach wcześniejszych niż Ruby 1.9 i wielu systemach Czas jest reprezentowany jako 32-bitowa wartość ze znakiem, opisująca liczbę sekund od 1 stycznia 1970 UTC, cienkie opakowanie o wartości zgodnej ze standardem POSIX time_t
i ograniczone :
Time.at(0x7FFFFFFF)
# => Mon Jan 18 22:14:07 -0500 2038
Time.at(-0x7FFFFFFF)
# => Fri Dec 13 15:45:53 -0500 1901
Nowsze wersje Ruby są w stanie obsłużyć większe wartości bez tworzenia błędów.
DateTime to podejście oparte na kalendarzach, w którym rok, miesiąc, dzień, godzina, minuta i sekunda są przechowywane indywidualnie. Jest to konstrukcja Ruby on Rails, która służy jako opakowanie dla standardowych pól DATETIME języka SQL. Zawierają one arbitralne daty i mogą reprezentować prawie każdy punkt w czasie, ponieważ zakres ekspresji jest zazwyczaj bardzo duży.
DateTime.new
# => Mon, 01 Jan -4712 00:00:00 +0000
Zapewnia to, że DateTime może obsłużyć posty na blogu od Arystotelesa.
Wybierając jeden, różnice są teraz nieco subiektywne. Historycznie DateTime zapewniało lepsze opcje manipulowania nim w kalendarzu, ale wiele z tych metod przeniesiono również do czasu, przynajmniej w środowisku Rails.
Myślę, że odpowiedź na pytanie "jaka jest różnica" jest jedną z niefortunnych, wspólnych odpowiedzi na to pytanie w standardowych bibliotekach Ruby: dwie klasy/biblioteki zostały stworzone w różny sposób przez różnych ludzi w różnym czasie. Jest to jedna z niefortunnych konsekwencji społecznościowej ewolucji Rubiego w porównaniu ze starannie zaplanowanym rozwojem czegoś takiego jak Java. Deweloperzy oczekują nowej funkcjonalności, ale nie chcą wchodzić na istniejące interfejsy API, więc tworzą nową klasę - dla użytkownika końcowego nie ma żadnego oczywistego powodu, dla którego obie strony mogłyby istnieć.
Dotyczy to ogólnie bibliotek oprogramowania: często powodem tego, że jakiś kod lub interfejs API jest taki, jak się okazuje, jest raczej historyczny niż logiczny.
Kuszenie zaczyna się od DateTime, ponieważ wydaje się bardziej ogólne. Data ... i czas, prawda? Źle. Czas również robi daty lepiej, i faktycznie może parsować strefy czasowe, gdzie DateTime nie może. Działa również lepiej.
Skończyło się na używaniu czasu wszędzie.
Dla bezpieczeństwa jednak pozwalam na przekazywanie argumentów DateTime do moich interfejsów API Timey i albo konwertuję. Także, jeśli wiem, że obie mają metodę Jestem zainteresowany Akceptuję albo, jak tej metody napisałem dla razy konwersji do formatu XML (dla plików xmltv)
# Will take a date time as a string or as a Time or DateTime object and
# format it appropriately for xmtlv.
# For example, the 22nd of August, 2006 at 20 past midnight in the British Summertime
# timezone (i.e. GMT plus one hour for DST) gives: "20060822002000 +0100"
def self.format_date_time(date_time)
if (date_time.respond_to?(:rfc822)) then
return format_time(date_time)
else
time = Time.parse(date_time.to_s)
return format_time(time)
end
end
# Note must use a Time, not a String, nor a DateTime, nor Date.
# see format_date_time for the more general version
def self.format_time(time)
# The timezone feature of DateTime doesn't work with parsed times for some reason
# and the timezone of Time is verbose like "GMT Daylight Saving Time", so the only
# way I've discovered of getting the timezone in the form "+0100" is to use
# Time.rfc822 and look at the last five chars
return "#{time.strftime('%Y%m%d%H%M%S')} #{time.rfc822[-5..-1]}"
end
Ponadto, Time.new i DateTime.new mają do czynienia ze strefą czasową w różny sposób. Jestem na GMT + 7, więc 'Time.nowy (2011, 11, 1, 10, 30) 'produkuje' 2011-11-01 10:30:00 + 0700' podczas gdy 'DateTime.new (2011, 11, 1, 10, 30)' tworzy 'Wt, 01 Lis 2011 10:30:00 + 0000 ". –
I jak wszyscy wiemy, starannie zaplanowany rozwój Javy zaowocował wyłącznie prostymi, logicznymi interfejsami API. – pje
@ PhươngNguyễn: Czy dodasz to jako odpowiedź, abym mógł ją głosować w górę? Właśnie z tego powodu zdecydowałem się wybrać Time over DateTime. – Senseful
Nieaktualny! Zobacz poniżej ...
Różnice w wydajności nie można wystarczająco podkreślić ...Czas to C i DateTime jest Ruby:
>> Benchmark.bm do |bm|
?> bm.report('DateTime:') do
?> n1 = DateTime.now
>> n2 = DateTime.now
>> 1_000_000.times{ n1 < n2 }
>> end
>> bm.report('Time: ') do
?> n1 = Time.now
>> n2 = Time.now
>> 1_000_000.times{ n1 < n2 }
>> end
>> end
user system total real
DateTime: 4.980000 0.020000 5.000000 ( 5.063963)
Time: 0.330000 0.000000 0.330000 ( 0.335913)
Update (2/2012):
Jak już wspomniano w komentarzu, 1.9.3 znacznie zwiększyła DateTime
wydajność:
user system total real
DateTime: 0.330000 0.000000 0.330000 ( 0.333869)
Time: 0.300000 0.000000 0.300000 ( 0.306444)
Aktualizacja: Ruby 1.9.3 powinien przynieść szybsze 'DateTime' zaimplementowane w C: http://www.rubyinside.com/ruby-1-9-3-preview-1-released-5229.html, więc ta odpowiedź z nadzieją może nie być istotnym dłużej. –
Uruchomiłem twój kod w Ruby 2.0.0-p247, a moje wyniki są bardzo różne. Z DateTime jest znacznie szybszy (5 razy) 'DateTime: 0.520000 0.010000 0.530000 (0.522596) | Czas: 2.800000 0.000000 2.800000 (2.814311) ' – Leito
Powtarzam to samo na 32-bitowym Ruby 2.0.0p247' DateTime: 0.200000 0.010000 0.210000 (0.200798) | Czas: 0.180000 0.000000 0.180000 (0.184122) ' – Kokizzu
Znalazłem takie rzeczy jak parsowanie i obliczanie początku/końca dnia w różnych strefach czasowych są łatwiejsze do zrobienia z DateTime, zakładając, że korzystasz z rozszerzeń ActiveSupport.
W moim przypadku musiałem obliczyć koniec dnia w strefie czasowej użytkownika (dowolna) w oparciu o czas lokalny użytkownika, który otrzymałem jako ciąg znaków, np. "10.10.2012 10:10 +0300"
Z DateTime jest to tak proste jak
irb(main):034:0> DateTime.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 +0300
# it preserved the timezone +0300
Teraz spróbujmy go w ten sam sposób z Czasu:
irb(main):035:0> Time.parse('2012-10-10 10:10 +0300').end_of_day
=> 2012-10-10 23:59:59 +0000
# the timezone got changed to the server's default UTC (+0000),
# which is not what we want to see here.
Właściwie potrzebuje czasu znać strefę czasową przed parsowania (również pamiętać, że to Time.zone.parse
nie Time.parse
):
irb(main):044:0> Time.zone = 'EET'
=> "EET"
irb(main):045:0> Time.zone.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 EEST +03:00
S o, w tym przypadku zdecydowanie łatwiej jest iść z DateTime.
Używając tego w produkcji teraz, są czy są jakieś wady techniki? –
DateTime nie uwzględnia czasu letniego. Tak więc przy oszczędzaniu czasu nie będzie działać poprawnie. 'DateTime.parse ('2014-03-30 01:00:00 +0100'). End_of_day' produkuje' Sun, 30 Mar 2014 23:59:59 + 0100', ale 'Time.zone = 'CET'; Time.zone.parse ('2014-03-30 01:00:00'). End_of_day' produkuje 'Sun, 30 Mar 2014 23:59:59 CEST +02: 00' (CET = + 01: 00, CEST = +02: 00 - zauważ, że przesunięcie zostało zmienione). Ale aby to zrobić, potrzebujesz więcej informacji o strefie czasowej użytkownika (nie tylko przesunięcie, ale także o tym, czy oszczędzasz czas). –
Może to być oczywiste, ale 'Time.zone.parse' jest * bardzo * użyteczne podczas analizowania czasu z różnymi strefami - zmusza do zastanowienia się, która strefa powinna być używana. Czasami funkcja Time.find_zone działa jeszcze lepiej. – prusswan
Począwszy od ruby 2.0, większość z wyżej wymienionych informacji jest nieaktualna.
W szczególności Time
jest obecnie praktycznie niezwiązany. Może ona być wyższa lub nawet mniej niż 63 bitów ze Epoki:
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> Time.at(2**62-1).utC# within Integer range
=> 146138514283-06-19 07:44:38 UTC
irb(main):003:0> Time.at(2**128).utC# outside of Integer range
=> 10783118943836478994022445751222-08-06 08:03:51 UTC
irb(main):004:0> Time.at(-2**128).utC# outside of Integer range
=> -10783118943836478994022445747283-05-28 15:55:44 UTC
jedynie wskutek użycia większej wartości należy wydajności, co jest lepsze, gdy stosuje się Integer
s (w porównaniu Bignum
S (wartości poza Integer
zakresów) lub Rational
s (przy nanosekund są śledzone)):
od Ruby 1.9.2 wdrożenie czas używa podpisany 63 bitową liczbę całkowitą Bignum lub racjonalny. Liczba całkowita jest liczbą nanosekund od epoki, która może reprezentować 1823-11-12 do 2116-02-20. Gdy używana jest metoda Bignum lub Rational (przed 1823, po 2116, pod nanosekundą), czas działa wolniej, niż gdy używana jest liczba całkowita. (http://www.ruby-doc.org/core-2.1.0/Time.html)
Innymi słowy, o ile mi zrozumieć, DateTime
nie obejmuje szerszy zakres potencjalnych wartości niż Time
.
Ponadto dwa wcześniej niewymienione ograniczenia DateTime
należy prawdopodobnie zauważył:
DateTime nie uznaje żadnych leapseconds, nie zapisuje żadnych zasad okresie letnim. (http://www.ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html#class-Date-label-DateTime)
Najpierw DateTime
ma koncepcji sekundy przestępne:
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> require "date"
=> true
irb(main):003:0> t = Time.new(2012,6,30,23,59,60,0)
=> 2012-06-30 23:59:60 +0000
irb(main):004:0> dt = t.to_datetime; dt.to_s
=> "2012-06-30T23:59:59+00:00"
irb(main):005:0> t == dt.to_time
=> false
irb(main):006:0> t.to_i
=> 1341100824
irb(main):007:0> dt.to_i
=> 1341100823
drugie, DateTime
ma bardzo ograniczoną wiedzę o strefach czasowych, w szczególności ma koncepcji światła dziennego oszczędności. To dość dużo obsługuje stref czasowych jako proste UTC + X offsety:
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> require "date"
=> true
irb(main):003:0> t = Time.local(2012,7,1)
=> 2012-07-01 00:00:00 +0200
irb(main):004:0> t.zone
=> "CEST"
irb(main):005:0> t.dst?
=> true
irb(main):006:0> dt = t.to_datetime; dt.to_s
=> "2012-07-01T00:00:00+02:00"
irb(main):007:0> dt.zone
=> "+02:00"
irb(main):008:0> dt.dst?
NoMethodError: undefined method `dst?' for #<DateTime:0x007f34ea6c3cb8>
Może to powodować problemy, gdy czasy są wprowadzane jako DST, a następnie przekształcony w non-DST strefy czasowej bez śledzenie odpowiednich przesunięć poza DateTime
sama (wiele systemów operacyjnych może już to zająć).
Ogólnie rzecz biorąc, chciałbym powiedzieć, że w dzisiejszych czasach Time
jest lepszym wyborem dla większości aplikacji.
Należy również zwrócić uwagę na ważną różnicę w zakresie dodawania: dodawanie liczby do obiektu czasu jest liczone w sekundach, ale po dodaniu numeru do obiektu DateTime jest ono liczone w dniach.
Zastanów się, jak poradzić sobie z niestandardowymi strefy czasowe inaczej dawałaby:
irb(main):001:0> Time.new(2016,9,1)
=> 2016-09-01 00:00:00 -0400
irb(main):002:0> DateTime.new(2016,9,1)
=> Thu, 01 Sep 2016 00:00:00 +0000
irb(main):003:0> Time.new(2016,9,1).to_i
=> 1472702400
irb(main):004:0> DateTime.new(2016,9,1).to_i
=> 1472688000
To może być trudne podczas tworzenia zakresów czasowych itp
Wydaje się, że tylko z prostym rubinem (tzn. Bez szyn) – vemv
- 1. W Ruby on Rails, jaka jest różnica między DateTime, Timestamp, Time and Date?
- 2. Jaka jest różnica między Ruby i Ruby w Rails?
- 3. Jaka jest różnica między metodami i atrybutami w Ruby?
- 4. Jaka jest różnica między? : i ||
- 5. Jaka jest różnica między $ i $$?
- 6. Jaka jest różnica między testami i specyfikacją?
- 7. Jaka jest różnica między metodą ruby send a ruby public_send?
- 8. Jaka jest różnica między = i: = w mysql?
- 9. Jaka jest różnica między! = I =! w Javie?
- 10. Jaka jest różnica między 'i "w PHP
- 11. Jaka jest różnica między! i !! w yaml?
- 12. jaka jest różnica między @ i @@ w module?
- 13. Jaka jest różnica między * i. * W Matlab?
- 14. Jaka jest różnica między | i || w MATLAB?
- 15. Jaka jest różnica między * i * | * w CSS?
- 16. Jaka jest różnica między% Q a% {} w ruby?
- 17. Jaka jest różnica między ciągiem a symbolem w Ruby?
- 18. Jaka jest różnica między symbolem a zmienną w Ruby?
- 19. Jaka jest różnica między System.Windows.Controls.Control i System.Windows.Forms.Control?
- 20. Jaka jest różnica między asersem i static_assert?
- 21. Jaka jest różnica między PropertyChangeListener i VetoableChangeListener?
- 22. Jaka jest różnica między Ja i Ja?
- 23. Jaka jest różnica między ATL i WTL?
- 24. Jaka jest różnica między FontMetrics.stringWidth() i FontMetrics.getStringBounds()?
- 25. Jaka jest różnica między "CompletionStage" i "CompletableFuture"?
- 26. Jaka jest różnica między CellClick i CellMouseClick?
- 27. Jaka jest różnica między ObjectResult i JsonResult
- 28. Jaka jest różnica między ssize_t i ptrdiff_t?
- 29. Jaka jest różnica między fn i fn *?
- 30. Jaka jest różnica między getMeasuredHeight i getHeight
Dlatego należy zawsze używać DateTime? –
Jeśli pracujesz z datami, użyłbym DateTime. Czas jest wygodny do przedstawiania rzeczy takich jak aktualna pora dnia lub punktów w niedalekiej przyszłości, takich jak 10.minutes.from_now. Oba mają ze sobą wiele wspólnego, choć jak wspomniano, DateTime może reprezentować znacznie szerszy zakres wartości. – tadman
> Czas jest wygodny do przedstawiania rzeczy takich jak aktualna godzina lub punktów w bliskiej przyszłości, takich jak 10.minutes.from_now. Dlaczego w tym celu czas jest wygodniejszy niż DateTime? –