Question

Convert a Unix Timestamp to Ruby DateTime

rubydatetimetimestamp

Question

How can you convert a Unix timestamp, which represents seconds since the Unix epoch, into a Ruby DateTime value?

For example, given a Unix timestamp like 1700000000, what is the correct way to turn it into a Ruby date/time object?

Short Answer

By the end of this page, you will understand how Unix timestamps work in Ruby, how to convert them into Time and DateTime objects, when to use each type, and what common mistakes to avoid when dealing with time zones and epoch values.

Concept

A Unix timestamp is the number of seconds that have passed since January 1, 1970 00:00:00 UTC. It is a very common way to store or transmit dates in databases, APIs, log files, and background jobs.

In Ruby, the most common way to convert a Unix timestamp is to first create a Time object:

time = Time.at(1700000000)

If you specifically need a DateTime, you can convert that Time object:

require 'date'

datetime = Time.at(1700000000).to_datetime

This matters because Ruby has multiple date/time types:

  • Time for most general timestamp work
  • Date for calendar dates without a time-of-day
  • DateTime for date-time values when you specifically need that class

In real Ruby programs, developers usually prefer Time unless they have a reason to use DateTime. But if your code, library, or data model expects DateTime, converting from a Unix timestamp is straightforward using Time.at(...).to_datetime.

Mental Model

Think of a Unix timestamp as a counter that starts at zero on January 1, 1970 UTC.

  • 0 means the starting point
  • 60 means 60 seconds later
  • 3600 means one hour later
  • 1700000000 means a very large number of seconds later

Ruby's Time.at is like saying: "Show me the calendar date and clock time at this many seconds after the starting point."

If you then call to_datetime, you are changing the object into a different date/time representation, while keeping the same moment in time.

Take Quiz

Syntax and Examples

The core syntax is:

Time.at(unix_timestamp)

If you need a DateTime object:

require 'date'

Time.at(unix_timestamp).to_datetime

Example 1: Convert to Time

timestamp = 1700000000
result = Time.at(timestamp)

puts result

This creates a Ruby Time object from the Unix timestamp.

Example 2: Convert to DateTime

require 'date'

timestamp = 1700000000
result = Time.at(timestamp).to_datetime

puts result

This creates a DateTime object.

Example 3: UTC conversion

Unix timestamps are based on UTC, so you often want to be explicit:

require 'date'

timestamp = 1700000000
result = Time.at(timestamp).utc.to_datetime

puts result

This avoids confusion from local system time zones.

Example 4: Local time vs UTC

timestamp = 1700000000

local_time = Time.at(timestamp)
utc_time = Time.at(timestamp).utc

puts local_time
puts utc_time

Depending on your machine settings, local_time and utc_time may display different offsets, even though they represent the same instant.

Step by Step Execution

Consider this example:

require 'date'

timestamp = 1700000000

time = Time.at(timestamp)
datetime = time.to_datetime

puts time
puts datetime

Step by step:

  1. require 'date'

    • Loads Ruby's date library so DateTime is available.
  2. timestamp = 1700000000

    • Stores the Unix timestamp in a variable.
    • This number means "1700000000 seconds after January 1, 1970 UTC".
  3. time = Time.at(timestamp)

    • Ruby converts the integer into a Time object.
    • You now have a full date and time representation.
  4. datetime = time.to_datetime

    • Ruby converts the Time object into a DateTime object.
    • The represented moment stays the same.
  5. puts time

    • Prints the Time object.
  6. puts datetime

    • Prints the DateTime object.

Small trace

If timestamp is 0:

Time.at(0)

This represents the Unix epoch start:

1970-01-01 00:00:00 UTC

If you write:

Time.at(0).to_datetime

You get the same moment as a DateTime object instead.

Real World Use Cases

Unix timestamp conversion appears in many real programs:

  • API responses

    • An external API may return created_at: 1700000000.
    • Your Ruby app converts it before displaying it.
  • Database records

    • Some systems store timestamps as integers for portability.
    • Ruby converts them when reading data.
  • Log processing

    • Server logs often contain epoch-based times.
    • Scripts convert them into human-readable dates.
  • Background jobs

    • A scheduled task may run at a timestamp stored in Redis or a queue.
    • Ruby converts the integer into a time object to compare or schedule work.
  • Data imports

    • CSV or JSON files may contain Unix timestamps.
    • Ruby converts them during parsing and validation.
Take Quiz

Real Codebase Usage

In real Ruby codebases, developers usually use a few common patterns around timestamp conversion.

1. Parse incoming data safely

def parse_created_at(data)
  return nil unless data[:created_at]

  Time.at(data[:created_at]).utc
end

This uses a guard clause to avoid errors when the timestamp is missing.

2. Convert only when needed

def created_at_datetime(timestamp)
  Time.at(timestamp).utc.to_datetime
end

If another part of the app specifically needs DateTime, convert at that boundary.

3. Validate timestamp values

def valid_timestamp?(value)
  value.is_a?(Integer) && value >= 0
end

This helps avoid passing strings or invalid data into Time.at.

4. Be explicit about time zone

time = Time.at(timestamp).utc

This avoids bugs caused by different server or developer machine time zones.

5. Map over collections

timestamps = [1700000000, 1700003600, 1700007200]
times = timestamps.map { |ts| Time.at(ts).utc }

This is common when processing batches of records from APIs or files.

Common Mistakes

Here are common beginner mistakes when converting Unix timestamps in Ruby.

1. Forgetting that Time.at already returns a Time

Broken expectation:

result = Time.at(1700000000)
# expecting DateTime directly

Time.at returns a Time, not a DateTime.

Use this if you need DateTime:

require 'date'
result = Time.at(1700000000).to_datetime

2. Forgetting to require date

Broken code:

result = Time.at(1700000000).to_datetime

In some environments, DateTime support may not be loaded yet.

Safer version:

require 'date'
result = Time.at(1700000000).to_datetime

3. Confusing milliseconds with seconds

Some APIs return milliseconds, not seconds.

Broken code:

Time.at(1700000000000)

This is likely the wrong date because the value is too large for a seconds-based timestamp.

Correct approach:

milliseconds = 1700000000000
Time.at(milliseconds / 1000)

4. Ignoring time zones

Broken code:

Time.at(1700000000)

This may use local system time for display.

Safer approach:

Time.at(1700000000).utc

5. Passing strings without conversion

Broken code:

timestamp = "1700000000"
Time.at(timestamp)

Convert first if needed:

timestamp = "1700000000"
Time.at(timestamp.to_i)

Be careful: to_i turns invalid strings into 0, so validate input when necessary.

Comparisons

ConceptWhat it representsTypical useExample
TimeA specific moment in timeMost Ruby timestamp workTime.at(1700000000)
DateTimeA date and time object from the date libraryWhen APIs or code specifically expect DateTimeTime.at(1700000000).to_datetime
DateA calendar date onlyBirthdays, due dates, no time-of-day neededDate.today
Unix timestampInteger seconds since epochStorage, transfer, comparisons1700000000

Time vs DateTime

FeatureTimeDateTime
Best for most Ruby appsYesUsually no
Built around timestampsYesLess directly
Good for arithmetic with real momentsYesSometimes, but Time is more common
Requires require 'date' for related featuresNoYes

Which should you use?

  • Use Time for most application code.
  • Use DateTime when:
    • a library expects it
    • you are already working with DateTime
    • your codebase standard uses it

For the original question, the direct answer is usually:

require 'date'
Time.at(timestamp).to_datetime
Take Quiz

Cheat Sheet

# Unix timestamp -> Time
Time.at(timestamp)

# Unix timestamp -> UTC Time
Time.at(timestamp).utc

# Unix timestamp -> DateTime
require 'date'
Time.at(timestamp).to_datetime

# Unix timestamp -> UTC DateTime
require 'date'
Time.at(timestamp).utc.to_datetime

Rules to remember

  • Unix timestamps are usually in seconds since 1970-01-01 00:00:00 UTC
  • Time.at(...) returns a Time object
  • Use .to_datetime if you specifically need DateTime
  • Be careful with milliseconds vs seconds
  • Use .utc when you want predictable timezone handling

Common input cleanup

timestamp = params[:timestamp].to_i
Time.at(timestamp).utc

Epoch example

Time.at(0)
# => 1970-01-01 00:00:00 UTC

FAQ

How do I convert a Unix timestamp to a Ruby DateTime?

Use:

require 'date'
Time.at(timestamp).to_datetime

How do I convert a Unix timestamp to Ruby Time?

Use:

Time.at(timestamp)

Should I use Time or DateTime in Ruby?

For most Ruby programs, use Time. Use DateTime only when you specifically need that class.

Why does my converted time look different on another machine?

Because local time zones may differ. Use .utc to make the result consistent.

What if my timestamp is in milliseconds?

Divide by 1000 before passing it to Time.at.

Time.at(milliseconds / 1000)

Can I convert a string timestamp like "1700000000"?

Yes, but convert it first:

Time.at("1700000000".to_i)

What does Time.at(0) mean?

It represents the Unix epoch start: 1970-01-01 00:00:00 UTC.

Take Quiz

Mini Project

Description

Build a small Ruby script that reads several Unix timestamps and prints them in a human-readable format. This demonstrates how to convert timestamps into both Time and DateTime, and how to handle UTC explicitly. It is similar to what you might do when processing API data or imported records.

Goal

Create a script that converts a list of Unix timestamps into readable UTC date/time values using Ruby.

Requirements

  • Store at least three Unix timestamps in an array.
  • Convert each timestamp to a Ruby Time object.
  • Also convert each timestamp to a DateTime object.
  • Print both values in a readable way.
  • Use UTC explicitly to avoid timezone confusion.
Take Quiz

Keep learning

Related questions

View more