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

Ruby
# 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)

Ruby
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

Ruby
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.

Ruby
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       # 1704067200

ActiveSupport (Rails) Time Helpers

In Rails, prefer Time.current and Time.zone for timezone-aware values (they respect config.time_zone).

Rails
# 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

Plain Ruby
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")
Rails / ActiveSupport
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
end

Common 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

Ruby
# 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.