Skip to content
shellmap

Convert a Unix epoch to a human-readable date

Render a Unix-epoch integer (e.g. `1747396980`) as a readable date — for log inspection, file-metadata audits, and translating database timestamps.

How to convert a unix epoch to a human-readable date in each shell

Bashunix
date -d @1747396980

GNU only. `date -d @EPOCH` interprets the integer as Unix seconds; without the leading `@` it tries to parse as a date string. With format: `date -ud @1747396980 +%Y-%m-%dT%H:%M:%SZ`.

Zshunix
date -d @1747396980
Fishunix
date -d @1747396980
PowerShellwindows
[DateTimeOffset]::FromUnixTimeSeconds(1747396980).UtcDateTime

`.UtcDateTime` keeps it in UTC. Drop the `.UtcDateTime` to keep a `[DateTimeOffset]` with offset 0. For ms-precision input: `[DateTimeOffset]::FromUnixTimeMilliseconds(1747396980123)`.

cmd.exewindows
powershell -NoProfile -Command "[DateTimeOffset]::FromUnixTimeSeconds(1747396980).UtcDateTime"

cmd has no epoch arithmetic — `(date | time)` math is locale-formatted strings, not integers. Always shell out to pwsh.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • **GNU vs BSD divergence — different flag entirely**: GNU (Linux) uses `date -d @EPOCH` (the `-d` is "describe a date string"; `@N` is the epoch-string syntax). BSD / macOS uses `date -r EPOCH` (the `-r` is "use the file's mtime, but if it parses as an integer treat as epoch"). These are NOT compatible — `date -d @1747396980` errors on macOS (`date: illegal option -- d`), and `date -r 1747396980` errors on Linux (`date: cannot stat ‘1747396980’: No such file or directory`). Detect the platform first: `if [ "$(uname)" = "Darwin" ]; then date -r $epoch; else date -d @$epoch; fi`. Or install GNU coreutils on macOS (`brew install coreutils`) and use `gdate -d @$epoch`.
  • Epoch precision: bash/`date` operates on **seconds**. Milliseconds (JavaScript / Java conventions) require dividing first: `date -d @$((EPOCH_MS / 1000))`. Microseconds (Postgres `epoch_us`) divide by 1,000,000. pwsh has explicit cmdlets for each: `FromUnixTimeSeconds`, `FromUnixTimeMilliseconds` — no `FromUnixTimeMicroseconds`, but `[DateTimeOffset]::UnixEpoch.AddTicks(MICROSECONDS * 10)` works (a tick is 100 ns, so a microsecond is 10 ticks). For nanoseconds (Linux kernel CLOCK_REALTIME, Go `time.UnixNano`), pwsh: `[DateTimeOffset]::UnixEpoch.AddTicks(NS / 100)`.
  • pwsh `[DateTimeOffset]::FromUnixTimeSeconds` returns a `[DateTimeOffset]` with offset `+00:00` (UTC); the `.UtcDateTime` accessor unwraps to a `[DateTime]` with `Kind=Utc`. To convert to LOCAL display: `.LocalDateTime` or `.ToLocalTime()`. Common pitfall: `[DateTime]::Parse((Get-Date).ToString())` LOSES the `Kind` — round-trip via `[DateTimeOffset]` or via the `"o"` format specifier instead. For pwsh 5.1 / .NET Framework 4.5 compat: `[DateTimeOffset]::FromUnixTimeSeconds` exists since .NET 4.6 — earlier 4.5 needs manual `(New-Object DateTime 1970,1,1,0,0,0,([DateTimeKind]::Utc)).AddSeconds($epoch)`.
  • Reverse direction (date → epoch): GNU `date -d "2026-05-16T14:23:00Z" +%s` (or whatever ISO subset). BSD: `date -j -f "%Y-%m-%dT%H:%M:%SZ" "2026-05-16T14:23:00Z" +%s` — note `-j` ("don't actually set the system clock") and `-f` ("input format"). pwsh: `([DateTimeOffset]"2026-05-16T14:23:00Z").ToUnixTimeSeconds()`. The asymmetry between GNU `-d` and BSD `-j -f` trips up nearly every cross-platform script — putting both branches behind a `to_epoch()` shell function is the durable fix.

Related commands

Related tasks