Convert Unix Timestamp in Bash/Shell
Converting Unix timestamps in Bash/Shell is primarily done using the date command. The main challenge is the difference between GNU date (Linux) and BSD date (macOS) syntax.
Get Current Unix Timestamp
# Current timestamp in seconds date +%s # Example output: 1704067200 # Current timestamp in milliseconds (GNU/Linux only) date +%s%3N # Example output: 1704067200123
Unix Timestamp to Date
# Convert timestamp to readable date date -d @1704067200 # Mon Jan 1 00:00:00 UTC 2024 # Convert with specific format date -d @1704067200 +"%Y-%m-%d %H:%M:%S" # 2024-01-01 00:00:00 # Convert to UTC date -d @1704067200 -u # Mon Jan 1 00:00:00 UTC 2024
# Convert timestamp to readable date date -r 1704067200 # Mon Jan 1 00:00:00 UTC 2024 # Convert with specific format date -r 1704067200 +"%Y-%m-%d %H:%M:%S" # 2024-01-01 00:00:00 # Convert to UTC date -r 1704067200 -u # Mon Jan 1 00:00:00 UTC 2024
Date to Unix Timestamp
# Convert specific date to timestamp date -d "2024-01-01 00:00:00" +%s # 1704067200 # Convert relative date to timestamp date -d "yesterday" +%s date -d "next monday" +%s date -d "2 weeks ago" +%s
# Convert specific date to timestamp date -j -f "%Y-%m-%d %H:%M:%S" "2024-01-01 00:00:00" +%s # 1704067200 # Note: BSD date has limited relative date support # For relative dates, use -v flag date -j -v-1d +%s # yesterday date -j -v+1w +%s # next week
Cross-Platform Compatibility
#!/bin/bash
# Detect date command type
if date --version >/dev/null 2>&1; then
# GNU date
timestamp_to_date() {
date -d "@$1" +"%Y-%m-%d %H:%M:%S"
}
else
# BSD date
timestamp_to_date() {
date -r "$1" +"%Y-%m-%d %H:%M:%S"
}
fi
# Usage
timestamp_to_date 1704067200
# 2024-01-01 00:00:00One-Liners with awk/perl
# Convert timestamp using awk (built-in strftime)
echo "1704067200" | awk '{print strftime("%Y-%m-%d %H:%M:%S", $1)}'
# 2024-01-01 00:00:00
# Process file with timestamps
awk '{print $1, strftime("%Y-%m-%d %H:%M:%S", $2)}' file.txt# Convert timestamp using perl
perl -e 'print scalar localtime(1704067200), "
"'
# Mon Jan 1 00:00:00 2024
# With custom format
perl -e 'use POSIX qw(strftime); print strftime("%Y-%m-%d %H:%M:%S", localtime(1704067200)), "
"'
# 2024-01-01 00:00:00# Convert timestamp using python
python3 -c 'import datetime; print(datetime.datetime.fromtimestamp(1704067200))'
# 2024-01-01 00:00:00
# With custom format
python3 -c 'import datetime; print(datetime.datetime.fromtimestamp(1704067200).strftime("%Y-%m-%d %H:%M:%S"))'
# 2024-01-01 00:00:00Timezone Handling
# Convert to specific timezone TZ="America/New_York" date -d @1704067200 # Sun Dec 31 19:00:00 EST 2023 # UTC time date -d @1704067200 -u # Mon Jan 1 00:00:00 UTC 2024 # Local time date -d @1704067200 # Mon Jan 1 00:00:00 <local timezone> 2024
# Convert to specific timezone TZ="America/New_York" date -r 1704067200 # Sun Dec 31 19:00:00 EST 2023 # UTC time date -r 1704067200 -u # Mon Jan 1 00:00:00 UTC 2024 # Local time date -r 1704067200 # Mon Jan 1 00:00:00 <local timezone> 2024
Common Pitfalls
GNU vs BSD Syntax
The most common issue is using GNU date syntax on macOS or vice versa. Always check which version you have.
# ❌ Wrong on macOS date -d @1704067200 # date: illegal option -- d # ✅ Correct on macOS date -r 1704067200 # ❌ Wrong on Linux (tries to read file modification time) date -r 1704067200 # date: 1704067200: No such file or directory # ✅ Correct on Linux date -d @1704067200
Timezone Assumptions
Date commands use the system timezone by default. Always specify timezone if you need consistent results across systems.
# ❌ Ambiguous - depends on system timezone date -d @1704067200 # ✅ Explicit UTC date -d @1704067200 -u # ✅ Explicit timezone TZ="UTC" date -d @1704067200
Millisecond Precision
Not all systems support millisecond precision. %N (nanoseconds) is GNU-specific and not available on BSD/macOS.
# ❌ Doesn't work on macOS date +%s%3N # ✅ Works on Linux/GNU date +%s%3N # ✅ Cross-platform alternative for milliseconds python3 -c 'import time; print(int(time.time() * 1000))'
Advanced Examples
# Process multiple timestamps from file
while read -r timestamp; do
echo "$timestamp -> $(date -d "@$timestamp" +"%Y-%m-%d %H:%M:%S")"
done < timestamps.txt
# Convert log timestamps
awk '{print $1, strftime("%Y-%m-%d %H:%M:%S", $2)}' /var/log/syslog# Process multiple timestamps from file
while read -r timestamp; do
echo "$timestamp -> $(date -r "$timestamp" +"%Y-%m-%d %H:%M:%S")"
done < timestamps.txt
# Convert log timestamps (awk works the same)
awk '{print $1, strftime("%Y-%m-%d %H:%M:%S", $2)}' /var/log/system.log# Show current timestamp and date every second
while true; do
ts=$(date +%s)
echo "$ts -> $(date -d "@$ts")"
sleep 1
done
# Monitor file changes with timestamps (inotifywait is Linux-specific)
inotifywait -m /path/to/file | while read path; do
echo "$(date +%s): $path"
done# Show current timestamp and date every second
while true; do
ts=$(date +%s)
echo "$ts -> $(date -r "$ts")"
sleep 1
done
# Monitor file changes with timestamps (use fswatch on macOS)
fswatch /path/to/file | while read path; do
echo "$(date +%s): $path"
doneFrequently Asked Questions
What is the difference between GNU and BSD date commands?
GNU date (Linux) uses -d for date strings and @ for timestamps, while BSD date (macOS) uses -r for timestamps and -f for input formats. The syntax for getting current timestamp is the same.
Why does my date command fail on macOS?
macOS uses BSD date, not GNU date. Use date -r timestamp instead of date -d @timestamp (note: BSD does not use the @ prefix). For complex date parsing, you may need to use -f with format strings.
How do I handle milliseconds in shell?
Standard Unix timestamps are in seconds. For milliseconds, divide by 1000 before converting to date, or multiply by 1000 when getting current time with date +%s%3N (GNU only).
Can I convert timestamps without the date command?
Yes, you can use awk, perl, or python one-liners. These are useful when date command is unavailable or when you need more control over formatting.