Shell Scripting
Date Format
Programming
Coding Tutorials
YYYY-MM-DD Format

YYYY-MM-DD format date in shell script

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

To get the current date in YYYY-MM-DD format in a shell script, use date +%Y-%m-%d. This works on Linux (GNU coreutils) and macOS (BSD) and produces output like 2026-06-18. The format string %Y gives the four-digit year, %m the zero-padded month, and %d the zero-padded day.

Basic Usage

Assign the formatted date to a variable and use it in your script:

bash
1#!/bin/bash
2
3today=$(date +%Y-%m-%d)
4echo "Today is $today"

Output:

 
Today is 2026-06-18

The $(...) syntax runs the date command in a subshell and captures its output. No quotes are needed around the format string as long as it contains no spaces, but quoting is a good defensive habit:

bash
today=$(date "+%Y-%m-%d")

Common Date Format Variations

The date command supports many format specifiers. Here are the most useful combinations:

Format StringExample OutputDescription
+%Y-%m-%d2026-06-18ISO 8601 date
+%Y%m%d20260618Compact date (good for filenames)
+%Y-%m-%d_%H-%M-%S2026-06-18_14-30-00Date and time (filename-safe)
+%Y-%m-%dT%H:%M:%S%z2026-06-18T14:30:00+0000ISO 8601 with timezone
+%s1781856600Unix timestamp (seconds since epoch)
+%A, %B %d, %YThursday, June 18, 2026Human-readable long format
+%d/%m/%Y18/06/2026European date format

Date Arithmetic

GNU date (Linux)

GNU date supports the -d (or --date) option for date arithmetic:

bash
1# Yesterday
2yesterday=$(date -d "yesterday" +%Y-%m-%d)
3
4# Tomorrow
5tomorrow=$(date -d "tomorrow" +%Y-%m-%d)
6
7# 7 days ago
8week_ago=$(date -d "7 days ago" +%Y-%m-%d)
9
10# 30 days from now
11future=$(date -d "+30 days" +%Y-%m-%d)
12
13# First day of current month
14first_of_month=$(date -d "$(date +%Y-%m-01)" +%Y-%m-%d)
15
16# Last day of previous month
17last_of_prev_month=$(date -d "$(date +%Y-%m-01) -1 day" +%Y-%m-%d)

BSD date (macOS)

macOS uses BSD date, which has a different syntax for date arithmetic:

bash
1# Yesterday
2yesterday=$(date -v-1d +%Y-%m-%d)
3
4# Tomorrow
5tomorrow=$(date -v+1d +%Y-%m-%d)
6
7# 7 days ago
8week_ago=$(date -v-7d +%Y-%m-%d)
9
10# 30 days from now
11future=$(date -v+30d +%Y-%m-%d)
12
13# First day of current month
14first_of_month=$(date -v1d +%Y-%m-%d)

Cross-Platform Date Arithmetic

If your script needs to run on both Linux and macOS, detect the platform:

bash
1#!/bin/bash
2
3get_date_offset() {
4    local days=$1
5    if date --version >/dev/null 2>&1; then
6        # GNU date (Linux)
7        date -d "$days days" +%Y-%m-%d
8    else
9        # BSD date (macOS)
10        date -v"${days}d" +%Y-%m-%d
11    fi
12}
13
14yesterday=$(get_date_offset -1)
15tomorrow=$(get_date_offset +1)
16echo "Yesterday: $yesterday"
17echo "Tomorrow: $tomorrow"

Practical Script Examples

Log Rotation with Date Stamps

bash
1#!/bin/bash
2
3log_dir="/var/log/myapp"
4today=$(date +%Y-%m-%d)
5archive_dir="$log_dir/archive"
6
7mkdir -p "$archive_dir"
8
9# Rotate current log
10if [ -f "$log_dir/app.log" ]; then
11    mv "$log_dir/app.log" "$archive_dir/app-$today.log"
12    gzip "$archive_dir/app-$today.log"
13fi
14
15# Delete archives older than 90 days
16find "$archive_dir" -name "*.gz" -mtime +90 -delete

Timestamped Backup Script

bash
1#!/bin/bash
2
3timestamp=$(date +%Y-%m-%d_%H-%M-%S)
4backup_dir="/backups/$timestamp"
5
6mkdir -p "$backup_dir"
7pg_dump mydb > "$backup_dir/mydb.sql"
8tar czf "$backup_dir/config.tar.gz" /etc/myapp/
9
10echo "Backup completed: $backup_dir"

Date Range Loop

Iterate over a range of dates (GNU date):

bash
1#!/bin/bash
2
3start_date="2026-06-01"
4end_date="2026-06-18"
5
6current="$start_date"
7while [[ "$current" < "$end_date" || "$current" == "$end_date" ]]; do
8    echo "Processing $current"
9    # Your logic here
10    current=$(date -d "$current +1 day" +%Y-%m-%d)
11done

Comparing Dates

Compare dates as strings since YYYY-MM-DD format sorts lexicographically:

bash
1#!/bin/bash
2
3today=$(date +%Y-%m-%d)
4deadline="2026-12-31"
5
6if [[ "$today" > "$deadline" ]]; then
7    echo "Deadline has passed"
8elif [[ "$today" == "$deadline" ]]; then
9    echo "Deadline is today"
10else
11    echo "Deadline is in the future"
12fi

This works because the YYYY-MM-DD format preserves chronological order in string comparison. Formats like MM/DD/YYYY do not have this property.

UTC vs. Local Time

By default, date uses the system's local timezone. For consistent results across servers in different timezones, use UTC:

bash
1# UTC date
2utc_today=$(date -u +%Y-%m-%d)
3
4# Or set TZ explicitly
5eastern=$(TZ="America/New_York" date +%Y-%m-%d)
6tokyo=$(TZ="Asia/Tokyo" date +%Y-%m-%d)

Using UTC is especially important in cron jobs and distributed systems where servers may be in different timezones.

Format Specifier Reference

SpecifierMeaningExample
%YFour-digit year2026
%yTwo-digit year26
%mMonth (01-12)06
%dDay of month (01-31)18
%HHour, 24-hour (00-23)14
%MMinute (00-59)30
%SSecond (00-59)45
%sUnix timestamp1781856600
%ZTimezone abbreviationUTC
%zTimezone offset+0000
%AFull weekday nameThursday
%aAbbreviated weekdayThu
%BFull month nameJune
%bAbbreviated monthJun
%jDay of year (001-366)169
%uDay of week (1=Mon, 7=Sun)4

Common Pitfalls

Confusing %m with %M. %m is the month, %M is the minute. Writing date +%Y-%M-%d gives you the minute in the month position, producing nonsensical dates like 2026-30-18.

Using uppercase %D. The %D specifier produces MM/DD/YY (American short format), not YYYY-MM-DD. This is a common source of confusion.

Forgetting the + before the format string. Writing date %Y-%m-%d without the + causes date to try to parse it as a date string, not as a format specifier.

Assuming GNU date on macOS. macOS ships with BSD date, which does not support -d. Use -v for date arithmetic on macOS, or install GNU coreutils via Homebrew (gdate).

Using backticks instead of $(...). While backticks work, they do not nest cleanly and are harder to read. The $(...) syntax is the modern standard:

bash
1# Avoid
2today=`date +%Y-%m-%d`
3
4# Prefer
5today=$(date +%Y-%m-%d)

Not quoting variables in comparisons. If the date variable is empty for any reason, an unquoted comparison like [ $today = $deadline ] will produce a syntax error. Always use double brackets or quote the variables: [[ "$today" == "$deadline" ]].

Summary

Use date +%Y-%m-%d to get the current date in ISO 8601 format in any shell script. For date arithmetic, use -d on Linux (GNU) or -v on macOS (BSD). The YYYY-MM-DD format is ideal for filenames, logs, and date comparisons because it sorts chronologically as a plain string. Use UTC (date -u) for consistent results across timezones. Watch out for the %m vs. %M confusion, and remember that macOS and Linux have different date command syntax for offsets.


Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions