Làm thế nào để lấy thời gian hiện tại dưới dạng số nguyên 13 chữ số trong Ruby?


88

Tôi có jQueryhàm này trả về thời gian hiện tại dưới dạng số mili giây kể từ kỷ nguyên (ngày 1 tháng 1 năm 1970):

time = new Date().getTime();

Có cách nào để làm điều tương tự trong Ruby không?

Hiện tại, tôi đang sử dụng Ruby's Time.now.to_ihoạt động tốt nhưng trả về một số nguyên 10 chữ số (số giây)

Làm cách nào để tôi có thể làm cho nó hiển thị số mili giây, như trong jQuery?


5
Đó không phải là "hàm jQuery", nó chỉ đơn giản là ECMAScript (javascript). Có lẽ đó là những gì đã thúc đẩy -1, mặc dù hơi khắc nghiệt.
RobG

Câu trả lời:


151
require 'date'

p DateTime.now.strftime('%s') # "1384526946" (seconds)
p DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)

31
Lưu ý đối với người dùng Rails: strftimephương thức được cung cấp bởi ActiveSupport::TimeWithZonekhông bao gồm các chỉ định %s%Q. Bạn sẽ cần phải chuyển đổi sang một Ruby đơn giản DateTimeđầu tiên, bằng cách sử dụng to_datetimephương pháp.
Lonnon Foster

6
@LonnonFoster Bây giờ nó đã hoạt động (vừa được thử nghiệm trong bảng điều khiển Rails).
Nikola Stojaković

Xin chào, làm cách nào tôi có thể làm điều tương tự, nhưng không phải bây giờ, mà là từ trường ngày tháng?
Tomer


101

Javascript gettime()trả về số mili giây kể từ kỷ nguyên.

Ruby Time.now.to_isẽ cung cấp cho bạn số giây kể từ kỷ nguyên. Nếu bạn thay đổi điều đó thành Time.now.to_f, bạn vẫn nhận được giây nhưng với một thành phần phân số. Chỉ cần nhân nó với 1.000 và bạn có mili giây. Sau đó, sử dụng #to_iđể chuyển nó thành một số nguyên. Và bạn kết thúc với:

(Time.now.to_f * 1000).to_i

Cảm ơn rất nhiều cho lời giải thích! Vẫn còn mới đến toàn bộ sự việc này ... Do không biết được câu trả lời cho dấu là điều đúng thực sự ...
Tintin81

1
Chỉ để biết thêm thông tin, Time.nowđến từ Ruby vì Time.currentđến từ Rails. Do đó, Time.currentđược thừa nhận bởi múi giờ ứng dụng Rails và Time.nowđang sử dụng múi giờ máy chủ. Theo kinh nghiệm của tôi, luôn luôn sử dụng Time.currenttrên ứng dụng Rails của bạn cho phù hợp múi giờ
vutran

1
Không, bạn hoàn toàn không nên sử dụng Time.currentở đây, sẽ mất nhiều thời gian hơn để xây dựng và vì bạn đang ngay lập tức chuyển đổi nó thành dấu thời gian unix, bạn hoàn toàn không quan tâm đến tính nhất quán của múi giờ. (Dấu thời gian Unix luôn liên quan đến UTC). Vì vậy, trong khi những gì bạn đang nói là đúng trong 99% trường hợp, thì hiệu suất khôn ngoan này rơi vào 1% cuối cùng.
The Pellmeister

1
Đây là cách tiếp cận ưa thích của tôi. Một điều tôi muốn làm là tăng cường lớp Thời gian để thêm một :epochphương thức: class Time def epoch (self.to_f * 1000) .to_i end end
Matt Welke

1
này hàng giả các mili giây
brauliobo

31

(Time.now.to_f * 1000).to_i nên làm điều tương tự.


1
@brauliobo mili giây giả là gì?
Erik Rothoff

1
@brauliobo Nó không, vì to_fbao gồm mili giây dưới dạng số thập phân.
CashIsClay

20

Bằng cách sử dụng strftime, bạn có thể nhận được số giây và thêm phần mili giây (hoặc các đơn vị nhỏ hơn, nếu cần):

2.2.2 :001 > t = Time.new
 => 2015-06-02 12:16:56 -0700 
2.2.2 :002 > t.strftime('%s%3N')
 => "1433272616888" 

Xin lưu ý rằng điều này không làm tròn, nó sẽ bị cắt bớt, như bạn có thể thấy với to_fhoặc nếu bạn đi ra ngoài đến micro giây:

2.2.2 :003 > t.to_f
 => 1433272616.888615
2.2.2 :004 > t.usec
 => 888615 

to_f/ to_igiải pháp có cùng một vấn đề:

2.2.2 :009 > (t.to_f * 1000).to_i
 => 1433272616888

vì vậy nếu bạn thực sự quan tâm đến độ chính xác mili giây, bạn có thể đặt cược tốt hơn to_fvới round:

2.2.2 :010 > (t.to_f * 1000).round
 => 1433272616889

Điều đó nói rằng, như đã lưu ý trong tài liệu , "IEEE 754 double không đủ chính xác để đại diện cho số nano giây kể từ Kỷ nguyên", vì vậy nếu bạn thực sự quan tâm, hãy xem xét to_rthay vì to_f-

2.2.2 :011 > (t.to_r * 1000).round
 => 1433272616889 

- mặc dù nếu bạn chỉ làm tròn đến mili giây thì có lẽ bạn vẫn ổn.


18

Hãy cẩn thận, đừng nhầm lẫn. Thực tế là Ruby ủng hộ ý tưởng về giây phân số như một số thực không thực sự khiến nó trở thành một số dấu phẩy động. Tôi đã gặp rắc rối với điều này khi tôi thực hiện so sánh thời gian dấu thời gian Wireshark bằng Python ... các phép tính thời gian trong pcap-ng không hoạt động. Chỉ khi tôi xử lý hai phần (giây tích phân và nano giây tích phân) là cả hai số nguyên thì tôi mới có thể nhận được số thích hợp.

Đó là bởi vì số dấu phẩy động có vấn đề về Độ chính xác . Thật vậy, một chút về Ruby sẽ cho bạn thấy rằng to_f không bằng, ví dụ, nsec:

irb(main):019:0> t=Time.now
=> 2015-04-10 16:41:35 -0500
irb(main):020:0> puts "#{t.to_f}; #{t.nsec}"
1428702095.1435847; 143584844

Lập trình viên báo trước. Bạn có thể an toàn với 3 chữ số có nghĩa, nhưng thực tế vẫn là: Số dấu phẩy động trên máy tính là số gần đúng. Các bộ đếm nano giây trên máy tính hiện đại là các số nguyên.


Các phản ứng tốt hơn. Cảm ơn bạn. Định dạng chỉ thị .strftime("%9N")cũng có thể được sử dụng. ruby-doc.org/core-2.3.1/Time.html#method-i-strftime
rplaurindo

13

Lấy đối tượng Thời gian với Time.now, việc gọi #to_itrả về một dấu thời gian Unix (giây từ kỷ nguyên). #to_fcung cấp giây phân số mà bạn có thể sử dụng để lấy mili giây từ kỷ nguyên:

Time.now.to_f * 1000

3
này hàng giả các mili giây
brauliobo

0

Số nguyên typecast (1e6 * Time.now.to_f) trả về một Bignum có thể chứa mili giây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.