[ruby] 유닉스 타임 스탬프 (epoch 이후 초)를 Ruby DateTime으로 변환하는 방법은 무엇입니까?

유닉스 타임 스탬프 (에포크 이후 초)를 Ruby DateTime으로 어떻게 변환합니까?



답변

DateTime.strptime에포크 이후 초를 처리 할 수 ​​있습니다. 숫자는 문자열로 변환되어야합니다.

require 'date'
DateTime.strptime("1318996912",'%s')


답변

죄송합니다. 짧은 시냅스 장애 순간입니다. 실제 답변은 다음과 같습니다.

require 'date'

Time.at(seconds_since_epoch_integer).to_datetime

간단한 예 (현재 시스템 시간대를 고려함) :

$ date +%s
1318996912

$ irb

ruby-1.9.2-p180 :001 > require 'date'
 => true

ruby-1.9.2-p180 :002 > Time.at(1318996912).to_datetime
 => #<DateTime: 2011-10-18T23:01:52-05:00 (13261609807/5400,-5/24,2299161)> 

추가 업데이트 (UTC의 경우) :

ruby-1.9.2-p180 :003 > Time.at(1318996912).utc.to_datetime
 => #<DateTime: 2011-10-19T04:01:52+00:00 (13261609807/5400,0/1,2299161)>

최근 업데이트 : 일주일 또는 이틀 전에 HA 서비스를 작업 하면서이 스레드에서 최고의 솔루션을 벤치마킹했으며 Time.at(..)성능 이 뛰어남 DateTime.strptime(..)(업데이트 : 더 많은 벤치 마크 추가) 에 놀랐습니다 .

# ~ % ruby -v
#  => ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin13.0]

irb(main):038:0> Benchmark.measure do
irb(main):039:1*   ["1318996912", "1318496912"].each do |s|
irb(main):040:2*     DateTime.strptime(s, '%s')
irb(main):041:2>   end
irb(main):042:1> end

=> #<Benchmark ... @real=2.9e-05 ... @total=0.0>

irb(main):044:0> Benchmark.measure do
irb(main):045:1>   [1318996912, 1318496912].each do |i|
irb(main):046:2>     DateTime.strptime(i.to_s, '%s')
irb(main):047:2>   end
irb(main):048:1> end

=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>

irb(main):050:0* Benchmark.measure do
irb(main):051:1*   ["1318996912", "1318496912"].each do |s|
irb(main):052:2*     Time.at(s.to_i).to_datetime
irb(main):053:2>   end
irb(main):054:1> end

=> #<Benchmark ... @real=1.5e-05 ... @total=0.0>

irb(main):056:0* Benchmark.measure do
irb(main):057:1*   [1318996912, 1318496912].each do |i|
irb(main):058:2*     Time.at(i).to_datetime
irb(main):059:2>   end
irb(main):060:1> end

=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>


답변

시간대 처리

미래의 사람들 이이 중요한 차이점을 놓치지 않도록 주석을 달았지만 명확히하고 싶습니다.

DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000

UTC로 반환 값을 표시하고 초는 String이어야하고 UTC Time 객체를 출력합니다.

Time.at(1318996912) # => 2011-10-19 00:01:52 -0400

LOCAL 표준 시간대에 반환 값을 표시하며 일반적으로 FixNum 인수가 필요하지만 표시가 아닌 경우에도 Time 개체 자체는 여전히 UTC입니다.

따라서 두 정수에 동일한 정수를 전달했지만 클래스의 방법으로 인해 두 가지 다른 결과가 나타납니다. #to_s 메소드 작동 방식으로 가 나타납니다. 그러나 @Eero는 나에게 두 번 상기시켜야했습니다.

Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true

두 반환 값 사이의 동등 비교는 여전히 true를 반환합니다. 다시 말하지만 이는 기본적으로 값이 동일하기 때문입니다 (다른 클래스에도 불구하고#== 메소드가이를 처리하지만) #to_s메소드는 크게 다른 문자열을 인쇄합니다. 문자열을 보면 실제로 다른 시간대에 인쇄 된 문자열이 실제로 같은 시간임을 알 수 있습니다.

메소드 인수 설명

문서는 또한 “숫자 인수가 주어지면 결과는 현지 시간입니다”라고 말합니다. 이것은 말이되지만 문서에 정수가 아닌 인수의 예를 제공하지 않기 때문에 약간 혼란 스럽습니다. 따라서 정수가 아닌 인수 예제의 경우 :

Time.at("1318996912")
TypeError: can't convert String into an exact number

String 인수를 사용할 수 없지만 Time 인수를 사용할 수 Time.at있으며 인수의 시간대에 결과를 반환합니다.

Time.at(Time.new(2007,11,1,15,25,0, "+09:00"))
=> 2007-11-01 15:25:00 +0900

벤치 마크

그의 답변에 대한 @AdamEberlin과의 토론 후, 나는 모든 것을 가능한 동일하게 만들기 위해 약간 변경된 벤치 마크를 게시하기로 결정했습니다. 또한, 나는 이것을 다시 구축하고 싶지 않으므로 이것을 저장하기에 좋은 곳입니다.

Time.at (int) .to_datetime ~ 2.8x 빠름

09:10:58-watsw018:~$ ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
09:11:00-watsw018:~$ irb
irb(main):001:0> require 'benchmark'
=> true
irb(main):002:0> require 'date'
=> true
irb(main):003:0>
irb(main):004:0* format = '%s'
=> "%s"
irb(main):005:0> times = ['1318996912', '1318496913']
=> ["1318996912", "1318496913"]
irb(main):006:0> int_times = times.map(&:to_i)
=> [1318996912, 1318496913]
irb(main):007:0>
irb(main):008:0* datetime_from_strptime = DateTime.strptime(times.first, format)
=> #<DateTime: 2011-10-19T04:01:52+00:00 ((2455854j,14512s,0n),+0s,2299161j)>
irb(main):009:0> datetime_from_time = Time.at(int_times.first).to_datetime
=> #<DateTime: 2011-10-19T00:01:52-04:00 ((2455854j,14512s,0n),-14400s,2299161j)>
irb(main):010:0>
irb(main):011:0* datetime_from_strptime === datetime_from_time
=> true
irb(main):012:0>
irb(main):013:0* Benchmark.measure do
irb(main):014:1*   100_000.times {
irb(main):015:2*     times.each do |i|
irb(main):016:3*       DateTime.strptime(i, format)
irb(main):017:3>     end
irb(main):018:2>   }
irb(main):019:1> end
=> #<Benchmark::Tms:0x00007fbdc18f0d28 @label="", @real=0.8680500000045868, @cstime=0.0, @cutime=0.0, @stime=0.009999999999999998, @utime=0.86, @total=0.87>
irb(main):020:0>
irb(main):021:0* Benchmark.measure do
irb(main):022:1*   100_000.times {
irb(main):023:2*     int_times.each do |i|
irb(main):024:3*       Time.at(i).to_datetime
irb(main):025:3>     end
irb(main):026:2>   }
irb(main):027:1> end
=> #<Benchmark::Tms:0x00007fbdc3108be0 @label="", @real=0.33059399999910966, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=0.32000000000000006, @total=0.32000000000000006>

**** 모든면에서 완전하고 완전하게 부정확하지 않도록 편집 ****

**** 추가 된 벤치 마크 ****


답변

날짜 시간을 Unix 형식으로 변환 한 다음 문자열로 변환하는 하나의 명령

    DateTime.strptime(Time.now.utc.to_i.to_s,'%s').strftime("%d %m %y")

    Time.now.utc.to_i #Converts time from Unix format
    DateTime.strptime(Time.now.utc.to_i.to_s,'%s') #Converts date and time from unix format to DateTime

마지막으로 strftime은 날짜 형식을 지정하는 데 사용됩니다

예:

    irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y")
    "10 09 14"


답변

이것은 코드를 실행하는 순간부터 미래의 초 수를 나타냅니다.

time = Time.new + 1000000000 #date in 1 billion seconds

풋 (시간)

현재 시간에 따라 인쇄 된 질문에 답하고 있습니다 047-05-14 05:16:16 +0000(앞으로 10 억 초)

또는 특정 시간에서 수십억 초를 세고 싶다면 형식입니다. Time.mktime(year, month,date,hours,minutes)

time = Time.mktime(1987,8,18,6,45) + 1000000000

puts ( “10 억 초가되었습니다 :”+ 시간)


답변

당신은 단지 날짜를 원한다면, 당신은 할 수있는 Date.strptime(invoice.date.to_s, '%s')invoice.date의 형태로 제공 Fixnum한 후 변환 String.


답변