How to Get the Current Time in Seconds Since the Epoch in Bash on Linux
You need a timestamp for logging, calculating time differences, or working with APIs that expect Unix time. How do you get the current time in seconds since the epoch in Bash?
TL;DR
Use date +%s to get the current Unix timestamp (seconds since January 1, 1970 00:00:00 UTC). For milliseconds, use date +%s%3N. To convert a specific date to epoch seconds, use date -d "2024-01-15" +%s. To convert epoch seconds back to a human-readable date, use date -d @1704067200.
The Unix epoch is midnight UTC on January 1, 1970. The Unix timestamp counts seconds since that moment, making it useful for time calculations and comparisons.
Get the current timestamp:
date +%s
Output (current time):
1711892400
This number represents seconds elapsed since the epoch.
Why Use Unix Timestamps?
Unix timestamps are useful because:
- They're timezone-independent (always UTC)
- Easy to compare and calculate differences
- Widely used in programming and APIs
- Compact representation of time
- No ambiguity about format
Getting Milliseconds
Some applications need millisecond precision:
# Seconds with milliseconds (13 digits)
date +%s%3N
Output:
1711892400123
The %3N adds milliseconds (3 digits of nanoseconds).
For microseconds:
date +%s%6N
For nanoseconds:
date +%s%N
Converting Specific Dates to Epoch
Convert a date string to Unix timestamp:
# Specific date
date -d "2024-01-15" +%s
# Date with time
date -d "2024-01-15 14:30:00" +%s
# Relative dates
date -d "yesterday" +%s
date -d "next week" +%s
date -d "3 days ago" +%s
The -d flag parses date strings in various formats.
Converting Epoch Back to Human-Readable Date
Convert a Unix timestamp to readable format:
# Using @ prefix
date -d @1704067200
# With custom format
date -d @1704067200 +"%Y-%m-%d %H:%M:%S"
Output:
2024-01-01 00:00:00
Calculating Time Differences
Measure how long something takes:
#!/bin/bash
# Record start time
START=$(date +%s)
# Do something that takes time
sleep 5
# Your actual work here
# Record end time
END=$(date +%s)
# Calculate difference
ELAPSED=$((END - START))
echo "Operation took $ELAPSED seconds"
Output:
Operation took 5 seconds
Practical Example: Timestamped Logging
Add timestamps to log entries:
#!/bin/bash
LOG_FILE="app.log"
log() {
TIMESTAMP=$(date +%s)
DATETIME=$(date +"%Y-%m-%d %H:%M:%S")
echo "[$TIMESTAMP] [$DATETIME] $*" >> "$LOG_FILE"
}
# Usage
log "Application started"
log "User logged in"
log "Processing complete"
Log file output:
[1711892400] [2024-03-31 15:00:00] Application started
[1711892405] [2024-03-31 15:00:05] User logged in
[1711892412] [2024-03-31 15:00:12] Processing complete
Practical Example: Benchmarking
Compare performance of different approaches:
#!/bin/bash
benchmark() {
local description="$1"
local command="$2"
local start=$(date +%s%3N)
eval "$command"
local end=$(date +%s%3N)
local elapsed=$((end - start))
echo "$description: ${elapsed}ms"
}
# Usage
benchmark "Method 1" "for i in {1..1000}; do echo $i > /dev/null; done"
benchmark "Method 2" "seq 1 1000 > /dev/null"
Output:
Method 1: 245ms
Method 2: 12ms
Creating Unique Filenames with Timestamps
Use timestamps for unique file names:
# Backup with timestamp
TIMESTAMP=$(date +%s)
cp important.txt "important-$TIMESTAMP.txt.bak"
# Log file with timestamp
LOG_FILE="app-$TIMESTAMP.log"
touch "$LOG_FILE"
# More readable format
READABLE=$(date +"%Y%m%d-%H%M%S")
mkdir "backup-$READABLE"
Checking File Age
Determine how old a file is:
#!/bin/bash
FILE="$1"
if [ ! -f "$FILE" ]; then
echo "File not found"
exit 1
fi
# Get file modification time in epoch seconds
FILE_TIME=$(stat -c %Y "$FILE")
# Get current time
CURRENT_TIME=$(date +%s)
# Calculate age in seconds
AGE=$((CURRENT_TIME - FILE_TIME))
# Convert to days
AGE_DAYS=$((AGE / 86400))
echo "File is $AGE seconds old ($AGE_DAYS days)"
Setting Timeout Conditions
Implement timeouts in scripts:
#!/bin/bash
TIMEOUT=60 # seconds
START=$(date +%s)
while true; do
# Your condition
if some_check; then
echo "Success!"
break
fi
# Check timeout
CURRENT=$(date +%s)
ELAPSED=$((CURRENT - START))
if [ $ELAPSED -gt $TIMEOUT ]; then
echo "Timeout after $TIMEOUT seconds"
exit 1
fi
sleep 1
done
Comparing Timestamps
Check if one timestamp is older than another:
TIMESTAMP1=1704067200 # 2024-01-01
TIMESTAMP2=1711892400 # 2024-03-31
if [ $TIMESTAMP1 -lt $TIMESTAMP2 ]; then
echo "Timestamp 1 is older"
else
echo "Timestamp 2 is older"
fi
# Calculate difference
DIFF=$((TIMESTAMP2 - TIMESTAMP1))
DIFF_DAYS=$((DIFF / 86400))
echo "Difference: $DIFF_DAYS days"
Time Zones and Epoch
Epoch time is always UTC. To get a timestamp for a specific timezone:
# Current time in New York
TZ="America/New_York" date +%s
# Current time in Tokyo
TZ="Asia/Tokyo" date +%s
But since epoch is UTC-based, these return the same value - the current UTC time. To get the timestamp for "midnight in New York":
TZ="America/New_York" date -d "today 00:00:00" +%s
Practical Example: Session Timeout
Track user sessions with expiry:
#!/bin/bash
SESSION_FILE=".session"
TIMEOUT=3600 # 1 hour
start_session() {
date +%s > "$SESSION_FILE"
echo "Session started"
}
check_session() {
if [ ! -f "$SESSION_FILE" ]; then
echo "No active session"
return 1
fi
SESSION_START=$(cat "$SESSION_FILE")
CURRENT=$(date +%s)
ELAPSED=$((CURRENT - SESSION_START))
if [ $ELAPSED -gt $TIMEOUT ]; then
echo "Session expired"
rm "$SESSION_FILE"
return 1
fi
REMAINING=$((TIMEOUT - ELAPSED))
echo "Session active ($REMAINING seconds remaining)"
return 0
}
# Usage
start_session
sleep 5
check_session
Practical Example: Rate Limiting
Implement simple rate limiting:
#!/bin/bash
RATE_FILE=".last_run"
MIN_INTERVAL=300 # 5 minutes between runs
can_run() {
if [ ! -f "$RATE_FILE" ]; then
return 0 # No previous run, allowed
fi
LAST_RUN=$(cat "$RATE_FILE")
CURRENT=$(date +%s)
ELAPSED=$((CURRENT - LAST_RUN))
if [ $ELAPSED -lt $MIN_INTERVAL ]; then
WAIT=$((MIN_INTERVAL - ELAPSED))
echo "Please wait $WAIT seconds before running again"
return 1
fi
return 0
}
record_run() {
date +%s > "$RATE_FILE"
}
# Usage
if can_run; then
echo "Running task..."
# Do your task
record_run
fi
Using bc for Precise Calculations
For more complex time calculations:
#!/bin/bash
START=$(date +%s)
sleep 2
END=$(date +%s)
# Calculate with decimals
ELAPSED=$(echo "$END - $START" | bc)
echo "Elapsed: ${ELAPSED}s"
# Convert seconds to hours
HOURS=$(echo "scale=2; $ELAPSED / 3600" | bc)
echo "That's $HOURS hours"
Common Time Constants
Useful constants for time calculations:
# Time constants in seconds
SECOND=1
MINUTE=60
HOUR=3600
DAY=86400
WEEK=604800
MONTH=2592000 # 30 days
YEAR=31536000 # 365 days
# Calculate timestamps
ONE_HOUR_AGO=$(($(date +%s) - HOUR))
TOMORROW=$(($(date +%s) + DAY))
NEXT_WEEK=$(($(date +%s) + WEEK))
Epoch Time Limitations
The Unix timestamp has limitations:
- 32-bit systems face the "Year 2038 problem" (max timestamp: 2147483647)
- 64-bit systems are fine until year 292 billion+
- Doesn't include leap seconds
- Always UTC, requires conversion for local time display
For Y2038-safe code on 32-bit systems, consider using 64-bit integers or alternative time representations.
Converting Between Formats
Quick reference for conversions:
# Now to epoch
date +%s
# Epoch to human-readable
date -d @1711892400
# Specific date to epoch
date -d "2024-03-31 15:00:00" +%s
# With milliseconds
date +%s%3N
# File modification time to epoch
stat -c %Y filename
Getting the Unix timestamp in Bash is simple with date +%s. Whether you're logging events, measuring performance, implementing timeouts, or working with time-based logic, epoch seconds provide a reliable, timezone-independent way to work with time.
We earn commissions when you shop through the links below.
DigitalOcean
Cloud infrastructure for developers
Simple, reliable cloud computing designed for developers
DevDojo
Developer community & tools
Join a community of developers sharing knowledge and tools
Acronis
The most secure backup
Acronis: the most secure backup solution for your data
Want to support DevOps Daily and reach thousands of developers?
Become a SponsorFound an issue?