Get current time in seconds since the Epoch on Linux, Bash
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
On Linux, date +%s prints the current Unix timestamp as the number of whole seconds since 1970-01-01 00:00:00 UTC. This is the standard shell idiom for epoch time and works in Bash, Zsh, Dash, and any POSIX-compatible shell on systems with GNU coreutils.
The rest of this guide covers capturing the value in variables, getting millisecond and nanosecond precision, converting back to human-readable dates, and avoiding common timezone and arithmetic mistakes.
Capture the Timestamp in a Variable
Most scripts need the epoch value stored in a variable, not printed to stdout.
This is the most common pattern in shell scripts for logging timestamps, generating cache keys, or computing elapsed time.
Measure Elapsed Time
Subtracting two epoch timestamps gives you elapsed seconds without any date string parsing:
This works reliably because epoch seconds are a simple integer. You do not need to handle hours, minutes, or day boundaries. The subtraction is pure arithmetic.
For more readable output on longer durations:
Get Milliseconds and Nanoseconds
date +%s gives only whole seconds. When you need finer precision, GNU date supports %N for nanoseconds (9 digits):
The %s.%N format is useful for benchmarking because it produces a float-like string. However, Bash arithmetic only handles integers, so you will need bc or awk for fractional math:
Convert Epoch Seconds Back to a Date
On GNU/Linux, use date -d @SECONDS to convert an epoch timestamp to a human-readable date:
With a custom format:
On macOS/BSD, the flag is -r instead of -d @:
| Platform | Convert Epoch to Date | Get Epoch Seconds |
| GNU/Linux | date -d @EPOCH | date +%s |
| macOS/BSD | date -r EPOCH | date +%s |
| Busybox | date -d @EPOCH | date +%s |
Timezones Do Not Change the Epoch Value
A common misconception is that changing TZ affects the epoch timestamp. It does not. The epoch is always UTC-referenced. Changing TZ only changes how the date is displayed.
The displayed date differs, but the epoch value is identical because it represents the same absolute moment in time. This is exactly why epoch timestamps are useful for logging and storage: they are timezone-independent.
Using Epoch Time in Practical Scripts
Log Rotation
Simple Rate Limiting
Cache Expiration
Other Ways to Get Epoch Time
Bash Built-in EPOCHSECONDS (Bash 5.0+)
Bash 5.0 introduced a built-in variable that avoids the overhead of forking a date process:
These are faster than $(date +%s) in tight loops because no subprocess is created.
Python One-Liner
Perl One-Liner
Common Pitfalls
Assuming date +%s returns milliseconds instead of seconds is the most frequent mistake. The value is always whole seconds. For milliseconds, you need date +%s%N with division.
Forgetting to quote command substitutions can cause subtle bugs in larger scripts. Always write "$(date +%s)" in conditionals and assignments.
Mixing human-readable timestamps and epoch values in the same variable or log field makes debugging harder. Pick one format per field and convert only when displaying.
Expecting timezone changes to alter the epoch value confuses display formatting with absolute time. date +%s always returns UTC-based seconds regardless of TZ.
Using %N on macOS fails silently because the BSD date command does not support nanoseconds. Use gdate (GNU date via Homebrew) or python3 for sub-second precision on macOS.
Using second-precision timing for benchmarks that need microsecond accuracy produces misleading data. Use $EPOCHREALTIME or date +%s.%N with bc for high-resolution timing.
Summary
date +%sreturns current time in whole seconds since the Unix epoch.- Capture it with
now=$(date +%s)and subtract two values for elapsed time. - Use
date +%s%Nfor nanosecond precision; divide by 1,000,000 for milliseconds. - Convert back with
date -d @EPOCHon GNU/Linux ordate -r EPOCHon macOS. - Epoch timestamps are timezone-independent;
TZonly affects display formatting. - On Bash 5.0+, use
$EPOCHSECONDSor$EPOCHREALTIMEto avoid subprocess overhead.

