简体   繁体   English

Ruby on Rails从日期时间解析时间,而不是字符串

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

I'm trying to extract the time component from a DateTime object (which is represented as "at" in my example). 我正在尝试从DateTime对象(在我的示例中表示为“ at”)中提取时间分量。 How do I do this, I am absolutely stumped? 我该怎么办,我很沮丧吗? (I don't want to parse it to a string with strftime as i did here): (我不想像我在这里那样用strftime将其解析为字符串):

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

I would really like to return the hours and minutes as a Time object. 我真的很想将小时和分钟作为Time对象返回。

If you have a DateTime object: 如果您有一个DateTime对象:

date_time = DateTime.now

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

Is there a specific reason you want a Time object? 您是否需要时间对象的特定原因?

Just so we're clear, the Time class in Ruby isn't just "DateTime without the date." 就像我们清楚地知道的那样,Ruby中的Time类不仅仅是“没有日期的DateTime”。 As " What's the difference between DateTime and Time in Ruby? " explains, "Time is a wrapper around POSIX-standard time_t, or seconds since January 1, 1970." 正如“ Ruby中的DateTime和Time有什么区别? ”解释说,“ Time是POSIX标准time_t的包装,或者是自1970年1月1日以来的秒数。” Like DateTime, a Time object still has year, month, and day, so you don't really gain anything by using Time instead. 与DateTime一样,Time对象仍然具有年,月和日,因此使用Time并不会带来任何好处。 There's not really a way to represent just hour and minute using either Time or DateTime. 确实没有一种方法可以使用Time或DateTime仅表示小时和分钟。

The best you could do with Time, I think, would be this: 我认为,使用Time可以做的最好的事情是:

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

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

...but then you still have to call time.hour and time.min to get at the hour and minute. ...但是您仍然必须致电time.hourtime.min来获取小时和分钟。

If you're just looking for a lightweight data structure to represent an hour and minute pair, though, you might as well just roll your own: 但是,如果您只是在寻找一个轻量级的数据结构来表示小时和分钟,那么您也可以自己滚动:

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 ]

Edit re: 重新编辑:

I have a variable that stores an appointment -- this variable is a DateTime object. 我有一个存储约会的变量-该变量是DateTime对象。 I have two table fields that store the start and end times of a location. 我有两个表字段,用于存储位置的开始时间和结束时间。 I need to check if the time scheduled for that appointment lies between the start and end times. 我需要检查为该约会安排的时间是否在开始时间和结束时间之间。

Ah, it seems you had a bit of a XY problem . 嗯,看来您有点XY问题 This makes a lot more sense now. 现在,这变得更加有意义。

Absent any more information, I'm going to assume your "fields that store the start and end times of a location" are MySQL TIME columns called start_time and end_time . 缺少更多信息,我将假设您的“存储位置开始和结束时间的字段”是MySQL TIME列,称为start_timeend_time Given MySQL TIME columns, Rails casts the values to Time objects with the date component set to 1/1/2000 . 给定MySQL TIME列,Rails将日期分量设置为1/1/2000的值转换为Time对象。 So if your database has the values start_time = '09:00' and end_time = '17:00' , Rails will give you Time objects like this: 因此,如果您的数据库具有值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 ...

Now you say your appointment time is a DateTime, so let's call it appointment_datetime and suppose it's at 10:30am tomorrow: 现在你说你的预约时间是一个DateTime,让我们把它叫做appointment_datetime并假设它在上午10:30明天:

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

So now to rephrase your question: How do we tell if the time part of appointment_datetime is between the time part of start_time and end_time . 所以,现在要改一下你的问题:我们如何告诉我们,如果在部分时间 appointment_datetime是部分时间之间start_timeend_time The answer is, we need to either change the date part of start_time and end_time to match the date part of appointment_datetime , or the other way around. 答案是,我们需要更改的日期部分start_timeend_time匹配的日期部分appointment_datetime ,或者反过来。 Since it's easier to change one thing than two, let's do it the other way around and change appointment_datetime to match start_time and end_time (and, since those two are Time objects, we'll create a Time object): 由于更改一件事情要比更改一件事情容易,让我们以另一种方式来做,并更改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 ...

Now we can compare them directly: 现在我们可以直接比较它们:

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

You would, of course, want to wrap all of this up in a method, perhaps in your Location model (which, again, I'm assuming has start_time and end_time attributes): 当然,您可能希望将所有这些都包装在一个方法中,也许是在您的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

I hope that's helpful! 希望对您有所帮助!

PS Another way to implement this would be to ditch the date/time objects entirely and do a straight numeric comparison: 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