Dates and Times
date followed by + and a pattern prints a date in the shape you need, such as date +%F for 2026-11-09; date -d works out other days, such as 7 days ago; date +%s counts seconds, for timing a job; and a Mac's date uses -v instead of -d.
Journeyman · Unix · Linux · Updated
After this lesson you can
- Print a date in the format you need with date +%F and other % codes, and put it in a file name
- Work out other dates with date -d, such as 7 days ago, and time a job with date +%s
Key takeaways
- date +%F prints the date as year-month-day, which also sorts in date order. %Y, %m, %d, %A and %B give its parts.
- "notes-$(date +%F).txt" puts the date in a file name, so every day gets its own file.
- date -d '7 days ago' +%F works out another day. -d understands yesterday, next friday and a date such as 2026-12-24.
- A Mac's date has no -d: date -v-7d +%F is a week ago there. Or install coreutils with Homebrew and use gdate.
- date +%s is the number of seconds since 1970. Take one reading from another to time a job.
A weather report should say which day it's for. A notes file you save every evening needs a name that says which evening. A cleanup script should delete only the backups more than a week old. Each of those starts with "what's the date?", and a script has to ask the computer, because nobody is there to type it. Administrators put the date on every backup and log they make, and data analysts on every export. Values from Commands: $( ) and $(( )) met date +%F; this lesson goes further: other shapes, other days, and counting seconds.
Today, in the shape you need
date, then + and a pattern, prints the parts of the date you ask for. Each % and a letter (read "percent F" and so on) stands for one part, and everything else is printed as written. A pattern with spaces goes in quotes:
date +%F
date '+%A, %B %d, %Y'
date +%d/%m/%Y
2026-11-09
Monday, November 09, 2026
09/11/2026
Yours will show the day you run it. These codes cover most jobs:
| Code | Means | Example |
|---|---|---|
%F |
the full date, the same as %Y-%m-%d |
2026-11-09 |
%Y |
the year | 2026 |
%m |
the month's number | 11 |
%d |
the day of the month | 09 |
%A |
the day's name | Monday |
%B |
the month's name | November |
%H, %M, %S |
the hour (00 to 23), the minute and the second | 07, 45, 00 |
%F is the one to choose for anything a computer sorts. Year first, then month, then day means that sorting the dates as text puts them in date order, which is why it's the international standard way to write a date (ISO 8601).
A date in a file name
$( ) puts the output of date into another command. These lines save tonight's notes under today's date:
mkdir -p ~/terminal-practice/dates && cd ~/terminal-practice/dates
echo "Fixed the bike's back tire" > notes.txt
cp notes.txt "notes-$(date +%F).txt"
ls
notes-2026-11-09.txt notes.txt
Run the cp line again tomorrow and you get a second dated file, instead of replacing this one. For a job that runs more than once a day, add the hour and minute, date +%F_%H%M, for names such as notes-2026-11-09_0745.txt.
Other days: date -d
-d (read "date of") tells date which day to describe, in plain words or as a date:
date -d yesterday +%F
date -d '7 days ago' +%F
date -d 'next friday' +%F
date -d 2026-12-24 +%A
2026-11-08
2026-11-02
2026-11-13
Thursday
It also understands tomorrow, 3 months ago, 2 weeks (from today) and '2026-12-24 + 7 days'. A phrase it can't read stops with an invalid date error. Ubuntu 26.04's date is a newer rewrite of the classic tool: it understands the same phrases, though a message can be worded a little differently on other Linux systems.
On a Mac, date has no -d. Its -v moves the date instead: date -v-7d +%F is a week ago, and date -v+1d +%A is tomorrow's name. Or install Homebrew's coreutils (brew install coreutils) and use gdate, which works exactly as this lesson shows. The + patterns are the same on both.
Dates written as %F compare correctly as text, so a cleanup script can ask whether a dated file is more than a week old. Inside [[ ]], < (read "comes before") compares text:
cutoff=$(date -d '7 days ago' +%F)
[[ 2026-10-30 < $cutoff ]] && echo "2026-10-30 is more than a week ago"
2026-10-30 is more than a week ago
Outside [[ ]], < still means "from a file", so keep this test inside the double brackets.
Seconds since 1970: timing a job
Computers keep time as one big number: the seconds since the first moment of 1970. It's called Unix time, or a timestamp, and date +%s prints it. It's hard to read, but arithmetic works on it directly, so it's how a script times itself:
start=$(date +%s)
sleep 3
end=$(date +%s)
echo "That took $((end - start)) seconds"
That took 3 seconds
sleep 3 waits three seconds and stands in for a real job, such as a backup. The clock counts whole seconds, so now and then you'll see 4. A backup script can write that line to its log every night, and the day it says 400 instead of 40, you know to look.
Check yourself
2 questions to try on the lesson page.
So what
A date in a file name, today's date at the top of a report, "older than a week" and "how long did that take" are each one date command away: the pieces every scheduled script needs.