Нужны ли классы Date, Time и DateTime? - PullRequest
34 голосов
/ 09 мая 2011

Какова цель иметь классы Date и Time, когда существует класс DateTime, который может обрабатывать оба?

Ответы [ 5 ]

43 голосов
/ 23 декабря 2012

Подводя итог, что представляют собой общие классы времени в рубине:

Time

Это базовый класс времени в рубине для рабочей лошадки.

  • Имеет дату иатрибуты времени (год, месяц, день, час, мин, сек, подсек)
  • На основе секундных интервалов с плавающей запятой с эпохи Unix (1970-01-01)
  • Может обрабатывать отрицательные временадо эпохи unix
  • Может обрабатывать арифметику времени в секундах
  • Работает в UTC или локальном (системном часовом поясе)

На самом деле 3виды объектов Time, когда дело доходит до работы с часовыми поясами, давайте посмотрим на летнее время, чтобы показать летнее время:

utc = Time.utc(2012,6,1) # => 2012-12-21 00:00:00 UTC
utc.zone       # => "UTC"
utc.dst?       # => false
utc.utc?       # => true
utc.utc_offset # => 0

local = Time.local(2012,6,1) # => 2012-06-01 00:00:00 -0700
local.zone       # => "PDT"
local.dst?       # => true
local.utc?       # => false
local.utc_offset # => -25200

nonlocal = Time.new(2012,6,1,0,0,0, "-07:00") # => 2012-06-01 00:00:00 -0700
nonlocal.zone       # => nil
nonlocal.dst?       # => false
nonlocal.utc?       # => false
nonlocal.utc_offset # => -25200

Последние 2 выглядят похожими, но будьте осторожны: вы не должны делать арифметику снелокальное время .Это просто время со смещением UTC и без зоны, поэтому он не знает правил DST.Добавление времени за границу летнего времени не изменит смещения, и полученное время суток будет неправильным.

ActiveSupport::TimeWithZone

Это стоит упомянуть здесь, поскольку оно используется вRails.То же, что и время, плюс:

  • Может обрабатывать любой часовой пояс
  • Относится к летнему времени
  • Может конвертировать время между зонами

Я вообщевсегда достигайте этого, когда ActiveSupport доступен, поскольку он заботится обо всех ловушках часового пояса.

Date

  • Имеет только атрибуты даты (год, месяц, день)
  • На основе целочисленных интервалов целого дня из произвольного "нулевого дня" (-4712-01-01)
  • Может обрабатывать арифметику дат в единицах целых дней
  • Может преобразовывать междудаты от древнего юлианского календаря до современного григорианского

Дата более полезна, чем Время, когда вы имеете дело с целыми днями: никаких часовых поясов, чтобы беспокоиться!(Я удивлен, что это не относится к современному персидскому календарю, так как он знает об устаревшем юлианском календаре столетия назад.)

DateTime

  • Имеет дату и времяатрибуты (год, месяц, день, час, мин, сек)
  • На основе долей интервалов целого дня от произвольного "нулевого дня" (-4712-01-01)
  • Можетобрабатывать арифметику дат в единицах целых дней или долей

Лично у меня никогда нет причин использовать это: это медленно, оно обрабатывает время без учета часовых поясов и имеетпротиворечивый интерфейс.Я считаю, что это приводит к путанице, когда вы предполагаете, что у вас есть объект, подобный времени, но на самом деле он ведет себя как дата вместо этого:

Time.new(2012, 12, 31, 0, 0, 0) + 1 == Time.new(2012, 12, 31, 0, 0, 1)
DateTime.new(2012, 12, 31, 0, 0, 0) + 1 == DateTime.new(2013, 1, 1, 0, 0, 0)

Кроме того, он имеет бессмысленную «зону»атрибут (обратите внимание, что нелокальные объекты времени предупреждают вас об этом zone == nil), и вы не можете больше ничего знать о нем, прежде чем сначала превратить его во время:

dt = DateTime.new(2012,12,6, 1, 0, 0, "-07:00")
dt.zone # => "-07:00"
dt.utc? # => NoMethodError: undefined method `utc?'
dt.dst? # => NoMethodError: undefined method `dst?'
dt.utc_offset # => NoMethodError: undefined method `utc_offset'

Работа с микросекундами для проверкиокругление тоже немного странно.Вы можете подумать, что, поскольку у него нет атрибута usec, он имеет дело только с целыми числами, но вы ошибаетесь:

DateTime.now.usec # => NoMethodError: undefined method `usec'
DateTime.now.to_time.usec => 629399

Короче говоря, если вы не имеете дело с астрономическими событиямив древнем прошлом и необходимости конвертировать юлианскую дату (со временем дня) в современный календарь, пожалуйста, не используйте DateTime.Если у кого-то есть реальный вариант использования этого класса, я бы с удовольствием прочитал ваши комментарии.

28 голосов
/ 10 мая 2011

Я знаю, что есть принятый ответ, но мне есть что добавить. Класс Date - тяжелый, академический класс силы. Он может обрабатывать всевозможные RFC, анализировать самые странные вещи и преобразовывать юлианские даты от тысячи лет назад до григорианских с выбранной датой реформы. Класс Time является легким, и он не знает ни одного из этого материала. Это дешевле, и это видно в тесте:

require 'benchmark'
require 'date'

Benchmark.bm(10) do |x|
  x.report('date'){100000.times{Date.today} }
  x.report('datetime'){100000.times{DateTime.now} }
  x.report('time'){100000.times{Time.now} }
end

Результат:

                user     system      total        real
date        1.250000   0.270000   1.520000 (  1.799531)
datetime    6.660000   0.360000   7.020000 (  7.690016)
time        0.140000   0.030000   0.170000 (  0.200738)

(Ruby 1.9.2)

17 голосов
/ 10 мая 2011

DateTime является подклассом Date, поэтому все, что вы можете сделать с Date, можно сделать с DateTime.Но, как указывают Тэдман и Стинслаг, DateTime медленнее.См. Ответ Стинслага о том, насколько он медленнее.

Что касается DateTime против, Time, я нашел здесь .

Цитата


Time is a wrapper around Unix-Epoch.
Date (and DateTime) use rational and a "day zero" for storage. So Time 
is faster but the upper and lower bounds are tied to epoch time (which 
for 32bit epoch times is something around 1970-2040 ... while Date (and DateTime) have an 
almost infinite range but are terribly slow.

Короче говоря, DateTime - универсальная суперзвезда, и ее следует предпочитать в целом, но если вы хотите оптимизировать до последнего бита, используйте Time может улучшить производительность.

4 голосов
/ 10 мая 2011

Другой способ думать об этом заключается в том, что Date и DateTime моделируют время в терминах часов и календарей, что полезно для описания времени для пользователей и планирования событий. Наличие Date без времени - это хорошо, когда вам нет дела до времени, и вы не хотите думать о часовых поясах.

Time моделирует время как континуум и является оберткой вокруг метки времени Unix, которая является просто целым числом. Это полезно для всевозможных внутренних приложений, где компьютер не заботится о том, была ли пересечена граница календаря, а сколько секунд (или миллисекунд) прошло.

0 голосов
/ 09 мая 2011

Да. Date обрабатывает только дату чего-либо, т.е. 31 марта 1989 года. Но она не обрабатывает Time, например, 12:30 PM. DateTime, может обрабатывать как, 31 марта 1989 года 12:30 вечера по восточному времени.

Иногда вам не нужны все части DateTime. Например, вы хотите знать, когда подписка на ваш веб-сайт будет полезной, Дата будет здесь полезной, поскольку время в конечном итоге не имеет значения.

В некоторых случаях вам может понадобиться только время. Например, если время обеда, вы можете сообщить пользователю, что ваш офис закрыт. На данный момент данные не имеют значения.

Однако в большинстве случаев используется DateTime, поскольку его можно использовать как дату, время или как то и другое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...