[英]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.hour
和time.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_time
和end_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_time
和end_time
。 答案是,我們需要更改的日期部分start_time
和end_time
匹配的日期部分appointment_datetime
,或者反過來。 由於更改一件事情要比更改一件事情容易,讓我們以另一種方式來做,並更改appointment_datetime
以匹配start_time
和end_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_time
和end_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.