How to Compare Dates in Bash
Quick Answer: Compare Dates in Bash
For ISO 8601 dates (YYYY-MM-DD), simple string comparison works: if [ "$date1" \< "$date2" ]. For any format, convert to epoch timestamps and compare: if [ $(date -d "$d1" +%s) -lt $(date -d "$d2" +%s) ]. The epoch method is most reliable for any format.
Quick Comparison: Date Comparison Methods
| Method | Format | Flexibility | Reliability |
|---|---|---|---|
| String compare | ISO 8601 only | Low | High |
| Epoch compare | Any | High | Very high |
| File dates | File mtime | Limited | Good |
Bottom line: Use epoch conversion for reliable date comparisons with any format.
Compare dates in Bash to determine which date is earlier, later, or equal. Learn string comparison, epoch time, and file modification dates.
Method 1: Date String Comparison
Simple string comparison works for ISO 8601 format dates (YYYY-MM-DD):
date1="2026-02-21"
date2="2026-03-15"
if [[ "$date1" < "$date2" ]]; then
echo "date1 is earlier"
else
echo "date1 is later or equal"
fi
Output:
date1 is earlier
Note: String comparison only works reliably with YYYY-MM-DD format because digits compare correctly as strings.
Convert to Epoch (Seconds Since 1970)
For more robust comparison, convert dates to epoch time (seconds):
#!/bin/bash
date1="2026-02-21"
date2="2026-03-15"
# Convert to epoch seconds
epoch1=$(date -d "$date1" +%s)
epoch2=$(date -d "$date2" +%s)
if [ "$epoch1" -lt "$epoch2" ]; then
echo "date1 is earlier"
elif [ "$epoch1" -gt "$epoch2" ]; then
echo "date1 is later"
else
echo "dates are equal"
fi
Output:
date1 is earlier
Compare File Modification Dates
Use -nt (newer than) and -ot (older than) operators:
# Check if file1 is newer than file2
if [ file1.txt -nt file2.txt ]; then
echo "file1 is newer"
fi
# Check if file1 is older than file2
if [ file1.txt -ot file2.txt ]; then
echo "file1 is older"
fi
# Check if file1 exists and is newer than file2
if [ file1.txt -nt file2.txt ] && [ -f file1.txt ]; then
echo "file1 is newer and exists"
fi
Calculate Days Between Dates
#!/bin/bash
date1="2026-02-21"
date2="2026-03-15"
# Convert to epoch
epoch1=$(date -d "$date1" +%s)
epoch2=$(date -d "$date2" +%s)
# Calculate difference in seconds
diff_seconds=$((epoch2 - epoch1))
# Convert to days
diff_days=$((diff_seconds / 86400))
echo "Days between dates: $diff_days"
Output:
Days between dates: 22
Compare Dates with Times
#!/bin/bash
date1="2026-02-21 10:30:00"
date2="2026-02-21 14:15:30"
epoch1=$(date -d "$date1" +%s)
epoch2=$(date -d "$date2" +%s)
diff_seconds=$((epoch2 - epoch1))
# Convert to hours and minutes
hours=$((diff_seconds / 3600))
minutes=$(((diff_seconds % 3600) / 60))
echo "Difference: $hours hours and $minutes minutes"
Output:
Difference: 3 hours and 44 minutes
Practical Example: Backup Rotation
#!/bin/bash
# File: cleanup_old_backups.sh
backup_dir="$1"
days_to_keep="$2"
if [ -z "$backup_dir" ] || [ -z "$days_to_keep" ]; then
echo "Usage: $0 <backup_dir> <days>"
exit 1
fi
if [ ! -d "$backup_dir" ]; then
echo "ERROR: Directory not found: $backup_dir"
exit 1
fi
current_time=$(date +%s)
for file in "$backup_dir"/*; do
if [ -f "$file" ]; then
file_time=$(stat -c %Y "$file")
age_seconds=$((current_time - file_time))
age_days=$((age_seconds / 86400))
if [ "$age_days" -gt "$days_to_keep" ]; then
echo "Removing old backup: $(basename "$file") ($age_days days old)"
rm "$file"
fi
fi
done
echo "Cleanup completed"
Usage:
$ chmod +x cleanup_old_backups.sh
$ ./cleanup_old_backups.sh ~/backups 30
Removing old backup: backup_20250815.tar (195 days old)
Cleanup completed
Check if Date is in the Past
#!/bin/bash
target_date="2026-02-20"
current_date=$(date +%Y-%m-%d)
target_epoch=$(date -d "$target_date" +%s)
current_epoch=$(date -d "$current_date" +%s)
if [ "$target_epoch" -lt "$current_epoch" ]; then
echo "$target_date is in the past"
elif [ "$target_epoch" -gt "$current_epoch" ]; then
echo "$target_date is in the future"
else
echo "$target_date is today"
fi
Output:
2026-02-20 is in the past
Compare with Deadline
#!/bin/bash
deadline="2026-03-31"
project="ProjectX"
deadline_epoch=$(date -d "$deadline" +%s)
current_epoch=$(date +%s)
if [ "$current_epoch" -gt "$deadline_epoch" ]; then
echo "ERROR: $project deadline has passed!"
exit 1
else
days_left=$(( ($deadline_epoch - $current_epoch) / 86400 ))
echo "$project deadline: $days_left days remaining"
fi
Output:
ProjectX deadline: 37 days remaining
Compare Timestamps from Files
#!/bin/bash
# Compare log files by timestamp in filename
log1="app_2026-02-15_10-30.log"
log2="app_2026-02-21_14-45.log"
# Extract dates from filenames
date1=$(echo "$log1" | cut -d_ -f2)
date2=$(echo "$log2" | cut -d_ -f2)
epoch1=$(date -d "$date1" +%s)
epoch2=$(date -d "$date2" +%s)
if [ "$epoch1" -lt "$epoch2" ]; then
echo "$log2 is newer"
else
echo "$log1 is newer"
fi
Output:
app_2026-02-21_14-45.log is newer
File Test Operators
| Operator | Meaning |
|---|---|
-nt | newer than |
-ot | older than |
-ef | same file |
if [ file1 -nt file2 ] && [ -f file1 ]; then
echo "file1 exists and is newer"
fi
Common Mistakes
- Not using epoch time - string comparison unreliable for different formats
- Forgetting
date -drequires GNU date - BSD date syntax differs - Integer arithmetic overflow - rarely happens with epoch time
- Not handling timezones - epoch is always UTC
- Comparing invalid dates - validate format first
Tips and Best Practices
- Use YYYY-MM-DD format for consistency
- Convert to epoch for reliable comparisons
- Always check if date conversion succeeds
- Use
-nt/-otfor file modifications - Remember epoch time is in UTC
Summary
Date comparison in Bash requires careful attention to format. String comparison works for ISO dates, but epoch conversion is more robust for calculations. Use file operators for modification times, and always handle timezone considerations in production scripts.