strftime#
Format codes for date / time string formatting. The same codes work
across most languages’ formatters: C strftime, Python
datetime.strftime, Go time.Format (with translation), Java
DateTimeFormatter, Ruby strftime, JS via libraries.
Most-Used Codes#
The codes that appear in nearly every date format string an operator writes. Year / month / day / hour / minute / second plus weekday and timezone, enough to build any of the standard datetime patterns from scratch.
Code |
Example |
Description |
|---|---|---|
|
2026 |
4-digit year |
|
26 |
2-digit year |
|
04 |
month (01-12) |
|
27 |
day of month (01-31) |
|
14 |
hour, 24-hour (00-23) |
|
02 |
hour, 12-hour (01-12) |
|
05 |
minute (00-59) |
|
30 |
second (00-59) |
|
PM |
AM / PM |
|
Mon |
abbreviated weekday |
|
Monday |
full weekday |
|
Apr |
abbreviated month |
|
April |
full month |
|
117 |
day of year (001-366) |
|
1 |
day of week (0=Sunday) |
|
1 |
ISO day of week (1=Monday) |
|
17 |
week of year (Sunday-first) |
|
17 |
week of year (Monday-first) |
|
18 |
ISO week (01-53) |
|
2026 |
ISO week-numbering year |
|
UTC |
time-zone name |
|
+0000 |
time-zone offset |
|
1745765130 |
Unix timestamp (GNU) |
Common Patterns#
The format strings that come up over and over. ISO 8601 / RFC
3339 for new APIs and logs; RFC 2822 for email; the compact
%Y%m%dT%H%M%SZ for filenames you want sorted lexicographically;
%H:%M:%S for time-only displays.
Pattern |
Output |
|---|---|
|
2026-04-27 (ISO date) |
|
2026-04-27T14:05:30 (ISO datetime; no zone) |
|
2026-04-27T14:05:30+0000 (ISO with offset) |
|
2026-04-27 14:05:30 UTC |
|
Mon, 27 Apr 2026 14:05:30 +0000 (RFC 2822 / email) |
|
14:05:30 (time only) |
|
20260427 (compact date; filenames) |
|
20260427T140530Z (compact UTC; filenames) |
|
2026-W18-1 (ISO week date) |
Locale-Sensitive Codes#
The codes whose output changes by machine. Avoid them in logs,
wire formats, and any tool you might run on a system whose locale
you don’t control. %c / %x / %X are the headline
offenders here.
Code |
Example (en_US) |
Description |
|---|---|---|
|
Mon Apr 27 14:05:30 2026 |
locale’s date+time |
|
04/27/26 |
locale’s date |
|
14:05:30 |
locale’s time |
Avoid these in tools / logs / wire formats; the output changes by machine. Use explicit codes.
Less-Common Codes#
The codes that come up rarely but read awkwardly when you don’t
recognize them. %C is “century”; %e / %k / %l are
the space-padded variants of day / hour; %n / %t / %%
are the literal escapes.
Code |
Example |
Description |
|---|---|---|
|
20 |
century |
|
27 |
day-of-month, space-padded (” 1”-“31”) |
|
14 |
hour, 24-h, space-padded |
|
2 |
hour, 12-h, space-padded |
|
(newline) |
literal newline |
|
(tab) |
literal tab |
|
% |
literal percent sign |
GNU Extensions (Linux strftime)#
Extensions GNU added on top of POSIX strftime. %s (epoch
seconds) is the most-used; %F / %T / %R are short
aliases for the most common ISO patterns. None are portable to
non-GNU systems; check before using on macOS or BSD.
Code |
Example |
Description |
|---|---|---|
|
1745765130 |
Unix epoch seconds |
|
123456789 |
nanoseconds (date / GNU coreutils) |
|
pm |
lowercase AM/PM |
|
14:05 |
short form of |
|
14:05:30 |
short form of |
|
2026-04-27 |
short form of |
|
04/27/26 |
short form of |
|
02:05:30 PM |
locale’s 12-hour time |
Practical Snippets#
Working examples in each language an operator is likely to hit.
Bash and Python use familiar strftime codes; JavaScript needs a
library or Intl.DateTimeFormat; Go uses its idiosyncratic
reference-time pattern instead.
Bash / coreutils
$ date
$ date -u
$ date -Iseconds
$ date +%s
$ date +%Y-%m-%dT%H:%M:%SZ -u
$ date +%Y%m%dT%H%M%SZ -u
$ date -d "2026-04-27 14:05" +%s
$ date -j -f "%Y-%m-%d" "2026-04-27" +%s
Python
from datetime import datetime, timezone
datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
# 2026-04-27T14:05:30Z
datetime.strptime("2026-04-27 14:05", "%Y-%m-%d %H:%M")
# ISO format helper
datetime.now(timezone.utc).isoformat()
# 2026-04-27T14:05:30+00:00
JavaScript
JS lacks strftime; use Intl.DateTimeFormat or libraries.
// ISO
new Date().toISOString()
// 2026-04-27T14:05:30.123Z
// Locale-aware
new Intl.DateTimeFormat("en-US", { dateStyle: "medium", timeStyle: "short" })
.format(new Date());
// date-fns / dayjs / luxon for token-based formatting
format(new Date(), "yyyy-MM-dd HH:mm:ss") // date-fns
dayjs().format("YYYY-MM-DD HH:mm:ss") // dayjs
Go
Go uses a reference time instead of strftime codes. Memorize one
example: Mon Jan 2 15:04:05 MST 2006 (or 01/02 03:04:05PM '06
-0700).
import "time"
time.Now().UTC().Format(time.RFC3339)
// 2026-04-27T14:05:30Z
time.Now().Format("2006-01-02 15:04:05")
// 2026-04-27 14:05:30
Common Pitfalls#
The mistakes that break date handling silently in production.
%M vs %m is the most-confused pair; %s and %V /
%G have portability and pairing footguns; locale-sensitive
codes mangle output the moment a script lands on a non-en_US
host.
%M(minute) vs.%m(month), the most-confused pair.%y(2-digit year) is rarely what you want.%Zmay be empty depending on locale / system;%z(offset) is more reliable.%s(epoch seconds) is GNU-only; not in POSIX.%V/%G(ISO week / week-year), use both together; never%Vwith%Y.JS doesn’t have strftime natively; libraries differ in token syntax.
Avoid locale-dependent codes (
%c,%x,%X,%a,%A,%b,%B) in logs and wire formats.
Standards Worth Remembering#
The five datetime standards that operators encounter in the wild. ISO 8601 / RFC 3339 is the modern default for new APIs; the RFC 2822 / 5322 / HTTP-date formats appear in protocol headers; the Unix epoch is the wire format for almost every machine-to- machine timestamp.
ISO 8601,
YYYY-MM-DDTHH:MM:SS±hh:mm(or withZfor UTC).RFC 3339, a profile of ISO 8601 used by JSON / OpenAPI / most web APIs.
RFC 2822 / 5322, email format:
Mon, 27 Apr 2026 14:05:30 -0500.HTTP-date (RFC 9110),
Mon, 27 Apr 2026 14:05:30 GMT.Unix epoch, seconds since 1970-01-01T00:00:00Z.
For new APIs and logs, prefer ISO 8601 / RFC 3339 with explicit time zones.