# format strings

Date and time format elements for parsing/printing are defined by the following groups of characters.
As a general rule, they typically follow the implicit case pattern of "YYYY/MM/DD hh:mm:ss".
Not very strictly followed, however numeric forms of Months/minutes are specified by case.
A simple rule to remember is "The Month of May may be Capitalized, minutes never are".

element | aliases | description
D | d | One- or two-digit day.
DD | dd | Two-digit day. Single-digit day values are preceded by a zero.
th | st/TH/ST | Two-character ordinal suffix. (lower/uppercase) Must immediately follow d/D/dd/DD.
Ddd | DDD/ddd | Three-character weekday abbreviation. (capitalised/uppercase/lowercase)
Dddd | DDDD/dddd | Full weekday name. (capitalised/uppercase/lowercase)
doy |  | Day of year (1..366).
h | H | One- or two-digit hour. (See am/pm notes below.)
hh | HH | Two-digit hour. Single-digit values are preceded by a zero. ("")
m | mm | Two-digit minute. Single-digit values are preceded by a zero. (NB not M/MM)
s | ss/S/SS | Two-digit second. Single-digit values are preceded by a zero.
ms |  | Three-digit millisecond, 000 to 999.
pm | am/PM/AM | Two-letter am/pm abbreviation, prior hour must exist. (lower/uppercase)
M |  | One- or two-digit month number. (NB not m)
MM |  | Two-digit month number. Single-digit values are preceded by a zero. (NB not mm)
Mmm | MMM/mmm | Three-character month abbreviation. (capitalised/uppercase/lowercase)
Mmmm | MMMM/mmmm | Full month name. (capitalised/uppercase/lowercase)
Y | y/YY/yy | One- or two-digit year.
YYYY | yyyy | Four-digit year.
TZ | tz | Three- or four-character uppercase time zone (always uppercase, eg "GMT")
Tzz | TZZ/tzz | Full time zone name. (always as-is/capitalised, eg "Greenwich Mean Time")
Examples |  |
    "YYYY/MM/DD ham tz"                         "Ddd, Mmm dst, yyyy"
    "YYYY/MM/DD ham"                            "Ddd, Mmm dth, yyyy"
    "DD Mmm YY"             "hh:mm"             "DDD, Mmm dST, yyyy"
    "M/D/YY"                "hh:mmpm"           "Ddd, MMM DTH, yyyy"
    "D/M/Y"                 "hh:mm tz"          "Ddd, Mmm dth, YYYY, h:mmpm tz"
    "M/D/Y"                 "hpm tz"            "Ddd, Mmm dth, YYYY, h:mmpm"
    "M/D/YYY"               "hpm"               "Dddd, Mmmm dth, YYYY, h:mmpm"
    "MM/DD/YY"              "h:m:s am"          "Dddd, Mmmm dd, yyyy"
    "M/DD/YY"               "h:m:sam"           "Dddd, Mmmm d, YYYY"
    "M/DD/YYYY"             " (tzz)"            "Dddd d Mmmm yyyy h:mmpm tz"
    "YYYY-MM-DD"                                "Mmmm d, yyyy, hh:mm:ss"
    "D/M/YYYY hpm TZ"                           "Mmmm dth yyyy h:mmam tz"
    "D/M/YYYY hpm (Tzz)"                        "Mmmm dth yyyy h:mmam"
    "dd-Mmm-YY"                                 "Mmmm d yyyy h:mmpm tz"
    "’Today is’ Dddd, Mmmm dth, YYYY" -- (put literals in single quotes)
    "’Today’’’’s date is’ Dddd, Mmmm dth, YYYY"
WRONG |  |
    "dd/mm/yyyy"    -- would be day/minute/year!!
    "HH:MM"         -- would be hour/month!!
An error (3 element sequence) is returned if minute immediately follows day or year, or if month immediately follows hour or precedes second or ampm. (But not if minute immedately precedes year or day, since "1:50 [2016] 2nd Jan" is fine, and month immediately preceding hour or day is fine.)
Technicalia |  | Special attention is required to avoid confusing m/mm (minute) and M/MM (month). Spaces and punctuation (other than single quotes) in a format are treated as literals. Any required literal alphanumerics must be enclosed in single quotes, with two adjacent single quotes treated as one single quote, eg "'Today''''s date is 'DD/MM/YYYY.", which yields/parses eg "Today's date is 14/09/2015." Feel free to print fragments, eg "dst", "Mmmm", "tz", and post-process/stitch together. At the moment ordinals (1st/2nd/3rd/4th/etc) are only supported in/for english. There’s a commented-out set_timedate_lang() and google translates for seven other languages besides English, all untested and awaiting approval by someone who speaks it. Minutes and seconds <10 cannot be printed without a leading 0, but month/day/hours can. Two digit years use a -80..+20 rule, eg in 2017, 36 -> 2036 but 37 -> 1937. lowercase/uppercase actually match any case input, whereas capitalised is more strict; it is really for output that all those different distinctions are available anyway. Obviously uppercase/lowercase format specifiers make no difference on numeric fields. A timezone is always parsed and printed in uppercase. Tzz/TZZ/tzz as-is, see tzdesc. When am/pm is parsed/printed, it adjusts a previous hour (error if none) appropriately. There is no way to print a 12-hour time without also printing an am/pm indicator. The times "12:15am" and "2:15pm" are internally stored as {0,15} and {14,15} respectively, and reconstituted exactly as they were, as long as you use the same format string. Some languages, eg de, use a two-character weekday abbreviation - but the format string used to obtain said is still three characters long (ddd/Ddd/DDD). Great care has been taken to avoid any potential ambiguity, the only potential mishap is "stz" which opts for "st" (aka "th") which will probably error out because it does not immediately follow a d, and if it was "dstz" then it would error on the "z" anyway. Should you really want seconds hard pressed against a timezone with no separating space, use "sstz" instead, or stitch fragments together. Update: I added "ms" somewhat hastily: previously it would have printed minutes hard pressed against seconds, which would now require "mmss" (or just "mms"). A key idea is that the same format strings can be used for parse and output, so rather than have any fiddly "optional" bits, just use a collection of acceptable formats (and if you need more than say eight, it may be time to think of an alternative strategy). When translating the frankly rather bizzare specifiers of Euphoria’s datetime:format(), which has been renamed as dateformat(), I recommend the following Phix equivalents (following YYYYMMDD hh:mm:ss case rules). %a ==> Ddd %A ==> Dddd %b ==> Mnn %B ==> Mmmm %C ==> YY %d ==> DD %H ==> hh %I ==> hh1 %j ==> doy %k ==> h %l ==> h1 %m ==> MM %M ==> mm %p ==> PM %P ==> pm %S ==> ss %y ==> YY %Y ==> YYYY 1 ie %(uppercase i or lowercase L) needs to be followed by am/pm/AM/PM (that is, to get the 12-hour format) %u is 1..7 for Monday..Sunday, not directly supported here but see day_of_week() %w is 0..6 for Sunday..Saturday, ... (words fail me) %s is seconds since 0:00:00am 1/1/1970, erm, ditto... (besides, if you need a nonce, it should be at least to milliseconds accuracy) For those in need, a link to the original: https://openeuphoria.org/docs/std_datetime.html#_1174_format The default format of dateformat(), "%Y-%m-%d %H:%M:%S", is equivalent to "YYYY-MM-DD hh:mm:ss", whereas format_timedate() has a default of "h:mpm Dddd Mmmm ddth, yyyy".