簡體   English   中英

Ruby on Rails從日期時間解析時間,而不是字符串

[英]Ruby on Rails parsing time from datetime, not as string

我正在嘗試從DateTime對象(在我的示例中表示為“ at”)中提取時間分量。 我該怎么辦,我很沮喪嗎? (我不想像我在這里那樣用strftime將其解析為字符串):

@session_date.at.strftime("%H:%M")

我真的很想將小時和分鍾作為Time對象返回。

如果您有一個DateTime對象:

date_time = DateTime.now

date_time.hour
# => 16
date_time.minute
# => 1

您是否需要時間對象的特定原因?

就像我們清楚地知道的那樣,Ruby中的Time類不僅僅是“沒有日期的DateTime”。 正如“ Ruby中的DateTime和Time有什么區別? ”解釋說,“ Time是POSIX標准time_t的包裝,或者是自1970年1月1日以來的秒數。” 與DateTime一樣,Time對象仍然具有年,月和日,因此使用Time並不會帶來任何好處。 確實沒有一種方法可以使用Time或DateTime僅表示小時和分鍾。

我認為,使用Time可以做的最好的事情是:

date_time = DateTime.now
seconds = date_time.hour * 60 * 60 + date_time.minute * 60

time = Time.at(seconds)
# => 1970-01-01 09:58

...但是您仍然必須致電time.hourtime.min來獲取小時和分鍾。

但是,如果您只是在尋找一個輕量級的數據結構來表示小時和分鍾,那么您也可以自己滾動:

HourAndMinute = Struct.new(:hour, :minute) do
  def self.from_datetime(date_time)
    new(date_time.hour, date_time.minute)
  end
end

hm = HourAndMinute.from_datetime(DateTime.now)
# => #<struct HourAndMinute hour=15, minute=58>
hm.to_h
# => { :hour => 15, :minute => 58 }
hm.to_a
# => [ 15, 58 ]

重新編輯:

我有一個存儲約會的變量-該變量是DateTime對象。 我有兩個表字段,用於存儲位置的開始時間和結束時間。 我需要檢查為該約會安排的時間是否在開始時間和結束時間之間。

嗯,看來您有點XY問題 現在,這變得更加有意義。

缺少更多信息,我將假設您的“存儲位置開始和結束時間的字段”是MySQL TIME列,稱為start_timeend_time 給定MySQL TIME列,Rails將日期分量設置為1/1/2000的值轉換為Time對象。 因此,如果您的數據庫具有值start_time = '09:00'end_time = '17:00' ,Rails將為您提供Time對象,如下所示:

start_time = Time.new(2000, 1, 1, 9, 0) # => 2000-01-01 09:00:00 ...
end_time = Time.new(2000, 1, 1, 17, 0)  # => 2000-01-01 17:00:00 ...

現在你說你的預約時間是一個DateTime,讓我們把它叫做appointment_datetime並假設它在上午10:30明天:

appointment_datetime = DateTime.new(2014, 11, 18, 10, 30) # => 2014-11-18 10:30:00 ...

所以,現在要改一下你的問題:我們如何告訴我們,如果在部分時間 appointment_datetime是部分時間之間start_timeend_time 答案是,我們需要更改的日期部分start_timeend_time匹配的日期部分appointment_datetime ,或者反過來。 由於更改一件事情要比更改一件事情容易,讓我們以另一種方式來做,並更改appointment_datetime以匹配start_timeend_time (並且,由於這兩個是Time對象,因此我們將創建一個Time對象):

appointment_time = DateTime.new(2000, 1, 1, appointment_datetime.hour, appointment_datetime.minute)
# => 2000-01-01 10:30:00 ...

現在我們可以直接比較它們:

if appointment_time >= start_time && appointment_time <= end_time
  puts "Appointment time is good!"
end

# Or, more succinctly:
if (start_time..end_time).cover?(appointment_time)
  puts "Appointment time is good!"
end

當然,您可能希望將所有這些都包裝在一個方法中,也許是在您的Location模型中(我再次假設它具有start_timeend_time屬性):

class Location < ActiveRecord::Base
  # ...

  def appointment_time_good?(appointment_datetime)
    appointment_time = DateTime.new(2000, 1, 1,
                         appointment_datetime.hour, appointment_datetime.minute)

    (start_time..end_time).cover?(appointment_time)
  end
end

location = Location.find(12) # => #<Location id: 12, ...>
location.appointment_time_good?(appointment_time) # => true

希望對您有所幫助!

PS實現此目的的另一種方法是完全放棄日期/時間對象並進行直接的數值比較:

def appointment_time_good?(appointment_datetime)
  appointment_hour_min = [ appointment_datetime.hour, appointment_datetime.minute ]

  appointment_hour_min >= [ start_time.hour, start_time.min ]
    && appointment_hour_min <= [ end_time.hour, end_time.min ]
end

如果您正在尋找從現在開始的時間(在Rails應用程序中很常見),那么這可能是一本好書: http : //api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method- i-time_ago_in_words

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM