Strftime / Format Cheat Sheet
Every strftime token with an engine-rendered example, portability columns and a live format preview — entirely on this device.
- Sample — 2026-03-08 15:26:05 UTC
2026-03-08 15:26:05- Now — this device's clock
—
The now row renders from this device's clock when the page loads or you type — it does not tick.
Rendering is pinned to the C/POSIX locale and UTC: English day and month names, %Z prints UTC, %z prints +0000.
%YYear with century%mMonth (01–12)%dDay of month, zero-padded (01–31)%HHour, 24-hour clock (00–23)%MMinute (00–59)%SSecond (00–60)
All 38 tokens shown
Date
| Token | Meaning | Example | Portability | Copy |
|---|---|---|---|---|
%a | Abbreviated weekday name | Sun | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%A | Full weekday name | Sunday | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%b | Abbreviated month name | Mar | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%B | Full month name | March | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%C | Century (year / 100, 00–99) | 20 | C99 · POSIX · GNU/glibc · BSD/macOS | |
%d | Day of month, zero-padded (01–31) | 08 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%e | Day of month, space-padded ( 1–31) | 8 | C99 · POSIX · GNU/glibc · BSD/macOS | |
%h | Abbreviated month name, same as %b | Mar | C99 · POSIX · GNU/glibc · BSD/macOS | |
%j | Day of year (001–366) | 067 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%m | Month (01–12) | 03 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%y | Year without century (00–99) | 26 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%Y | Year with century | 2026 | C99 · POSIX · GNU/glibc · BSD/macOS · Python |
Time
| Token | Meaning | Example | Portability | Copy |
|---|---|---|---|---|
%H | Hour, 24-hour clock (00–23) | 15 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%I | Hour, 12-hour clock (01–12) | 03 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%M | Minute (00–59) | 26 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%p | AM or PM | PM | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%S | Second (00–60) | 05 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%s | Seconds since the Unix epoch | 1772983565 | POSIX · GNU/glibc · BSD/macOS |
Week numbering
| Token | Meaning | Example | Portability | Copy |
|---|---|---|---|---|
%g | ISO week-numbering year, last two digits (00–99) | 26 | C99 · POSIX · GNU/glibc · BSD/macOS | |
%G | ISO week-numbering year | 2026 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%u | ISO weekday (1–7, Monday is 1) | 7 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%U | Week of year, Sunday first (00–53) | 10 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%V | ISO 8601 week number (01–53) | 10 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%w | Weekday number (0–6, Sunday is 0) | 0 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%W | Week of year, Monday first (00–53) | 09 | C99 · POSIX · GNU/glibc · BSD/macOS · Python |
Time zone
Composite formats
| Token | Meaning | Example | Portability | Copy |
|---|---|---|---|---|
%c | Date and time, same as %a %b %e %H:%M:%S %Y | Sun Mar 8 15:26:05 2026 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%D | US date, same as %m/%d/%y | 03/08/26 | C99 · POSIX · GNU/glibc · BSD/macOS | |
%F | Full date, same as %Y-%m-%d | 2026-03-08 | C99 · POSIX · GNU/glibc · BSD/macOS | |
%r | 12-hour clock time, same as %I:%M:%S %p | 03:26:05 PM | C99 · POSIX · GNU/glibc · BSD/macOS | |
%R | 24-hour time, same as %H:%M | 15:26 | C99 · POSIX · GNU/glibc · BSD/macOS | |
%T | 24-hour time, same as %H:%M:%S | 15:26:05 | C99 · POSIX · GNU/glibc · BSD/macOS | |
%x | Date, C locale renders %m/%d/%y | 03/08/26 | C99 · POSIX · GNU/glibc · BSD/macOS · Python | |
%X | Time, C locale renders %H:%M:%S | 15:26:05 | C99 · POSIX · GNU/glibc · BSD/macOS · Python |
Literals & whitespace
Padding flags (%-d, %_d, %0d) are glibc and BSD/macOS extensions; case and width flags (%^a, %#a, %12F) are glibc-only — plain C99 strftime defines none of them.
Language notes
Python
%CWorks where the platform strftime provides it; not in Python's documented portable set.%dFor an unpadded day of month, Linux and macOS accept "%-d"; Windows spells it "%#d".%ePlatform-dependent in CPython — missing on Windows.%FNot documented on Windows — date.isoformat() prints the same text portably.%GPython 3.6+. Pairs with %V and %u — it is not interchangeable with %Y.%TNot portable to Windows — spell it %H:%M:%S.%uPython 3.6+.%VPython 3.6+. Combine with %G — mixing %V with %Y is the classic week-year logging bug.%zAware datetimes only — naive ones render an empty string. Python 3.12+ also accepts %:z.%ZAware datetimes render tzname(); naive ones render an empty string.%sUnix-only in CPython; int(dt.timestamp()) is the portable spelling.
Ruby
%eRuby implements its own strftime, so %e works everywhere, including Windows.%pRuby adds %P for lowercase am/pm.%SRuby adds %L (milliseconds) and %N (fractional seconds) — C strftime has no sub-second conversion.
PHP
%YPHP: date("Y") — PHP's own strftime() is deprecated since 8.1.
C
%cIn the C locale this renders exactly %a %b %e %H:%M:%S %Y.%DTwo-digit year and month-first order — %F is the unambiguous spelling.%hIdentical to %b in every locale.%nC99 defines strftime's %n as a plain newline — unrelated to printf's %n.%rC locale: %I:%M:%S %p.%SThe range reaches 60 for leap seconds; Unix-time instants never render one.%UDays before the first Sunday of the year fall in week 00.%xC locale: %m/%d/%y.%XC locale: %H:%M:%S.%sNot in C99. POSIX.1-2024 standardizes what glibc and the BSDs shipped for years.
Go, Java and JavaScript equivalents
| Token | Go | Java | Moment.js | Day.js | date-fns | Luxon | Note |
|---|---|---|---|---|---|---|---|
%Y | 2006 | yyyy | YYYY | YYYY | yyyy | yyyy | |
%y | 06 | yy | YY | YY | yy | yy | |
%m | 01 | MM | MM | MM | MM | MM | |
%b | Jan | MMM | MMM | MMM | MMM | MMM | |
%B | January | MMMM | MMMM | MMMM | MMMM | MMMM | |
%d | 02 | dd | DD | DD | dd | dd | |
%e | _2 | d | D | D | d | — | Only Go's "_2" keeps %e's space padding — the others (and luxon "d", omitted from the exact column) print "8". |
%a | Mon | EEE | ddd | ddd | EEE | ccc | |
%A | Monday | EEEE | dddd | dddd | EEEE | cccc | |
%H | 15 | HH | HH | HH | HH | HH | |
%I | 03 | hh | hh | hh | hh | hh | |
%p | PM | a | A | A | a | a | |
%M | 04 | mm | mm | mm | mm | mm | |
%S | 05 | ss | ss | ss | ss | ss | |
%j | 002 | DDD | DDDD | — | DDD | ooo | dayjs needs the dayOfYear plugin (no zero-padded token); date-fns DDD requires useAdditionalDayOfYearTokens. |
%G | — | YYYY | GGGG | — | RRRR | kkkk | Go has no week-year layout (time.Time.ISOWeek returns it); Java's YYYY is locale week-based — use IsoFields.WEEK_BASED_YEAR for strict ISO. |
%V | — | ww | WW | — | II | WW | Go: ISOWeek(); dayjs: isoWeek plugin. Java's ww is locale week numbering — ISO only where the locale's week rules are ISO. |
%u | — | — | E | — | i | E | Go: Weekday() counts Sunday as 0; Java's e/c are locale-relative. |
%z | -0700 | xx | ZZ | ZZ | xx | ZZZ | |
%Z | MST | zzz | — | — | — | ZZZZ | moment/dayjs need the timezone plugin's z token; date-fns needs date-fns-tz. |
%F | 2006-01-02 | yyyy-MM-dd | YYYY-MM-DD | YYYY-MM-DD | yyyy-MM-dd | yyyy-MM-dd | |
%T | 15:04:05 | HH:mm:ss | HH:mm:ss | HH:mm:ss | HH:mm:ss | HH:mm:ss | |
%R | 15:04 | HH:mm | HH:mm | HH:mm | HH:mm | HH:mm | |
%D | 01/02/06 | MM/dd/yy | MM/DD/YY | MM/DD/YY | MM/dd/yy | MM/dd/yy | |
%s | — | — | X | X | t | X | Go: Unix(); Java: Instant.getEpochSecond(). |
No token matches that filter. Every documented code is in the tables below — try a shorter word like week or zone, or press Show all tokens.
Do it offline:$ date +"%Y-%m-%d %H:%M:%S"
How to use it
- Scan the token tables — grouped date, time, week, zone, composite and literal — where every example column shows real engine output, so what you read is what prints.
- Narrow with the filter: a token like %V, or plain words like week or am pm. Sections collapse to the matching rows; / focuses the box.
- Type a whole format in the preview to see the frozen sample instant and your device's clock rendered side by side, with a breakdown of what each token contributed.
- Copy what you need — the rendered output, or any single token from its table row — and check its portability columns before it lands in a script.
Every strftime conversion is on this page as plain HTML, each with the exact bytes it prints — rendered by the same engine that powers the preview, at one frozen instant, in the C locale and UTC. Filter by token or plain words, check the portability columns before a format ships, and paste your own format to watch it render token by token. Nothing you type leaves this page.
How it works
strftime walks the format string once, left to right. Ordinary characters are copied through unchanged; a % begins a conversion, and the character closing it selects what to print — %d the day, %H the hour, %% a literal percent sign. That is the whole dispatch model. What C99 does not define is a % followed by anything undocumented: glibc keeps the unrecognized text verbatim, and this page does the same while saying so.
Half the table is locale-dependent. %a, %A, %b, %B and %p print words from the active locale's tables, and %c, %x, %X and %r expand to whole locale-preferred layouts, so one format can emit different bytes on two differently configured machines. This page pins the C/POSIX locale and UTC, making every example one reproducible string — and the preview raises an honest note whenever your format touches a locale or zone token.
Between the % and the conversion letter, glibc accepts flags: - drops padding, _ pads with spaces, 0 pads with zeros, ^ upper-cases, # switches to the opposite case, and a decimal width sets a minimum field size. So %-d prints 8 where %d prints 08. The BSDs ship only the three padding flags — feed macOS %^a and it prints ^a, not SUN. None of it is C99, which is why the preview attaches an extensions note the moment a flag renders.
The week tokens hide the classic strftime bug. %V numbers weeks the ISO 8601 way, and the days around New Year can belong to a week of the neighbouring year — so pairing %V with %Y stamps some dates with a year that is simply wrong. %G exists precisely for this: it prints the year the ISO week belongs to. Build week labels from %G-W%V, never from %Y-W%V.
The portability columns are read from primary sources, not folklore: C99's strftime section, the POSIX.1-2024 specification, the glibc and BSD manual pages, and CPython's documented format-code list. The Python column is deliberately strict — CPython forwards tokens it does not implement to the platform's C library, so a token can work on a Mac and fail on Windows; the column records what the docs guarantee, the notes record what merely happens.
Examples
%Y-%m-%d %H:%M:%S2026-03-08 15:26:05The most-typed format there is: four-digit year, zero-padded month and day, 24-hour clock — every piece C99-portable, no locale tables involved.
%a, %d %b %Y %H:%M:%S %zSun, 08 Mar 2026 15:26:05 +0000An email-style date line. %a and %b read the locale's name tables and %z prints the UTC offset, so the preview shows both of its note chips beside this one.
%A %e %BSunday 8 MarchPadding contrast: %e pads the single-digit day with a space where %d would write a zero — look closely, there are two spaces before the 8.
%G-W%V-%u vs %Y2004-W53-6 vs 2005New Year's Day 2005 sits in ISO week 53 of 2004, so %G and %Y disagree from the same instant. This is the trap %G exists to close.
%-d/%^b8/MARglibc flags at work: - strips the day's zero padding and ^ upper-cases the month name. Neither flag is C99, and the preview says so.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Early January can belong to last ISO year
At the edge instant 2005-01-01T00:00:00Z, %V prints 53, %G prints 2004 and %g prints 04 while %Y prints 2005. Anything that builds week labels from %Y misfiles those days.
Unknown conversions stay in your output, flagged
Feed the preview %q and the output contains %q, with a warning naming the position. glibc keeps undocumented conversions verbatim, BSD libc quietly drops the %, and C99 calls the whole situation undefined — silently ignoring a typo would hide it.
A format can end mid-conversion
A trailing bare %, or a fragment like %-04 cut off before its letter, is undefined in C99. The engine keeps the fragment verbatim and warns with its position instead of guessing what you meant.
%n and %t print invisible characters
In real output they are a newline and a tab. In the example column they appear as \n and \t so the cells never look empty — the preview renders the genuine whitespace.
Midnight is 12 AM in %I
The 12-hour clock never prints 00: at the edge instant's midnight, %I renders 12 and %p renders AM. When a log needs hours nobody can misread, %H is the token.
Field widths clamp at 128 on this page
glibc parses arbitrarily large widths; here %200Y pads to exactly 128 characters and the extensions note names the width it clamped. A named bound beats an unbounded memory bill.
Common errors
`%q` at position 1 is not a documented conversion — kept verbatim in the output (glibc keeps unknown conversions; C99 leaves them undefined)- The warning every typo earns. The position is the character offset of the % in your format; the output still contains the literal %q, so nothing is lost — fix the token or escape the percent as %%.
the format ends with a bare `%` at position 4 — kept verbatim in the output (C99 leaves this undefined)- Produced by a format like abc% — the % opens a conversion that never gets its letter. Real C libraries disagree about what to do here, which is why it earns a warning before the format ships.
This format is longer than the 4,096-character limit for this tool. For longer jobs use the CLI: date +"%Y-%m-%d %H:%M:%S"- The preview's refusal for a format over 4,096 characters. The engine never truncates silently: the banner states the cap and hands you the CLI line below for anything genuinely that long.
FAQ
What is the difference between %d and %e?
Both print the day of month in a two-character field; %d pads a single digit with a zero (08) and %e with a space ( 8). %e is missing from Python's documented set and fails on Windows CPython; Ruby ships its own strftime, so %e works there everywhere.
When should I use %G instead of %Y?
Whenever %V appears in the same format. %Y is the calendar year; %G is the year the ISO week belongs to, and the two differ around New Year — the edge example above prints 2004 and 2005 from one instant. For a plain date, %Y is the right token.
How are %U, %V and %W different?
Three week-numbering rules: %U starts week 01 at the year's first Sunday, %W at its first Monday, and %V follows ISO 8601, where week 01 contains the year's first Thursday. At the sample instant they print 10, 10 and 09. The week number tool on this site walks the three systems day by day.
Why does %-d work on Linux but fail in Python on Windows?
The - flag is a glibc extension the BSDs also ship, and CPython hands formats to whatever C runtime the platform provides. Windows' CRT rejects %-d — it spells the same request %#d — so a format can pass every Linux test and still fail on Windows.
PHP deprecated strftime() — what replaces these tokens?
Since PHP 8.1 the replacement is date() or DateTime::format(), whose single-letter codes are spelled differently: Y for %Y, m for %m, d for %d, H for %H, i for %M and s for %S. The i/M swap is the one that bites — in date(), i is minutes and M is a month name.
Can %s print Unix epoch seconds portably?
POSIX.1-2024 standardized %s as seconds since the Unix epoch, blessing what glibc and the BSDs had shipped for years — but it is still not C99, and CPython does not document it. The row here prints the frozen sample instant's count; turning counts back into dates is the epoch converter's job.
Do these codes work for parsing dates too?
Mostly. strptime consumes the same conversions to turn text back into a date, and Python mirrors it with datetime.strptime. The sets are not identical, though — %s is formatting-only on many systems, and glibc's flags mean nothing to a parser. This page renders formats; it does not parse dates.
Keyboard shortcuts
- /
- Focus the token filter