Convert Unix Timestamp in Ruby
Ruby's Time class makes Unix timestamp conversion straightforward: use Time.now.to_i for "now in seconds" and Time.at() to build a time from an epoch value.
Get Current Unix Timestamp
# Seconds since epoch (integer) Time.now.to_i # With sub-second precision Time.now.to_f # seconds as float (e.g., 1704067200.123) Time.now.to_r # seconds as rational (exact) # Common helpers for milliseconds (Time.now.to_f * 1000).to_i ((Time.now.to_r * 1000).to_i) # avoids float rounding
Unix Timestamp to Time (Time.at)
timestamp = 1704067200 t = Time.at(timestamp) puts t # local time (depends on server timezone) puts t.utc # 2024-01-01 00:00:00 UTC # From milliseconds (13 digits) timestamp_ms = 1704067200000 puts Time.at(timestamp_ms / 1000.0).utc # Sub-second precision puts Time.at(1704067200.123).utc # Seconds + microseconds (Ruby 2.6+ supports the unit argument) puts Time.at(1704067200, 123_456, :usec).utc
Time to Unix Timestamp
t = Time.utc(2024, 1, 1, 0, 0, 0) puts t.to_i # 1704067200 (seconds) puts t.to_f # 1704067200.0 (float seconds) puts (t.to_f * 1000).to_i # 1704067200000 (milliseconds)
DateTime Class Usage
Ruby's DateTime lives in the standard date library. It can parse and format epoch seconds using %s.
require "date"
timestamp = 1704067200
# Unix timestamp -> DateTime (UTC)
dt = DateTime.strptime(timestamp.to_s, "%s")
puts dt.iso8601 # 2024-01-01T00:00:00+00:00
# DateTime -> Unix timestamp
dt2 = DateTime.new(2024, 1, 1, 0, 0, 0, "+00:00")
puts dt2.strftime("%s") # "1704067200"
puts dt2.to_time.to_i # 1704067200ActiveSupport (Rails) Time Helpers
In Rails, prefer Time.current and Time.zone for timezone-aware values (they respect config.time_zone).
# Current time (zone-aware) Time.current.to_i timestamp = 1704067200 # Unix timestamp -> ActiveSupport::TimeWithZone Time.zone.at(timestamp) # interpreted as UTC instant, represented in Time.zone Time.zone.at(timestamp).utc # keep the instant, show in UTC # If you have milliseconds timestamp_ms = 1704067200000 Time.zone.at(timestamp_ms / 1000.0) # Duration helpers (ActiveSupport) 5.minutes.ago 2.hours.from_now
Timezone Handling
timestamp = 1704067200
t = Time.at(timestamp)
# UTC
puts t.utc
# System local timezone
puts t.getlocal
# Fixed offset (no DST rules)
puts t.getlocal("+05:30")
# Change process timezone (affects Time.now / formatting)
ENV["TZ"] = "UTC"
puts Time.at(timestamp)
ENV.delete("TZ")Time.use_zone("America/New_York") do
t = Time.zone.at(1704067200)
puts t # 2023-12-31 19:00:00 -0500
puts t.utc # 2024-01-01 00:00:00 UTC
endCommon Pitfalls
Seconds vs Milliseconds
Ruby's Time.at expects seconds. If you pass milliseconds, you'll end up thousands of years in the future.
# ❌ Wrong - 13-digit milliseconds treated as seconds Time.at(1704067200000).utc # ✅ Correct - convert milliseconds to seconds Time.at(1704067200000 / 1000.0).utc
Implicit Local Time
Time.at(...) without utc/getlocal prints using the system timezone, which can differ between dev, CI, and production.
t = Time.at(1704067200)
# ✅ Prefer explicit
t.utc
t.getlocal("+00:00")Float Rounding
If you need exact millisecond math, prefer rationals (to_r) over floats (to_f).
Edge Cases
# Negative timestamps (before 1970) puts Time.at(-86400).utc # 1969-12-31 00:00:00 UTC # Very large timestamps may be platform dependent on 32-bit systems # (Year 2038 problem). Prefer 64-bit runtimes.
Frequently Asked Questions
Does Ruby use seconds or milliseconds for Unix timestamps?
Ruby uses seconds. If you have a 13-digit timestamp (milliseconds), divide by 1000 (use a float if you need sub-second precision).
What is the difference between Time and DateTime in Ruby?
Time is backed by the system time library and is usually faster and better for Unix timestamps. DateTime (from the date library) is more general for calendar math and can represent a wider range, but it's often slower.
How do I convert a Unix timestamp to a specific timezone?
With plain Ruby, use Time.at(ts).utc, Time.at(ts).getlocal, or getlocal("+05:30"). For IANA zones like "America/New_York", use Rails/ActiveSupport (Time.use_zone / Time.zone.at) or the tzinfo gem.
Why does the same timestamp show a different date on different machines?
The timestamp is absolute, but formatting defaults to the local system timezone. Convert to UTC (utc) or explicitly set the target timezone before formatting.