Get the current timestamp
Print the current date / time as either a Unix epoch (seconds since 1970-01-01 UTC) or an ISO 8601 string — for log lines, filenames, expiry calculations, and HTTP `Date` headers.
How to get the current timestamp in each shell
date +%s`date +%s` prints Unix epoch in seconds. ISO 8601 UTC: `date -u +%Y-%m-%dT%H:%M:%SZ`. Local time with offset: `date +%Y-%m-%dT%H:%M:%S%z` (e.g. `2026-05-16T14:23:00+0200`). Milliseconds: `date +%s%3N` (GNU `date` only; macOS BSD `date` lacks `%N`). Bash 5.0+ has `$EPOCHSECONDS` / `$EPOCHREALTIME` builtin vars — faster than forking `date`, useful for tight loops.
date +%sSame `date` binary. Zsh provides `$EPOCHSECONDS` and `$EPOCHREALTIME` via `zmodload zsh/datetime` — sub-second precision without forking. The zsh `strftime` builtin (`zmodload zsh/datetime; strftime "%Y-%m-%dT%H:%M:%S" $EPOCHSECONDS`) is also fork-free. For a unique filename suffix: `${EPOCHSECONDS}` is two orders of magnitude faster than `$(date +%s)` in a loop.
date +%sSame external `date`. ISO 8601 UTC: `date -u +%Y-%m-%dT%H:%M:%SZ`. Fish-specific: `date` works identically to bash; fish has no built-in epoch variable (no `$EPOCHSECONDS` equivalent) — call `date +%s` each time, or stash to a variable: `set t (date +%s)`. For filenames, fish-native string interpolation: `cp app.log app-(date +%Y%m%dT%H%M%S).log`.
[DateTimeOffset]::UtcNow.ToUnixTimeSeconds()The .NET-native answer for Unix epoch. ISO 8601 UTC: `(Get-Date).ToUniversalTime().ToString("o")` — pwsh `"o"` (round-trip) format outputs `2026-05-16T14:23:00.0000000Z`. Local ISO 8601 with offset: `(Get-Date).ToString("o")`. Milliseconds: `[DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()`. AVOID `Get-Date -UFormat %s` — on Windows pwsh 5.1 it returns LOCAL-time epoch (wrong by your UTC offset); pwsh 7+ fixed this but the bug is well-known. `[DateTimeOffset]` is always correct.
echo %date% %time%`%date%` and `%time%` are LOCALE-DEPENDENT — on a German Windows you get `Mo 16.05.2026 14:23:00,42` (note comma decimal), on English `Sat 05/16/2026 14:23:00.42`. Parsing this in a script is a portability nightmare. For a portable timestamp, shell out to pwsh: `for /f %i in ('powershell -NoProfile -Command "[DateTimeOffset]::UtcNow.ToUnixTimeSeconds()"') do set EPOCH=%i`. For a sortable filename-safe stamp: `wmic os get LocalDateTime /value | findstr "="` returns `LocalDateTime=20260516142300.420000+120` — strip the `=` and substring to taste. Honestly: cmd is hostile to timestamp work; use pwsh.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **Wall-clock vs monotonic clock**: `date +%s` (and all the equivalents above) read the **wall clock** — which can jump backwards on NTP correction, leap seconds, manual time adjustment, or VM suspend/resume. For measuring elapsed time inside a script ("how long did this run?") use a monotonic source: bash 5.0+ `$EPOCHREALTIME` is wall-clock too, NOT monotonic; the only portable monotonic timer is `/proc/uptime` (Linux) or `clock_gettime(CLOCK_MONOTONIC)` from C. Pwsh: `[Diagnostics.Stopwatch]::StartNew()` is monotonic (`.Elapsed.TotalSeconds`). For just-good-enough benchmarks, `time cmd` (bash builtin) and `Measure-Command` (pwsh) suffice.
- ISO 8601 vs RFC 3339 vs RFC 2822: ISO 8601 (`2026-05-16T14:23:00Z`) is the modern default — sortable, unambiguous, machine-friendly. RFC 3339 is a strict ISO 8601 subset used by JSON Schema, OpenAPI, and most REST APIs. RFC 2822 (`Sat, 16 May 2026 14:23:00 +0000`) is the legacy HTTP `Date` header format — `date -R` (GNU) / `date -u +"%a, %d %b %Y %H:%M:%S GMT"` (BSD) produces it. JSON dates → ISO 8601 with milliseconds + `Z`. Filenames → strip the colons (`2026-05-16T142300Z`) for cross-FS safety (NTFS forbids `:`).
- Time zones are the eternal trap. `date` defaults to LOCAL time unless `-u` is passed. `(Get-Date)` defaults to local. A server's local zone may not match the developer's; log lines with no `Z` / offset are ambiguous when shipped off-box. RULE: ALWAYS log in UTC (`date -u +%Y-%m-%dT%H:%M:%SZ`), display in local. For "ISO 8601 with explicit offset" (best of both): `date +%Y-%m-%dT%H:%M:%S%:z` (GNU `%:z` adds colon: `+02:00`; BSD `%z` is `+0200` — different RFC 3339 compliance).
- For sub-second precision: GNU `date +%s.%N` gives nanoseconds (last 6 digits typically zero — kernel resolution is microseconds on most kernels), bash 5.0+ `$EPOCHREALTIME` gives microseconds, pwsh `[DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()` gives ms (high-res internally — 100ns ticks). macOS BSD `date` has NO sub-second format (`%N` is unsupported — use `gdate` from `brew install coreutils`).