Подтвердить что ты не робот

Нужны ли классы Date, Time и DateTime?

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

4b9b3361

Ответ 1

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

Что касается DateTime vs, 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 может повысить производительность.

Ответ 2

Чтобы обобщить общие классы времени Ruby:

Time

Это основной класс ядра рубинового ядра.

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

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

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. Добавление времени по границе DST не изменит смещение, и результирующее время суток будет неправильным.

ActiveSupport::TimeWithZone

Здесь стоит упомянуть то, что вы используете в Rails. То же, что и Time, плюс:

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

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

Date

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

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

DateTime

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

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

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)

Кроме того, у него есть бессмысленный атрибут "зона" (обратите внимание, что нелокальные объекты Time предупреждают вас, что 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. Если у кого-то есть реальный прецедент для этого класса, я бы хотел прочитать ваши комментарии.

Ответ 3

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

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)

Ответ 4

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

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

Ответ 5

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

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

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

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