programing

Ruby에서 DateTime 및 Time으로 변환

telebox 2023. 6. 1. 22:41
반응형

Ruby에서 DateTime 및 Time으로 변환

루비에서 DateTime과 Time 객체를 어떻게 변환합니까?

require 'time'
require 'date'

t = Time.now
d = DateTime.now

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

루비 생태계의 최신 정보로서,Date,DateTime그리고.Time이제 다양한 클래스 간에 변환할 수 있는 메서드가 있습니다.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)
=> #<Date: 2000-01-01 (4903089/2,0,2299161)>
[5] pry(main)> ds.to_date
=> #<Date: 2000-01-01 (4903089/2,0,2299161)>
[6] pry(main)> ds.to_datetime
=> #<DateTime: 2000-01-01T00:00:00+00:00 (4903089/2,0,2299161)>
[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
=> #<Date: 2000-01-01 (4903089/2,0,2299161)>
[13] pry(main)> ts.to_date.class
=> Date
[14] pry(main)> ts.to_datetime
=> #<DateTime: 2000-01-01T12:01:01-07:00 (211813513261/86400,-7/24,2299161)>
[15] pry(main)> ts.to_datetime.class
=> DateTime

약간 다른 두 가지 변환이 필요합니다.

변환 대상 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

날짜와 유사하게 조정하면 변환할 수 있습니다. 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 시간 중에서 선택해야 합니다.

위의 코드 스니펫은 모두 오라일리의 루비 쿡북에서 가져온 것입니다.그들의 코드 재사용 정책은 이것을 허용합니다.

불행하게도, 그DateTime.to_time, Time.to_datetime그리고.Time.parse함수는 시간대 정보를 유지하지 않습니다.변환하는 동안 모든 항목이 로컬 표준 시간대로 변환됩니다.날짜 산술은 계속 작동하지만 원래 시간대로 날짜를 표시할 수 없습니다.이러한 상황 정보는 종종 중요합니다.예를 들어, 뉴욕에서 업무 시간에 수행되는 트랜잭션을 보려면 트랜잭션이 호주 현지 시간대(뉴욕보다 12시간 빠른 시간대)가 아닌 원래 시간대로 표시되는 것을 선호합니다.

아래의 변환 방법은 해당 tz 정보를 유지합니다.

Ruby 1.8의 경우 Gordon Wilson의 답변을 보십시오.믿을 수 있는 오래된 루비 쿡북에서 나온 거예요.

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

표준 시간대를 포함한 전체 원본 DateTime 정보가 유지됩니다.

Gordon Wilson 솔루션을 개선하기 위해 시도해 본 내용은 다음과 같습니다.

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

UTC에서도 동일한 시간을 얻을 수 있으며, 시간대가 손실됩니다(불행히도).

또한, 루비 1.9가 있다면, 그냥 사용해보세요.to_time방법

이러한 변환을 수행하는 동안 한 개체에서 다른 개체로 변환하는 동안 시간대의 동작을 고려해야 합니다.저는 이 스택 오버플로 게시물에서 몇 가지 좋은 노트와 예시를 발견했습니다.

사용할 수 있습니다.to_date,예.

> Event.last.starts_at
=> Wed, 13 Jan 2021 16:49:36.292979000 CET +01:00
> Event.last.starts_at.to_date
=> Wed, 13 Jan 2021

언급URL : https://stackoverflow.com/questions/279769/convert-to-from-datetime-and-time-in-ruby

반응형