FreeAI.DevTools

Epoch Converter in Java

Convert Unix timestamps to dates and back in Java: the idiomatic code, the gotchas, and a live converter.

How do you convert a Unix timestamp to a date in Java?

Use Instant.ofEpochSecond(ts) from java.time to get an Instant, and Instant.now().getEpochSecond() for the current epoch. Instant handles both units, ofEpochMilli for 13-digit values and ofEpochSecond for 10-digit ones, so check the digit count before picking, or your dates land in 1970 or the far future.

Epoch to date (Java)
import java.time.Instant;
import java.time.ZoneOffset;

long ts = 1777010400L;
Instant instant = Instant.ofEpochSecond(ts);
System.out.println(instant.atOffset(ZoneOffset.UTC));
// 2026-04-24T06:00Z
Date to epoch (Java)
import java.time.Instant;

Instant now = Instant.now();
long seconds = now.getEpochSecond();
long millis = now.toEpochMilli();
System.out.println(seconds + " " + millis);
Now:

Instant speaks both seconds and milliseconds

Java sits on both sides of the precision divide. The legacy System.currentTimeMillis() and everything descended from java.util.Date count milliseconds, while Unix tooling and most wire formats count seconds. java.time.Instant resolves this cleanly by offering both: ofEpochSecond and getEpochSecond for 10-digit values, ofEpochMilli and toEpochMilli for 13-digit ones. Pick by digit count. Feeding milliseconds to ofEpochSecond puts you roughly in the year 58000, and the reverse strands you in January 1970, so a wrong-era date is always a units bug, never a clock bug.

Leave java.util.Date in the past

Code that predates Java 8 still passes java.util.Date and Calendar around, and both are traps. Date.getYear() returns years since 1900, getMonth() is zero-based, the class is mutable, and its toString() renders in the JVM default timezone, which makes logs disagree across machines. Calendar is verbose and equally mutable. Modern code should hold an Instant for machine time and convert at the edge with instant.atZone(ZoneId.of("UTC")) or a specific zone only when formatting for a human. If a library forces a Date on you, convert immediately with date.toInstant() and never look back.

Frequently asked

How do I get milliseconds since epoch in Java?
Instant.now().toEpochMilli(), or System.currentTimeMillis() if you only need the raw long. Both return the same 13-digit value; Instant is preferable when the value will be compared, formatted, or converted, because it stays in the java.time type system.
Should I still use java.util.Date for timestamps?
No. Date is mutable, its getters use 1900-based years and zero-based months, and it renders in the JVM default timezone. Use java.time.Instant for machine timestamps and ZonedDateTime only at the formatting edge. Convert legacy values with date.toInstant().
How do I convert an Instant to a human-readable date in a specific timezone?
Call instant.atZone(ZoneId.of("Asia/Karachi")) to get a ZonedDateTime, then format with DateTimeFormatter. The Instant itself stays a pure UTC point in time; the zone is applied only for display, which is exactly the separation you want.

More in this series

// The subscription desk

The Inference Report

The weekly briefing for AI engineers: model releases, pricing moves, benchmarks, and the news that changes what you should build with and what it costs. Every Tuesday, 5-minute read. No fluff.

Join AI engineers who stopped overpaying for tokens. Unsubscribe anytime.