简单的问题,但我找不到一个好的或明确的答案。将Ruby Date和Time对象(对象,而不是字符串)组合到单个DateTime对象中的最佳和最有效的方法是什么?
答案 0 :(得分:46)
我发现了这一点,但它并不像你希望的那样优雅:
d = Date.new(2012, 8, 29)
t = Time.now
dt = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec, t.zone)
顺便说一句,ruby Time对象还存储了一年,一个月和一天,所以当你创建DateTime时你会丢掉它。
答案 1 :(得分:16)
简单:
Date.new(2015, 2, 10).to_datetime + Time.parse("16:30").seconds_since_midnight.seconds
# => Object: Tue, 10 Feb 2015 16:30:00 +0000
你必须爱Ruby!
答案 2 :(得分:14)
使用seconds_since_midnight
时,夏令时的变化可能会导致意外结果。
Time.zone = 'America/Chicago'
t = Time.zone.parse('07:00').seconds_since_midnight.seconds
d1 = Time.zone.parse('2016-11-06').to_date # Fall back
d2 = Time.zone.parse('2016-11-07').to_date # Normal day
d3 = Time.zone.parse('2017-03-12').to_date # Spring forward
d1 + t
#=> Sun, 06 Nov 2016 06:00:00 CST -06:00
d2 + t
#=> Mon, 07 Nov 2016 07:00:00 CST -06:00
d3 + t
#=> Sun, 12 Mar 2017 08:00:00 CDT -05:00
这是一个替代方案,类似于@ selva-raj上面的答案,使用字符串插值,strftime
和parse
。 %F
等于%Y-%m-%d
且%T
等于%H:%M:%S
。
Time.zone = 'America/Chicago'
t = Time.zone.parse('07:00')
d1 = Time.zone.parse('2016-11-06').to_date # Fall back
d2 = Time.zone.parse('2016-11-07').to_date # Normal day
d3 = Time.zone.parse('2017-03-12').to_date # Spring forward
Time.zone.parse("#{d1.strftime('%F')} #{t.strftime('%T')}")
#=> Sun, 06 Nov 2016 07:00:00 CST -06:00
Time.zone.parse("#{d2.strftime('%F')} #{t.strftime('%T')}")
#=> Sun, 07 Nov 2016 07:00:00 CST -06:00
Time.zone.parse("#{d3.strftime('%F')} #{t.strftime('%T')}")
#=> Sun, 12 Mar 2017 07:00:00 CDT -05:00
答案 3 :(得分:11)
如果使用Rails,请尝试以下任何一种方法:
d = Date.new(2014, 3, 1)
t = Time.parse("16:30")
dt = d + t.seconds_since_midnight.seconds
# => ActiveSupport::TimeWithZone
dt = (d + t.seconds_since_midnight.seconds).to_datetime
# => DateTime
dt = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec)
# => DateTime
答案 4 :(得分:1)
我发现了另一种方式,我希望这是正确的。
datetojoin=Time.parse(datetime).strftime("%Y-%m-%d")
timetojoin=Time.parse(time).strftime("%T")
joined_datetime = Time.parse(datetojoin +" "+ timetojoin).strftime("%F %T")
有什么想法?请分享。
答案 5 :(得分:0)
我一直都需要这个,我构建了一个方法来扩展DateTime类以组合日期和时间。 从日期开始占用区域,因此夏令时不会超过一小时。
另外,为方便起见,我也希望能够传入字符串。
class DateTime
def self.combine(d, t)
# pass in a date and time or strings
d = Date.parse(d) if d.is_a? String
t = Time.zone.parse(t) if t.is_a? String
# + 12 hours to make sure we are in the right zone
# (eg. PST and PDT switch at 2am)
zone = (Time.zone.parse(d.strftime("%Y-%m-%d")) + 12.hours ).zone
new(d.year, d.month, d.day, t.hour, t.min, t.sec, zone)
end
end
所以你可以这样做:
DateTime.combine(3.weeks.ago, "9am")
或
DateTime.combine("2015-3-26", Time.current)
等...