当前位置:  开发笔记 > 编程语言 > 正文

在Ruby中转换为DateTime和Time

如何解决《在Ruby中转换为DateTime和Time》经验,为你挑选了4个好方法。

如何在Ruby中的DateTime和Time对象之间进行转换?



1> anshul..:
require 'time'
require 'date'

t = Time.now
d = DateTime.now

dd = DateTime.parse(t.to_s)
tt = Time.parse(d.to_s)


+1这可能不是最有效的执行,但它有效,它简洁,而且非常易读.
不幸的是,这只适用于处理当地时间.如果以具有不同时区的DateTime或Time开头,则解析功能将转换为本地时区.你基本上失去了原来的时区.
从ruby 1.9.1开始,DateTime.parse确实保留了时区.(我无法访问早期版本.)Time.parse不保留时区,因为它代表POSIX标准time_t,我相信它是与epoch的整数差异.任何到时间的转换都应该具有相同的行为.

2> the Tin Man..:

作为一个更新的Ruby生态系统的状态Date,DateTimeTime现在有方法的各种类之间的转换.使用Ruby 1.9.2+:

pry
[1] pry(main)> ts = 'Jan 1, 2000 12:01:01'
=> "Jan 1, 2000 12:01:01"
[2] pry(main)> require 'time'
=> true
[3] pry(main)> require 'date'
=> true
[4] pry(main)> ds = Date.parse(ts)
=> #
[5] pry(main)> ds.to_date
=> #
[6] pry(main)> ds.to_datetime
=> #
[7] pry(main)> ds.to_time
=> 2000-01-01 00:00:00 -0700
[8] pry(main)> ds.to_time.class
=> Time
[9] pry(main)> ds.to_datetime.class
=> DateTime
[10] pry(main)> ts = Time.parse(ts)
=> 2000-01-01 12:01:01 -0700
[11] pry(main)> ts.class
=> Time
[12] pry(main)> ts.to_date
=> #
[13] pry(main)> ts.to_date.class
=> Date
[14] pry(main)> ts.to_datetime
=> #
[15] pry(main)> ts.to_datetime.class
=> DateTime



3> Gordon Wilso..:

您需要两次稍有不同的转换.

要转换 Time DateTime您可以修改Time类,如下所示:

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

请注意,您必须在本地时间和GM/UTC时间之间进行选择.

以上代码片段均取自O'Reilly的Ruby Cookbook.他们的代码重用策略允许这样.


这将在1.9中断,其中DateTime#sec_fraction返回一秒钟内的毫秒数.对于1.9,您要使用:usec = dest.sec_fraction*10**6

4> Bernard..:

不幸的是,DateTime.to_time, Time.to_datetimeTime.parse函数不保留时区信息.转换期间,所有内容都会转换为本地时区.日期算术仍然有效,但您将无法使用原始时区显示日期.上下文信息通常很重要.例如,如果我想看到在纽约工作时间执行的交易,我可能更愿意看到它们显示在原始时区,而不是我在澳大利亚的当地时区(比纽约提前12小时).

下面的转换方法确实保留了tz信息.

对于Ruby 1.8,请看Gordon Wilson的答案.这是来自古老可靠的Ruby Cookbook.

对于Ruby 1.9,它稍微容易一些.

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

这将打印以下内容

2010-01-01T10:00:00-02:00
2010-01-01 10:00:00 -0200
2010-01-01T10:00:00-02:00

保留包含时区的完整原始日期时间信息.


哇,这很糟糕..为什么处理时间这么难啊!!
时间很复杂,但没有理由不在不同的内置时间类之间提供内置转换.如果你试图获得公元前4713年的UNIX time_t,你可以抛出一个RangeException(虽然BigNum负值会更好),但至少为它提供一个方法.
推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有