require 'date'
class Time
def to_datetime
# Convert seconds + microseconds into a fractional number of seconds
seconds = sec + Rational(usec, 10**6)
# Convert a UTC offset measured in minutes to one measured in a
# fraction of a day.
offset = Rational(utc_offset, 60 * 60 * 24)
DateTime.new(year, month, day, hour, min, seconds, offset)
end
end
对Date的类似调整将允许您将 DateTime 转换为 Time .
class Date
def to_gm_time
to_time(new_offset, :gm)
end
def to_local_time
to_time(new_offset(DateTime.now.offset-offset), :local)
end
private
def to_time(dest, method)
#Convert a fraction of a day to a number of microseconds
usec = (dest.sec_fraction * 60 * 60 * 24 * (10**6)).to_i
Time.send(method, dest.year, dest.month, dest.day, dest.hour, dest.min,
dest.sec, usec)
end
end
require 'date'
# Create a date in some foreign time zone (middle of the Atlantic)
d = DateTime.new(2010,01,01, 10,00,00, Rational(-2, 24))
puts d
# Convert DateTime to Time, keeping the original timezone
t = Time.new(d.year, d.month, d.day, d.hour, d.min, d.sec, d.zone)
puts t
# Convert Time to DateTime, keeping the original timezone
d = DateTime.new(t.year, t.month, t.day, t.hour, t.min, t.sec, Rational(t.gmt_offset / 3600, 24))
puts d
def to_time
#Convert a fraction of a day to a number of microseconds
usec = (sec_fraction * 60 * 60 * 24 * (10**6)).to_i
t = Time.gm(year, month, day, hour, min, sec, usec)
t - offset.abs.div(SECONDS_IN_DAY)
end
5 回答
您需要两次稍有不同的转换 .
要将
Time
转换为DateTime
,您可以按如下方式修改Time类:对Date的类似调整将允许您将
DateTime
转换为Time
.请注意,您必须在本地时间和GM / UTC时间之间进行选择 .
以上代码片段均取自O 'Reilly' s Ruby Cookbook . 他们的代码重用policy允许这样做 .
作为Ruby生态系统状态的更新,
Date
,DateTime
和Time
现在具有在各种类之间进行转换的方法 . 使用Ruby 1.9.2:遗憾的是,
DateTime.to_time, Time.to_datetime
和Time.parse
函数无法显示具有原始时区的日期 . 上下文信息通常很重要 . 例如,如果我想看到在纽约工作时间执行的交易,我可能更愿意看到它们显示在原始时区,而不是我在澳大利亚的当地时区(比纽约提前12小时) .下面的转换方法确实保留了tz信息 .
对于Ruby 1.8,请查看Gordon Wilson's answer . 这是来自古老可靠的Ruby Cookbook .
对于Ruby 1.9,它稍微容易一些 .
这将打印以下内容
保留包含时区的完整原始日期时间信息 .
改进Gordon Wilson解决方案,这是我的尝试:
您将在UTC中获得相同的时间,丢失时区(不幸的是)
此外,如果你有ruby 1.9,只需尝试
to_time
方法