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.

Similar Posts