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:
Timefor most general timestamp workDatefor calendar dates without a time-of-dayDateTimefor 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.
0means the starting point60means 60 seconds later3600means one hour later1700000000means 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.
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:
-
require 'date'- Loads Ruby's date library so
DateTimeis available.
- Loads Ruby's date library so
-
timestamp = 1700000000- Stores the Unix timestamp in a variable.
- This number means "1700000000 seconds after January 1, 1970 UTC".
-
time = Time.at(timestamp)- Ruby converts the integer into a
Timeobject. - You now have a full date and time representation.
- Ruby converts the integer into a
-
datetime = time.to_datetime- Ruby converts the
Timeobject into aDateTimeobject. - The represented moment stays the same.
- Ruby converts the
-
puts time- Prints the
Timeobject.
- Prints the
-
puts datetime- Prints the
DateTimeobject.
- Prints the
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.
- An external API may return
-
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.
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
| Concept | What it represents | Typical use | Example |
|---|---|---|---|
Time | A specific moment in time | Most Ruby timestamp work | Time.at(1700000000) |
DateTime | A date and time object from the date library | When APIs or code specifically expect DateTime | Time.at(1700000000).to_datetime |
Date | A calendar date only | Birthdays, due dates, no time-of-day needed | Date.today |
| Unix timestamp | Integer seconds since epoch | Storage, transfer, comparisons | 1700000000 |
Time vs DateTime
| Feature | Time | DateTime |
|---|---|---|
| Best for most Ruby apps | Yes | Usually no |
| Built around timestamps | Yes | Less directly |
| Good for arithmetic with real moments | Yes | Sometimes, but Time is more common |
Requires require 'date' for related features | No | Yes |
Which should you use?
- Use
Timefor most application code. - Use
DateTimewhen:- 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
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 aTimeobject- Use
.to_datetimeif you specifically needDateTime - Be careful with milliseconds vs seconds
- Use
.utcwhen 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.
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
Timeobject. - Also convert each timestamp to a
DateTimeobject. - Print both values in a readable way.
- Use UTC explicitly to avoid timezone confusion.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.