date Command in Linux: Format, Parse, and Convert Timestamps

Build reliable Linux timestamps for logs, filenames, scripts, and timezone conversions with date examples that show UTC output, epoch math, file times, parser debugging, and cleanup.

PublishedAuthorJoshua JamesRead time10 minGuide typeLinux Commands

Timestamps become useful only when they are predictable: log names sort correctly, scripts compare the right instant, and timezone output is clear enough to trust later. The date command in Linux prints current time, formats timestamps, parses date strings, converts epoch values, and reads file modification times for shell workflows that need repeatable time handling.

Most Linux systems provide date through GNU Coreutils, but some current systems use compatible uutils builds and minimal images may expose a smaller BusyBox applet. Check the local implementation before relying on GNU-style parsed dates, --debug, --rfc-3339, nanosecond output, or timezone conversion details.

Understand the date Command in Linux

date has two jobs: it displays a time value, or it sets the system clock when used with privileged set-time options. Normal command-line work should treat date as a display and conversion tool. Setting the system clock is a separate administration task that can conflict with NTP, systemd-timesyncd, chrony, or another time synchronization service.

date Command Syntax

date [OPTION]... [+FORMAT]
date [OPTION]... [MMDDhhmm[[CC]YY][.ss]]
  • OPTION changes the time source, timezone handling, parser behavior, or output standard.
  • +FORMAT controls printed output. The plus sign is part of the command syntax, not decoration.
  • The numeric set-time form changes the system clock before printing it. Avoid that form unless you intentionally manage the machine clock.

The GNU Coreutils date documentation covers GNU behavior, including default output, TZ handling, and set-time forms. The uutils date documentation is the matching reference when date --version reports a uutils build.

Verify date Availability and Implementation

Confirm the command path and provider before writing scripts that depend on implementation-specific options:

command -v date
date --version 2>&1 | head -n 1

Example output from a GNU Coreutils system looks like this:

/usr/bin/date
date (GNU coreutils) 9.11

A uutils system reports a line such as date (uutils coreutils) 0.8.0. The everyday examples in this article use Coreutils-style behavior, but exact version banners, parser diagnostics, and edge-case timezone conversions can differ between implementations.

date Command Quick Reference

TaskCommand PatternWhat It Does
Show default date and timedatePrints the current time using the active locale and system timezone.
Print ISO-style datedate +%FOutputs YYYY-MM-DD.
Print time of daydate +%TOutputs HH:MM:SS.
Print Unix epoch secondsdate +%sShows seconds since 1970-01-01 00:00:00 UTC.
Format UTC timedate -u '+%F %T %Z'Prints Coordinated Universal Time instead of local time.
Parse a date stringdate -d '2026-01-15 08:30 UTC' '+%F %T %Z'Displays a supplied date instead of the current instant.
Convert epoch to dateTZ=UTC0 date -d '@1700000000' '+%F %T %Z'Converts an epoch timestamp to a readable UTC date.
Read dates from a filedate -f dates.txt '+%F'Parses one date string per line.
Show file modification timedate -r report.txt '+%F %T'Formats a file’s last modification timestamp.
Use RFC 3339 secondsdate --rfc-3339=secondsPrints a standards-friendly timestamp with timezone offset.
Debug parsingLC_ALL=C TZ=UTC0 date --debug -d '2026-03-31 -1 month' +%FPrints parser notes to standard error on implementations that support it.

Common date Format Specifiers

Use format specifiers after a leading +. Keep scripts to explicit numeric fields when another program will parse the output later.

SpecifierMeaningExample Use
%FFull date as YYYY-MM-DD.date +%F
%TTime as HH:MM:SS.date +%T
%YFour-digit year.date +%Y
%mTwo-digit month.date +%m
%dTwo-digit day of month.date +%d
%HHour in 24-hour format.date +%H
%MMinute.date +%M
%SSecond. Values can include 60 where leap-second handling applies.date +%S
%NNanoseconds.date +%s.%N
%sUnix epoch seconds.date +%s
%zNumeric timezone offset such as -0500.date +%z
%:zNumeric timezone offset with a colon, such as -05:00.date +%:z
%ZTimezone abbreviation.date +%Z
%%Literal percent sign.date '+%%Y means %Y'

Set Up date Practice Files

A disposable directory keeps file timestamp and script examples away from real logs or backups:

mkdir -p ~/date-demo/logs
cd ~/date-demo

printf 'report generated\n' > report.txt
TZ=UTC0 touch -d '2026-01-15 08:30:00 UTC' report.txt

cat > dates.txt <<'EOF'
2026-01-15 08:30:00 UTC
2026-06-18 12:00:00 UTC
@1700000000
EOF

The setup uses the printf command in Linux for predictable fixture content and touch to assign a known file modification time.

Format Current Date and Time with date

Display the Current Date and Time

A plain date command prints the current system time using the current locale and timezone:

date

The exact output changes with the clock, locale, and timezone. Use explicit formats for scripts, logs, filenames, and documentation so downstream commands do not have to parse locale-specific text.

Print a Sortable Calendar Date

Use %F when you need a compact ISO-style date that sorts correctly as text:

TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' +%F
2026-01-15

This format is better for filenames and CSV fields than locale formats such as 01/15/26, which can be ambiguous across regions.

Print a Full Timestamp for Logs

Combine date, time, and timezone fields when a log line must be readable after it moves between systems:

TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' '+%F %T %Z %z'
2026-01-15 08:30:00 UTC +0000

For machine-readable logs, prefer numeric offsets such as %z or fixed UTC. Timezone abbreviations like CST can mean different zones in different regions.

Print Unix Epoch Seconds

Epoch seconds are useful for arithmetic because they turn an instant into a single integer:

TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' +%s
1768465800

Epoch values are always anchored to UTC. Format them for display only at the edge of a script, after the calculation or comparison is complete.

Print RFC 3339 and ISO 8601 Timestamps

Use --rfc-3339=seconds when a log, API payload, or report wants a readable timestamp with an offset:

TZ=UTC0 date --rfc-3339=seconds -d '2026-01-15 08:30:00 UTC'
2026-01-15 08:30:00+00:00

Use -Iseconds or --iso-8601=seconds when the timestamp should use a T separator:

TZ=UTC0 date -Iseconds -d '2026-01-15 08:30:00 UTC'
2026-01-15T08:30:00+00:00

Both forms are clearer than assembling your own separator rules unless the receiving tool requires a custom timestamp shape.

Build Timestamped Filenames

Use numeric fields without spaces or colons for filenames that need to sort in chronological order:

stamp=$(TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' '+%Y%m%d-%H%M%S')
printf 'backup file: app-%s.tar.gz\n' "$stamp"
backup file: app-20260115-083000.tar.gz

Avoid slashes and spaces inside generated filenames unless the surrounding script quotes every expansion and the destination format expects them.

Parse and Convert Dates with date

Parse a Specific Date String

Use -d or --date to display a supplied date instead of the current instant. Include a timezone in examples and scripts so the result does not depend on the machine’s local zone:

TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' '+%A, %F %T %Z'
Thursday, 2026-01-15 08:30:00 UTC

The GNU date input format documentation shows how GNU Coreutils parses calendar dates, times, timezones, relative items, and epoch values. Treat that parser as convenient, not as a replacement for strict input validation in scripts.

Convert an Offset Timestamp to UTC

Log files and API payloads often carry numeric offsets instead of timezone names. Parse the offset-bearing timestamp, then format the result in UTC for comparison or storage:

TZ=UTC0 date -d '2026-01-15 08:30:00 -0500' '+%F %T %Z'
2026-01-15 13:30:00 UTC

Numeric offsets are less ambiguous than abbreviations such as EST or CST. Keep the original offset in raw logs when auditability matters, but normalize to UTC before sorting or comparing events from multiple systems.

Use Relative Date Strings

Relative items make quick terminal checks readable. Use them for interactive work, and pin important scripts to explicit dates when the exact result matters:

TZ=UTC0 date -d '2026-01-15 08:30:00 UTC + 2 days' +%F
TZ=UTC0 date -d '2026-01-15 08:30:00 UTC - 1 week' +%F
2026-01-17
2026-01-08

The GNU relative date documentation notes that relative items accumulate and that months and years are fuzzy units. Prefer days, hours, minutes, seconds, or epoch arithmetic when a boundary must be exact.

Convert Epoch Seconds to a Date

Prefix an epoch value with @ to convert it back to a formatted date. Set TZ=UTC0 when the output should be stable across machines:

TZ=UTC0 date -d '@1700000000' '+%F %T %Z'
2023-11-14 22:13:20 UTC

Use the same input with another timezone when the question is local wall-clock time for that instant:

TZ=America/New_York date -d '@1700000000' '+%F %T %Z %z'
2023-11-14 17:13:20 EST -0500

Convert a Date to Epoch Seconds

Print %s after parsing a date string when a script needs integer comparison or subtraction:

start_epoch=$(TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' +%s)
end_epoch=$(TZ=UTC0 date -d '2026-01-15 10:00:00 UTC' +%s)

printf 'duration_seconds=%s\n' "$((end_epoch - start_epoch))"
duration_seconds=5400

Epoch arithmetic is safer than subtracting formatted fields by hand. Convert to seconds first, calculate, then format the final value if humans need to read it.

Read Multiple Date Strings from a File

Use -f or --file when a file contains one date string per line. The output format applies to every parsed line:

TZ=UTC0 date -f dates.txt '+%F %T %Z'
2026-01-15 08:30:00 UTC
2026-06-18 12:00:00 UTC
2023-11-14 22:13:20 UTC

This is cleaner than looping over a small date list in the shell. Validate the input file first when blank lines, comments, or user-supplied values can appear.

Work with Time Zones and UTC

Display Current Time in UTC

Add -u, --utc, or --universal when you want UTC output from the current clock:

date -u '+%F %T %Z %z'

For scripts, an explicit TZ=UTC0 prefix makes UTC handling visible and keeps calendar arithmetic away from local daylight saving transitions.

Display Time in Another Timezone

Set TZ for one command when you need a different timezone without changing the system configuration:

TZ=America/New_York date -d '@1700000000' '+%F %T %Z %z'
2023-11-14 17:13:20 EST -0500

Use IANA timezone names from /usr/share/zoneinfo, such as America/New_York, Europe/London, or Australia/Perth. Avoid abbreviations in input because values such as IST, CST, and BST are ambiguous.

When a parsed date string already contains a timezone, avoid using TZ=Zone date -d '... UTC' as a portable conversion shortcut. GNU Coreutils converts that instant through the requested TZ value, while uutils 0.8.0 can keep the embedded UTC value in the output. Epoch input such as @1700000000, or a numeric offset parsed directly to UTC, is the more predictable conversion boundary.

Avoid Daylight Saving Surprises

Calendar arithmetic can cross daylight saving changes or invalid local times. Use UTC for duration calculations and convert back to local time only for display:

start=$(TZ=UTC0 date -d '2026-03-08 06:30:00 UTC' +%s)
end=$(TZ=UTC0 date -d '2026-03-08 08:30:00 UTC' +%s)
printf 'elapsed_hours=%s\n' "$(((end - start) / 3600))"
elapsed_hours=2

This avoids asking the local timezone parser to decide what a skipped or repeated wall-clock hour means during a clock change.

Use date with Files and Shell Scripts

Show a File’s Modification Time

Use -r or --reference to display a file’s modification time through the same format rules as any other date output:

TZ=UTC0 date -r report.txt '+%F %T %Z'
2026-01-15 08:30:00 UTC

Use touch command examples when you need to change the timestamp. Use date -r when you only need to read and format it.

Add a Timestamp to a Log Line

Command substitution is useful when a script needs to include the current timestamp beside a message:

printf '[%s] %s\n' "$(TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' '+%F %T %Z')" 'backup finished'
[2026-01-15 08:30:00 UTC] backup finished

For real scripts, remove the fixed -d input so date uses the current clock. Keep the surrounding TZ=UTC0 and format string if the log should stay in UTC.

Create Daily Log Files

Use a date stamp in a filename when logs, reports, or backups should group by day:

log_file="logs/app-$(TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' +%F).log"
printf 'log_file=%s\n' "$log_file"
log_file=logs/app-2026-01-15.log

Use %F for daily files and %Y%m%d-%H%M%S for files that can be created more than once per day. Quote the variable later because filenames still live in shell syntax.

Compare Dates in a Shell Script

Compare epoch seconds, not formatted strings, when a script needs to choose a branch:

deadline=$(TZ=UTC0 date -d '2026-01-15 09:00:00 UTC' +%s)
current=$(TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' +%s)

if (( current < deadline )); then
    printf 'before deadline\n'
else
    printf 'deadline reached\n'
fi
before deadline

The comparison stays numeric and timezone-neutral. Format dates for people after the branch decision, not before it.

Debug and Validate date Parsing

Debug Questionable Date Strings

--debug helps reveal how the parser understood a date string. This is useful when relative month arithmetic gives a surprising result:

LC_ALL=C TZ=UTC0 date --debug -d '2026-03-31 -1 month' +%F

Relevant output on GNU Coreutils includes a normalized date and the final formatted result:

date:    normalized Y M D: 2026 03 03
2026-03-03

That result is not a typo. Subtracting one month from March 31 can normalize through an invalid February 31. Some implementations print fewer debug notes than GNU Coreutils, so treat the final formatted result as the portable part. Anchor month calculations near the middle of the month when the goal is a month label rather than an exact elapsed duration.

TZ=UTC0 date -d '2026-03-15 -1 month' +%F
2026-02-15

Keep Locale Output Stable

Locale affects names such as weekdays and months. Set LC_ALL=C when a script or example needs stable English diagnostics, then use numeric fields for data that another command will parse:

LC_ALL=C TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' '+%a %b %d %F'
Thu Jan 15 2026-01-15

Human-facing labels can stay localized. Script-facing values should usually use numeric, fixed-width formats such as %F, %T, and %s.

Use date Safely

Do Not Use date as a Clock Fix by Default

date -s and numeric set-time operands can change the system clock when run with enough privilege. On modern Linux systems, clock policy usually belongs to timedatectl, NTP, chrony, systemd-timesyncd, or the virtualization host. For ordinary troubleshooting, inspect synchronization state first instead of forcing a new wall-clock value with date.

timedatectl status

If the system clock is wrong, fix the synchronization source, timezone, guest clock, or host time policy that owns it. When a systemd time service is involved, use systemctl command examples to inspect the owning unit instead of changing the clock with date. Manual clock setting can break logs, TLS validation, Kerberos, package repositories, build systems, and scheduled jobs.

Keep Timezone Changes Per Command

Use a one-command TZ=... prefix for examples and scripts that need a specific timezone. Avoid exporting TZ broadly in a shell session unless every later command should inherit it.

TZ=UTC0 date +%F
date +%F

The first command uses UTC only for that invocation. The second command returns to the shell’s normal timezone environment.

Troubleshoot Common date Errors

Fix Unparseable Date Strings

invalid date means the parser could not understand the supplied string. This command is intentionally invalid so you can recognize the failure:

LC_ALL=C date -d 'not-a-date' +%F
date: invalid date 'not-a-date'

Use an unambiguous date string with a timezone, then verify the parsed value:

TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' '+%F %T %Z'
2026-01-15 08:30:00 UTC

For user input, validate with a stricter parser in the language that owns the application. GNU-style free-form parsing is convenient for terminal work but too forgiving for many data pipelines.

Fix Missing Plus Signs in Format Strings

A format string must start with +. Without it, date treats the argument as a date string or set-time operand, so this intentionally incorrect command fails:

LC_ALL=C date '%F'
date: invalid date '%F'

Add the plus sign before the format:

TZ=UTC0 date -d '2026-01-15 08:30:00 UTC' +%F
2026-01-15

Check Unexpected Timezone Output

First prove the command is seeing the timezone you intended:

TZ=America/New_York date '+%Z %z'
date --version 2>&1 | head -n 1

If the timezone name is invalid, misspelled, or missing from the local timezone database, choose a valid IANA name from /usr/share/zoneinfo. If the implementation line reports uutils or BusyBox, check local help before assuming every GNU parser edge case is available.

Handle Permission Errors When Setting Time

Setting the system clock requires elevated privileges and can be blocked by synchronization policy. If a set-time command fails, do not work around it by adding broad privilege or disabling time sync blindly. Inspect the system time state first:

timedatectl status

On desktops, servers, and virtual machines, the correct fix is often timezone configuration, NTP reachability, guest clock synchronization, or host time correction rather than manual date -s.

Recover from Month Arithmetic Surprises

Month and year arithmetic is not the same as fixed-duration arithmetic because months have different lengths. Diagnose the exact expression under UTC when the result matters:

LC_ALL=C TZ=UTC0 date --debug -d '2026-03-31 -1 month' +%F

If the goal is “same day last month,” decide what should happen when the previous month has fewer days. If the goal is “previous month label,” anchor near the middle of the month instead:

TZ=UTC0 date -d '2026-03-15 -1 month' '+%B %Y'
February 2026

Clean Up the date Practice Directory

Remove the disposable files after finishing the examples:

cd ~
rm -rf -- ~/date-demo

The cleanup command targets only the practice directory created for this article.

Conclusion

date is ready for formatted timestamps, UTC output, epoch conversion, file modification checks, and script comparisons. Keep machine-facing output numeric and timezone-explicit, use epoch seconds for arithmetic, and check the local implementation before trusting parser diagnostics or timezone edge cases.

Share this guide

Help another Linux user troubleshoot faster

Share this guide with someone troubleshooting Linux systems or saving it for later.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show more of our fresh Linux tutorials in Top Stories and From your sources when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee
Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<a href="https://example.com">link</a> link
<blockquote>quote</blockquote> quote block

Got a Question or Feedback?

We read and reply to every comment - let us know how we can help or improve this guide.

Verify before posting: