As a core Linux utility, date may seem simple on the surface. But behind its basic date and time display capabilities lies an incredibly versatile tool for manipulating, processing, and reformatting temporal data. Mastering date is critical for Linux power users and programmers alike.
In this comprehensive 2600+ word guide, you‘ll gain true expertise in wielding advanced date functionality through numerous insightful examples and in-depth explanations. You‘ll level up your command line temporal abilities – whether it‘s reformatting dates, calculating future/past times, integrating dates into scripts, or leveraging dates in creative workflows.
Let‘s dive deep into the full power of date.
Date and Time Output Formatting
The default date output is quite simple:
Fri Mar 10 23:15:42 EST 2023
While some systems show the timezone (EST above), the default output leaves much to be desired. But date supports over 60 formatting options for ultimate control of your date/time display.
Some commonly used formatting codes:
| Code | Meaning | Example (Mar 10, 2023 11:21:33 PM EST) |
|---|---|---|
| %A | Full weekday name | Friday |
| %a | Abbreviated weekday | Fri |
| %B | Full month name | March |
| %b | Abbreviated month | Mar |
| %d | Day of month (01-31) | 10 |
| %j | Day of year (001-366) | 069 |
| %y | 2-digit year | 23 |
| %Y | 4-digit year | 2023 |
| %H | 24-hour clock hour | 23 |
| %I | 12-hour clock hour | 11 |
| %M | Minute (00-60) | 21 |
| %S | Second (00-60) | 33 |
| %p | AM/PM | PM |
The codes are case-sensitive. %B gives full month name, %b abbreviated name.
You chain codes together to build whatever output you need:
$ date "+%A, %B %d, %Y at %I:%M %p %Z"
Friday, March 10, 2023 at 11:21 PM EST
Experiment with different codes to customize formats for different use cases. Align values in columns with padding:
$ date "+%-d/%-m/%Y %-I:%M %-p"
10/03/2023 11:24 PM
The - flag left-aligns padded values. Without it numbers pad right.
Image Formatting
Here is a format useful for timestamping images:
$ date "+%Y-%m-%d-%H-%M-%S-EST"
2023-03-11-00-27-19-EST
Applied to an image from March 11, 2023 12:27:19 AM EST gives us:
myimage-2023-03-11-00-27-19-EST.jpg
Matches common image naming conventions containing date taken and avoids filename conflicts.
Date and Time Calculations
Calculating dates relative to today is a common need. Rather than mental math to figure out times in the future or past, date makes it easy.
Some examples:
$ date --date="2 days ago"
Wed Mar 8 00:30:40 EST 2023
$ date --date="3 weeks"
Fri Mar 31 00:31:00 EDT 2023
$ date --date="January 1 next year"
Mon Jan 1 00:31:33 EST 2024
Units supported are seconds, minutes, hours, days, weeks, months, years, next, last, tomorrow, yesterday along with arithmetic expressions:
$ date --date="4 years 2 months 15 days ago"
Sat Dec 28 00:32:32 EST 2019
Date math with units works right on command line without any scripting.
| Relative Date Examples | |
|---|---|
| 5 minutes ago | |
| 2 hours 30 minutes from now | |
| Tomorrow at 9:30 AM | |
| December 31, next year at noon |
Leveraging these calculations, you could run a backup script every 5 days, check logs every 3 hours, run a cron job every Friday – all without hardcoded delays. date math handles the relative timing.
Epoch Conversion
Epoch time tracks seconds since Jan 1st, 1970. This integer storage makes date math easy. Convert to/from epoch with:
$ date +%s # Current epoch seconds
1678512090
$ date -d @1678512090 # Convert back
Sat Mar 11 00:48:10 EST 2023
Epoch enables portable date storage good for logging or data analysis. Plus Unix-style piping into conversions:
$ uptime | awk ‘{print $3}‘ | date -d "@$(($(date +%s) - $(date +%s -d @$1)))"
up 1 day, 3:51
Showing how long the system has been running by converting boot time using epoch arithmetic.
Working with Time Zones
date outputs using your local time zone configuration. To override:
$ TZ=MST7MDT date
Sat Mar 11 01:13:44 MST 2023
On my EST machine setting TZ temporarily sets the zone for that command. Or save TZ configs in /etc/localtime.
Get UTC offset with name:
$ date -R
Sat, 11 Mar 2023 06:13:44 -0500
Force UTC times with:
$ date -u
Sat Mar 11 11:13:44 UTC 2023
Note the suffix Z indicating Zulu/UTC time. Useful for log files and global timestamp needs.
List available time zones:
$ timedatectl list-timezones
Africa/Abidjan
Africa/Accra
...
Etc/UTC
Etc/Zulu
Take your pick of any region or city on Earth!
Leveraging Dates in Bash Scripts
While using date on the command line is handy, it really shines in Bash script automation. Simple examples:
#!/bin/bash
now=$(date +%F)
echo "Today‘s date is: $now"
tomorrow=$(date --date=‘1 day‘ +%A)
echo "Tomorrow is $tomorrow"
Prints:
Today‘s date is: 2023-03-11
Tomorrow is Sunday
Elapsed Time Calculator
Here is a script to get time elapsed between two dates:
#!/bin/bash
if [ $# -ne 2 ]; then
echo "Usage: $0 YYYY-MM-DD YYYY-MM-DD" >&2
exit 1
fi
start_epoch=$(date -d "$1" +%s)
end_epoch=$(date -d "$2" +%s)
duration=$((end_epoch - start_epoch))
days=$((duration / 60 / 60 / 24))
echo "$1 to $2 was $days days"
Save as date-elapsed.sh, run it:
$ ./date-elapsed 2023-01-01 2023-02-15
2023-01-01 to 2023-02-15 was 45 days
Great for calculating project timespans, age, durations, etc.
We could improve it with hrs, mins, secs display by modding the duration var. left as an exercise!
Log File Rotation by Date
Here‘s a script to delete Apache logs older than 15 days. Runs via cron nightly:
#!/bin/bash
now=$(date +%s)
cutoff=$((now - 60*60*24*15))
old_logs=$(ls -t /var/log/httpd/ | grep "^access_log-" | head -n 1)
for log in $old_logs; do
log_date=$(date -d "${log:11:8}" +%s)
if [ $log_date -lt $cutoff ]; then
rm /var/log/httpd/$log
fi
done
It shows how to slice up log filenames containing dates to delete aged logs. date analyzes the internal date format. Safer than just deleting by mtime as it ensures proper rotation day boundaries.
The use cases are endless – from data retention policies to log management and archival workflows. Whenever dates are involved, date can likely help.
Date Conditionals
Check if a specific date has passed:
event_date="2023-12-31"
if $(date --date="$event_date" +%s) -lt $(date +%s); then
echo "$event_date has passed"
else
echo "$event_date has not passed yet!"
fi
By converting to epoch times, easy integer comparisons determine if a target date has elapsed.
date Command Options
We‘ve used date mainly by passing formatted strings or math expressions. But date has its own set of options and arguments to achieve additional functionality:
| Option | Description |
|---|---|
-d, --date=STRING |
Display date/time based on STRING, e.g. now, 3 days. |
-f, --file=DATEFILE |
Like -d but reads DATEFILE line by line. |
-I, --iso-8601[=TIME] |
Format output to ISO 8601 standard. Optionally pick time. |
-r, --reference=FILE |
Display last modified time of FILE. |
-R, --rfc-2822 |
Output date/time per RFC 2822 format. |
-s, --set=STRING |
Set system date/time to STRING. |
-u, --utc, --universal |
Print/set time as UTC. |
And more. Check man date for details. A few neat examples:
$ date -d @0
Thu Jan 1 00:00:00 EST 1970 # Unix epoch start
$ date -d "next day 2PM"
Sun Mar 12 14:00:00 EDT 2023
$ date -I
2023-03-11T14:48:05-05:00
So both human-readable strings and programmatic arguments extend functionality.
Invalid Dates
To check if a string is a valid date, use stderr redirection:
$ date -d "2023-13-35" +%F 2>/dev/null && echo "Valid" || echo "Invalid"
Invalid
-d tries to parse passed string, +%F would format it. But sends errors to null. The && || conditional handles validity test – avoids printing errors.
You could build this into date input validation in scripts.
Recipes and Use Cases
Let‘s explore some specific examples and "recipes" for applying date to solve real problems:
Scheduled Scripts
Run every 30 mins on the 5‘s using cron:
5,35 * * * * myscript.sh
Script starts with:
#!/bin/bash
now_min=$(date +%-M)
if [ $((now_min % 30)) -ne 5 ]; then
exit 0
fi
# Run cron job
Only runs if minute ends in 5 or 35.
File Timestamps
Loop through files, show 3 latest modified:
latest_files=$(ls -lt | head -3 | awk ‘{print $6" "$7" "$8}‘)
for file in $latest_files; do
timestamp=$(date -r $file +"%Y-%m-%d %H:%M")
echo "$file last modified: $timestamp"
done
Calls -r option to show human readable mtime.
User Age from Birthdate
Prompt user DOB:
read -p "Enter birthdate (YYYY-MM-DD): " dob
bday_epoch=$(date -d "$dob" +%s)
now_epoch=$(date +%s)
age_secs=$((now_epoch - bday_epoch))
age_years=$((age_secs / 60 / 60 / 24 / 365))
echo "Age: $age_years years"
Calculates elapsed time from epochs to display age.
ISO 8601 Conversion
Input:
2023-03-01T15:32:17EST
To ISO 8601:
$ date -d "2023-03-01T15:32:17EST" -Iseconds
2023-03-01T20:32:17+00:00
Presto! Adds offset for valid ISO datetime.
These recipes demonstrate date possibilities – from scheduled jobs, file workflows, user input handling, standards conversion, and more. Try applying date across your sysadmin, scripting, and command line usage for robust timestamp and date management.
Key Takeaways
After digesting numerous date usage examples and syntax, what are the key learning points to take with you?
-
Output Customization – Know your formatting strings and build whatever date/time view you need with
%codes. -
Math Tricks – No mental math needed! Manipulate and calculate datetimes with friendly strings.
-
Time Zone Mastery – Set timezone (
TZ) and use UTC (-u) for global interoperability. -
It‘s All About Epochs – Leverage seconds since Unix epoch for portable integer date storage and calculation.
-
Scripting Integration – Handle datetimes in Bash through variables, command substitutions, conditionals and more.
-
Validation Methods – Use stderr redirection to check if date strings are valid before passing to scripts.
Mastering both simple and advanced date functionality takes your command line skills to the next level. Feats that previously required custom scripts or code can now be done right in the shell. So explore all that date has to offer!
When it comes to wrangling date and time data, don‘t forget to have fun and get creative with date as your trusty tool.


