Date Format String Builder & Tester
Preview any date pattern, convert it between 13 languages and catch YYYY-vs-yyyy mistakes.
Pattern
Add a field
Inserts the token at the cursor. Only fields this language can write exactly are shown.
Preview with
Digits after the point, up to 9.
What each token means
| Token | Meaning | Prints |
|---|
In other languages
The same fields written for each language and previewed by its own rules. Notes say where a language has no exact equivalent.
| Language | Pattern | Prints |
|---|
About the Date Format String Builder & Tester
Write a date or time pattern in the language you use — C, Python or Ruby strftime, PHP date(), a Go layout, Java DateTimeFormatter, a .NET format string, ICU/Unicode LDML (Swift, Kotlin, Android), Moment.js, Day.js, date-fns, MySQL DATE_FORMAT or PostgreSQL to_char — and see exactly what it prints for any date, time, time zone and locale. Every token is explained, so you can see why %M is minutes in Python but the month name in MySQL.
The same pattern is then written in all the other languages, each previewed by its own rules, which makes porting a date format from one stack to another a copy-and-paste job. Common mistakes are flagged as you type: the week-based year YYYY instead of yyyy (with the exact date where it goes wrong), the day of the year DD instead of dd, minutes in place of the month, a 12-hour clock without AM/PM, PostgreSQL’s padded Month and more.
How to use it
- Choose the language whose pattern you want to write or check, and type the pattern — or pick one of the common formats.
- Click the buttons under Add a field to insert the right token for the year, month, day, time or time zone at the cursor; each button shows what it prints.
- Set the date, time, time zone and locale to preview with (the sample is a Saturday afternoon, so weekdays and AM/PM show), or press Now.
- Read the breakdown of every token and the warnings under the preview, and copy the pattern or its output.
- Under In other languages, copy the same pattern for another language; switching the language at the top converts the pattern too.
Examples
Language: Python Pattern: %A, %d %B %Y Date: 2026-03-07 14:05:09 Asia/Kolkata
Saturday, 07 March 2026
Language: Java Pattern: YYYY-MM-dd Date: 2026-12-28 10:00:00 UTC
2027-12-28
Y is the week-based year. With the US week rules (Locale.US), the week that holds 1 January 2027 starts on Sunday 27 December, so those last days of 2026 print as 2027. yyyy prints 2026.
Language: Go Pattern: 2006-01-02T15:04:05.000Z07:00 Date: 2026-03-07 14:05:09.123 Asia/Kolkata
2026-03-07T14:05:09.123+05:30
The same pattern is yyyy-MM-dd'T'HH:mm:ss.SSSXXX in Java and date-fns, and %Y-%m-%dT%H:%M:%S.%f%:z in Python 3.12+ (where %f always has 6 digits and UTC is written +00:00, not Z).
Language: PostgreSQL Pattern: FMDay, FMDDth FMMonth YYYY Date: 2026-03-07 14:05:09 UTC
Saturday, 7th March 2026
Without FM, Day and Month are padded with spaces to 9 characters (“Saturday ” and “March ”).
Common uses
- Checking a date format before it goes into code, a log configuration, a report or a SQL query.
- Porting date handling between stacks: a Python strftime pattern to Java, a Moment.js format to date-fns, a MySQL report to PostgreSQL.
- Finding out why a date prints wrong only in the last days of December, or why a minute shows up where the month should be.
- Looking up the token for a field (ISO week, day of the year, AM/PM, UTC offset) with a live example instead of reading a cheat sheet.
Look-alike tokens that cause bugs
- YYYY vs yyyy (Java, ICU, date-fns):
Yis the week-based year, which moves to the next year at the start of week 1 — up to a few days early or late. Useyyyy(oruuuuin Java). date-fns refusesYYYYandYYunless you passuseAdditionalWeekYearTokens. The same trap isgggg/GGGGin Moment,%Gin strftime,oin PHP andIYYYin PostgreSQL. - DD vs dd: in Java, ICU and date-fns
Dis the day of the year (66 for 7 March), while in Moment and Day.jsDDis the day of the month andddis the two-letter weekday. - mm vs MM:
mmis minutes almost everywhere; the month isMM. In strftime the month is%mand minutes%M— but in MySQL%Mis the month name and minutes are%i. In PostgreSQL the month isMMand minutes areMI. - hh vs HH:
hhis the 12-hour clock (01–12) and needs AM/PM (a,A,tt,%p);HHis 00–23. In PostgreSQLHHitself is the 12-hour clock: writeHH24. - S vs s:
Sis a fraction of a second,sthe seconds. - Go has no letters at all: a layout is the reference time
Mon Jan 2 15:04:05 MST 2006written the way you want, so2006-01-02is a date andYYYY-MM-DDprints literally.
The same date and time in each language
- C, Python and Ruby
strftime:%Y-%m-%d %H:%M:%S - PHP
date():Y-m-d H:i:s - Go:
2006-01-02 15:04:05 - Java, .NET, ICU and date-fns:
yyyy-MM-dd HH:mm:ss - Moment.js and Day.js:
YYYY-MM-DD HH:mm:ss - MySQL
DATE_FORMAT:%Y-%m-%d %H:%i:%s - PostgreSQL
to_char:YYYY-MM-DD HH24:MI:SS
Locales, time zones and platforms
- Names in your locale (month, weekday, AM/PM) come from your browser’s Unicode CLDR data for Java, .NET, ICU, Moment, Day.js and date-fns. C and Python use the C locale unless the program calls
setlocale(); Ruby, PHP and Go are always English; MySQL followslc_time_names(English by default) and PostgreSQL uses English unless you addTM. - Time zone abbreviations such as IST, CET or EDT come from the IANA tz database for C, Python, Ruby, PHP, Go and PostgreSQL, for every zone; before a zone’s standard time the tz database has local mean time (LMT, an offset with seconds such as +05:53:28), which Python’s
%zprints in full. ICU uses CLDR names, which are often “GMT+5:30”. Java uses CLDR’s name where the locale has one (EST, MEZ), its own older abbreviations where CLDR has none (IST, NPT, BRT), and in English outside North America it writes North American zones as GMT-05:00. - strftime differs by platform: Python passes the codes outside its documented table to the C library. C99 codes such as
%e,%Fand%Twork everywhere, Windows included;%-d,%k,%land%swork on Linux and macOS but not with Python on Windows (which writes%#dfor a day without a leading zero);%P, the^and#flags and field widths are GNU extensions that only Linux has, and macOS prints them as written. - Python’s %s ignores the datetime’s time zone and uses the computer’s; use
int(dt.timestamp()). - .NET replaces
/and:with the culture’s separators (07.03.2026in German) unless you format withCultureInfo.InvariantCulture, and a single-letter format such asdis a standard format, not a custom one.
References: POSIX strftime · Python · Ruby · PHP · Go · Java · .NET · ICU · Moment.js · Day.js · date-fns · MySQL · PostgreSQL
Limitations
- Formatting only: parsing functions (strptime, ParseExact, to_date) read patterns with extra rules of their own that are not covered.
- Localized names come from your browser’s CLDR data. A JDK carries its own, older copy, so Java words some names differently (era names, generic zone names such as PT, day periods (B), whose hours and words changed between CLDR versions, and some AM/PM, month and zone spellings); outside English, Moment, Day.js and date-fns use locale files of their own, which can differ too; ordinal suffixes (1st, 2nd) are English.
- Dates from the year 1000 to 9999, in the Gregorian calendar.
- For C, the GNU C library’s behaviour is shown; the page notes where macOS/BSD and Windows differ. For Day.js, the plugins a token needs are assumed to be loaded (the breakdown says which).
- .NET standard formats (single letters such as d or O) are explained but not previewed.
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
What is the difference between YYYY and yyyy?
In Java, ICU (Swift, Kotlin, Android) and date-fns, yyyy is the calendar year and YYYY the week-based year used with week numbers. They agree for most of the year, but in the days around 1 January the week-based year can already be the next year (or still the previous one), so YYYY-MM-dd prints dates such as 2027-12-28 for 28 December 2026. Use yyyy for ordinary dates; the page shows the first date where your pattern goes wrong.
Why does Go use 2006-01-02 instead of YYYY-MM-DD?
Go’s time package formats by example: you write its reference time, Monday 2 January 2006 15:04:05 in a zone seven hours west of GMT, the way you want dates to look. The numbers 1 to 6 stand for month, day, hour, minute, second and year, so 02/01/2006 is day/month/year and 3:04PM is a 12-hour time. Letters such as YYYY are printed as they are.
Why does %-d not work in Python on Windows?
Python passes everything except a few codes such as %f and %z to the C library. glibc (Linux) and macOS accept %-d for a day without a leading zero; Microsoft’s C runtime does not, and uses %#d instead. For code that runs everywhere, format the number yourself (str(dt.day)).
Why does MySQL print the month name where I expected minutes?
In MySQL’s DATE_FORMAT, %M is the full month name and minutes are %i; seconds are %s or %S. A pattern copied from strftime, %Y-%m-%d %H:%M:%S, therefore prints “2026-03-07 14:March:09”. The MySQL equivalent is %Y-%m-%d %H:%i:%s.
Is HH 24-hour in PostgreSQL?
No: in to_char, HH (like HH12) is the hour 01–12. Use HH24 for 00–23. Also note that MM is the month and MI the minutes, and add FM before Day or Month to drop the padding to 9 characters.
How do I put literal text in a pattern?
Each language escapes differently: single quotes in Java, ICU, date-fns and .NET (yyyy-MM-dd'T'HH:mm), square brackets in Moment and Day.js ([at]), a backslash per character in PHP (\a\t), double quotes in PostgreSQL ("at"), and %% for a percent sign in strftime and MySQL. Go has no escaping, so digits 1–6 and words such as Jan, Mon or PM in Go layouts are always read as fields. The “In other languages” table writes the escapes for you.
Is anything uploaded?
No. Patterns are parsed and dates formatted by JavaScript in this page, with your browser’s own time zone and locale data. It works offline once loaded.