codememo

날짜 시간과 시간의 차이(Ruby)

tipmemo 2023. 6. 2. 20:32
반응형

날짜 시간과 시간의 차이(Ruby)

사이에 무슨 차이가 있습니까?DateTime그리고.Time루비의 수업들과 어떤 요소들이 내가 하나 혹은 다른 하나를 선택하게 만들 것인가요?

최신 버전의 Ruby(2.0+)는 두 클래스 간에 큰 차이가 없습니다.일부 라이브러리는 역사적인 이유로 둘 중 하나를 사용하지만 새 코드는 반드시 걱정할 필요가 없습니다.일관성을 위해 하나를 선택하는 것이 가장 좋습니다. 따라서 라이브러리가 기대하는 것과 일치하도록 노력하십시오.예를 들어, ActiveRecord는 DateTime을 선호합니다.

1 UTC 이후의 초됩니다. POSIX 표준 Ruby 1.9 이전서년에템일 POSIX 1970 인 1 비 UTC 후 32 부표값트는하호설명를초수의으됩이로시니다전위의얇은은과스버퍼래은간많시시비▁in▁a▁around년▁a월▁wrapper▁since부표값▁represent설▁describ일ix▁prior▁is▁on트▁32▁systems▁thin▁time는▁ruby▁value하-호명▁a다수▁versions▁manytime_t값이며, 경계가 지정됩니다.

Time.at(0x7FFFFFFF)
# => Mon Jan 18 22:14:07 -0500 2038
Time.at(-0x7FFFFFFF)
# => Fri Dec 13 15:45:53 -0500 1901

최신 버전의 Ruby는 오류 없이 더 큰 값을 처리할 수 있습니다.

DateTime은 연도, 월, 일, 시간, 분 및 초를 개별적으로 저장하는 달력 기반 접근 방식입니다.이것은 SQL 표준 DATTIME 필드 주변의 래퍼 역할을 하는 Ruby on Rails 구조입니다.여기에는 임의의 날짜가 포함되어 있으며 일반적으로 식의 범위가 매우 크기 때문에 거의 모든 시점을 나타낼 수 있습니다.

DateTime.new
# => Mon, 01 Jan -4712 00:00:00 +0000

따라서 데이트타임이 아리스토텔레스의 블로그 게시물을 처리할 수 있다는 것은 안심이 됩니다.

하나를 선택할 때, 그 차이는 이제 다소 주관적입니다.역사적으로 DateTime은 달력 방식으로 조작하기 위한 더 나은 옵션을 제공했지만, 이러한 방법 중 대부분은 적어도 레일즈 환경 내에서 Time으로 포팅되었습니다.

[2018년 7월 편집]

Ruby 2.5.1에서는 아래의 모든 것이 여전히 유효합니다.참조 설명서에서 다음을 수행합니다.

DateTime은 윤초를 고려하지 않으며 여름 시간 규칙을 추적하지 않습니다.

이전에 이 스레드에서 언급되지 않은 것은 다음과 같은 몇 가지 이점 중 하나입니다.DateTime그것은 달력 개혁을 알고 있는 반면에.Time다음이 아닙니다.

[…] Ruby's Time 클래스는 프롤레틱 그레고리력을 구현하며 달력 개혁에 대한 개념이 없습니다.

참조 문서는 사용할 권장 사항으로 끝납니다.Time가까운 과거, 현재 또는 미래의 날짜/시간을 독점적으로 다루고 사용하는 경우DateTime예를 들어, 셰익스피어의 생일을 정확하게 변환해야 할 때: (강조 추가)

그럼 루비에서 DateTime은 언제 사용해야 하고 Time은 언제 사용해야 합니까? 앱이 현재 날짜와 시간을 처리하고 있기 때문에 거의 틀림없이 시간을 사용하고 싶을 것입니다.그러나 날짜와 시간을 기록 컨텍스트에서 처리해야 하는 경우 DateTime […]을 사용할 수 있습니다.만약 여러분이 또한 표준 시간대를 다루어야 한다면, 운이 좋을 것입니다. 19세기가 되어서야 철도의 도입이 표준 시간대와 궁극적으로 표준 시간대의 필요성을 필요로 했기 때문에 여러분이 아마도 지역적인 태양 시간대를 다루게 될 것이라는 것을 명심하세요.

[/2018년 7월 편집]

루비 2.0 기준으로 다른 답변의 대부분 정보는 최신 정보가 아닙니다.

특히,Time이제 사실상 언바운드 상태입니다.Epoch에서 63비트 이상 또는 이하의 거리에 있을 수 있습니다.

irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> Time.at(2**62-1).utc # within Integer range
=> 146138514283-06-19 07:44:38 UTC
irb(main):003:0> Time.at(2**128).utc # outside of Integer range
=> 10783118943836478994022445751222-08-06 08:03:51 UTC
irb(main):004:0> Time.at(-2**128).utc # outside of Integer range
=> -10783118943836478994022445747283-05-28 15:55:44 UTC

의 유일한 은 성능보다 성능이 더 .Integer사용됩니다(s 사용다니됩는(vs). Bignum(s)를 값)Integer 범위) 또는Rational할 때 s(나노초를 추적할 때):

Ruby 1.9.2 이후 Time 구현에서는 서명된 63비트 정수 Bignum 또는 Rational을 사용합니다.정수는 1823-11-12 ~ 2116-02-20을 나타낼 수 있는 Epoch 이후의 나노초 수입니다.Bignum 또는 Rational을 사용하는 경우(1823년 이전, 2116년 이후, 나노초 미만), Time은 정수를 사용할 때보다 느리게 작동합니다.(http://www.ruby-doc.org/core-2.1.0/Time.html)

즉, 제가 이해하기로는 더 이상 보다 더 넓은 범위의 잠재적 가치를 다루지 않습니다.

또한, 이전에 언급되지 않은 두 가지 제한 사항.DateTime다음과 같이 주의해야 합니다.

DateTime은 leapse초를 고려하지 않으며 여름 시간 규칙을 추적하지 않습니다.(http://www.ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html#class-Date-label-DateTime)

첫째, 윤초 개념이 없습니다.

irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> require "date"
=> true
irb(main):003:0> t = Time.new(2012,6,30,23,59,60,0)
=> 2012-06-30 23:59:60 +0000
irb(main):004:0> dt = t.to_datetime; dt.to_s
=> "2012-06-30T23:59:59+00:00"
irb(main):005:0> t == dt.to_time
=> false
irb(main):006:0> t.to_i
=> 1341100824
irb(main):007:0> dt.to_time.to_i
=> 1341100823

위의 예를 사용하여 작업합니다.Time를 들어 OS 윤 초 를 지 시 올 설 게 합 야 니 해 다 정 르 바 를 정 보 는 대 간 준 표 원 하 해 야 며 ▁the 예:TZ=right/UTC irb(많은 유닉스 시스템에서).

둘째, 시간대에 대한 이해가 매우 제한적이며 특히 일광 절약에 대한 개념이 없습니다.시간대를 간단한 UTC + X 오프셋으로 처리합니다.

irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> require "date"
=> true
irb(main):003:0> t = Time.local(2012,7,1)
=> 2012-07-01 00:00:00 +0200
irb(main):004:0> t.zone
=> "CEST"
irb(main):005:0> t.dst?
=> true
irb(main):006:0> dt = t.to_datetime; dt.to_s
=> "2012-07-01T00:00:00+02:00"
irb(main):007:0> dt.zone
=> "+02:00"
irb(main):008:0> dt.dst?
NoMethodError: undefined method `dst?' for #<DateTime:0x007f34ea6c3cb8>

이는 시간을 DST로 입력한 다음 외부에서 올바른 오프셋을 추적하지 않고 비 DST 시간대로 변환할 때 문제를 일으킬 수 있습니다.DateTime(많은 운영 체제에서 이미 이 문제를 해결하고 있습니다.)

전체적으로 요즘은.Time대부분의 애플리케이션에 적합합니다.

또한 추가에 대한 중요한 차이점에 유의하십시오. 시간 개체에 숫자를 추가하면 초 단위로 계산되지만 DateTime에 숫자를 추가하면 일 단위로 계산됩니다.

저는 "무엇이 다른가"에 대한 대답이 루비 표준 도서관에서 이 질문에 대한 불행한 공통된 대답 중 하나라고 생각합니다. 두 클래스/리브는 서로 다른 시기에 서로 다른 사람들에 의해 다르게 만들어졌습니다.그것은 자바와 같은 것의 신중하게 계획된 개발에 비해 루비의 진화의 공동체적 특성의 불행한 결과 중 하나입니다.개발자들은 새로운 기능을 원하지만 기존 API를 밟지 않기 때문에 새로운 클래스를 만들기만 하면 됩니다. 최종 사용자에게는 이 둘이 존재할 명확한 이유가 없습니다.

이는 일반적으로 소프트웨어 라이브러리에 해당합니다. 종종 일부 코드나 API가 논리적이기보다는 과거의 것으로 판명되는 방식 때문입니다.

DateTime이 더 일반적으로 보이기 때문에 시작하는 것이 좋습니다.날짜...그리고 시간, 맞지요?틀렸습니다. 시간도 날짜를 더 잘 잡아줍니다. 그리고 사실 DateTime이 할 수 없는 시간대를 구문 분석할 수 있습니다.또한 성능이 더 좋습니다.

저는 결국 모든 곳에서 시간을 사용하게 되었습니다.

하지만 안전을 위해 DateTime 인수를 Timey API로 전달하고 변환하는 것을 허용하는 경향이 있습니다.또한 두 가지 모두 시간을 XML로 변환하기 위해 작성한 이 방법(XMLTV 파일용)과 같이 내가 관심 있는 방법을 가지고 있다는 것을 알고 있다면 둘 중 하나를 수락합니다.

# Will take a date time as a string or as a Time or DateTime object and
# format it appropriately for xmtlv. 
# For example, the 22nd of August, 2006 at 20 past midnight in the British Summertime
# timezone (i.e. GMT plus one hour for DST) gives: "20060822002000 +0100"
def self.format_date_time(date_time)
  if (date_time.respond_to?(:rfc822)) then
    return format_time(date_time)
  else 
    time = Time.parse(date_time.to_s)
    return format_time(time)
  end    
end

# Note must use a Time, not a String, nor a DateTime, nor Date.
# see format_date_time for the more general version
def self.format_time(time)
  # The timezone feature of DateTime doesn't work with parsed times for some reason
  # and the timezone of Time is verbose like "GMT Daylight Saving Time", so the only
  # way I've discovered of getting the timezone in the form "+0100" is to use 
  # Time.rfc822 and look at the last five chars
  return "#{time.strftime( '%Y%m%d%H%M%S' )} #{time.rfc822[-5..-1]}"
end

ActiveSupport 확장을 사용한다고 가정할 때 DateTime을 사용하면 다양한 시간대에서 하루의 시작/종료를 분석하고 계산하는 것이 더 쉽다는 것을 알게 되었습니다.

저의 경우 문자열로 받은 사용자의 현지 시간을 기준으로 사용자의 시간대(임의)에서 하루의 끝을 계산해야 했습니다(예: "2012-10-10 10:10 +0300").

DateTime을 사용하면 다음과 같이 간단합니다.

irb(main):034:0> DateTime.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 +0300
# it preserved the timezone +0300

이제 시간과 동일한 방법으로 시도해 보겠습니다.

irb(main):035:0> Time.parse('2012-10-10 10:10 +0300').end_of_day
=> 2012-10-10 23:59:59 +0000
# the timezone got changed to the server's default UTC (+0000), 
# which is not what we want to see here.

은 구문 분석하기 . 사실, 시은구분기전합알니다시아를입니다.Time.zone.parse,것은 아니다.Time.parse):

irb(main):044:0> Time.zone = 'EET'
=> "EET"
irb(main):045:0> Time.zone.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 EEST +03:00

따라서 이 경우 DateTime을 사용하는 것이 확실히 더 쉽습니다.

사용자 지정 인스턴스를 사용하여 시간대를 다르게 처리하는 방법을 고려합니다.

irb(main):001:0> Time.new(2016,9,1)
=> 2016-09-01 00:00:00 -0400
irb(main):002:0> DateTime.new(2016,9,1)
=> Thu, 01 Sep 2016 00:00:00 +0000
irb(main):003:0> Time.new(2016,9,1).to_i
=> 1472702400
irb(main):004:0> DateTime.new(2016,9,1).to_i
=> 1472688000

이것은 시간 범위 등을 만들 때 까다로울 수 있습니다.

닐스 간저의 답변 외에도 다음과 같은 주장을 고려할 수 있습니다.

Ruby Style Guide에는 이에 대한 입장이 매우 명확하게 나와 있습니다.

날짜 시간 없음

일정관리 내역 변경을 고려해야 하는 경우를 제외하고 DateTime을 사용하지 마십시오. 변경한 경우 시작 인수를 명시적으로 지정하여 의도를 명확하게 설명하십시오.

# bad - uses DateTime for current time
DateTime.now

# good - uses Time for current time
Time.now

# bad - uses DateTime for modern date
DateTime.iso8601('2016-06-29')

# good - uses Date for modern date
Date.iso8601('2016-06-29')

# good - uses DateTime with start argument for historical date
DateTime.iso8601('1751-04-23', Date::ENGLAND)

경우에 따라 동작이 매우 다른 것 같습니다.

Time.parse("Ends from 28 Jun 2018 12:00 BST").utc.to_s

"2018-06-280 09:00 UTC"

Date.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s

"2018-06-27 21:00 UTC"

DateTime.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s

"2018-06-28 11:00 UTC"

언급URL : https://stackoverflow.com/questions/1261329/difference-between-datetime-and-time-in-ruby

반응형