moment / luxon

⏱ A library for working with dates and times in JS
https://moment.github.io/luxon
MIT License
15.4k stars 729 forks source link

Feature request - localized numeric date, padded to 2 #664

Open ccosmincc opened 4 years ago

ccosmincc commented 4 years ago

Currently there is the following formatting token: 'D' (localized numeric date) e.g.: 9/4/2017

Would it be possible to introduce a new token that will provide the same formatting, but padded to 2? e.g.: 09/04/2017

scola84 commented 4 years ago

Maybe related to this is that in a 24-hour localized format hours would preferably be padded to 2 as well. So "0:00 AM" in 12-hour format makes sense, but "0:00" in 24-hour format not completely.

GillesDebunne commented 4 years ago

These are valid requests. But some people may prefer only padding the month, or a 2-digit version of the year too. My point is: there are so many combinations that it seems easier to let each user define their preferred format.

For your specific use case:

function myFormat(d) { return d.toLocaleString({day:'2-digit', month:'2-digit', year:'numeric'}) }

See MDN for a full description of formatting options.

Shinigami92 commented 4 years ago

Would be really nice if there is a DateTime.DATE_LONG which is equal to { year: 'numeric', month: '2-digit', day: '2-digit' }

ccosmincc commented 4 years ago

I'm using Luxon as a Date Adapter for Angular Material Datepicker component. There I need to provide the different date formats that will be used by the datepicker ( https://github.com/angular/components/blob/80e4d3f1bebefd29f901f621dea928ccb38a35c8/src/components-examples/material/datepicker/datepicker-formats/datepicker-formats-example.ts#L18 ). I can only use formatting tokens there, that's why my request is for introducing a token, because I cannot format the dates via Javascript, using toLocaleString.

GillesDebunne commented 4 years ago

@ccosmincc the code you are referencing is using moment, that's a different library.

ccosmincc commented 4 years ago

@GillesDebunne I know that the example is using moment, but that is not really relevant, I just put it there to provide more context on my use case: I have a configuration object where I can only format via tokens. Here is the same configuration, but for luxon, if it makes things more clear: https://gist.github.com/Zyzle/a9c5daa396882eb155282bcb454b9511#file-luxon-date-adapter-ts-L11

GillesDebunne commented 4 years ago

This makes sense.

If you control that part, what prevents you from overloading the format method, where the formatting seems to happen?

format(date: DateTime, displayFormat: any): string { if (displayFormat == MY_CUSTOM) return date..toLocaleString({ pick_your_choice: '2-digit' }) return date.toFormat(displayFormat); }

On Fri, Sep 25, 2020 at 6:54 AM ccosmincc notifications@github.com wrote:

@GillesDebunne https://github.com/GillesDebunne I know that the example is using moment, but that is not really relevant, I just put it there to provide more context on my use case: I have a configuration object where I can only format via tokens. Here is the same configuration, but for luxon, if it makes things more clear: https://gist.github.com/Zyzle/a9c5daa396882eb155282bcb454b9511#file-luxon-date-adapter-ts-L11

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/moment/luxon/issues/664#issuecomment-698719149, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOPFGWIRWWSYHJTJSSROS3SHQO67ANCNFSM4KTVU3RA .

ccosmincc commented 4 years ago

@GillesDebunne I could introduce that logic in the format method, as you suggested, but I'm using Luxon in my entire project, not only for the datepicker, and I have one common place where I define the format, and at least 3 (most probably more in the future) other places where I handle Luxon dates based on that format (using date.toFormat), so I will be forced to introduce this custom logic everywhere.

olmobrutall commented 4 years ago

Using .Net Standard date and time format strings as a reference, check Short date pattern. The same token is used for dates, but is culture-specific whether it should use one or two digits:

2009-06-15T13:45:30 -> 6/15/2009 (en-US) 2009-06-15T13:45:30 -> 15/06/2009 (fr-FR) 2009-06-15T13:45:30 -> 2009/06/15 (ja-JP)

I checked the value ShortDatePattern for all the cultures, this is the result:

Name           ShortDatePattern
               MM/dd/yyyy
aa             dd/MM/yyyy
aa-DJ          dd/MM/yyyy
aa-ER          dd/MM/yyyy
aa-ET          dd/MM/yyyy
af             yyyy-MM-dd
af-NA          yyyy-MM-dd
af-ZA          yyyy-MM-dd
agq            d/M/yyyy
agq-CM         d/M/yyyy
ak             yyyy/MM/dd
ak-GH          yyyy/MM/dd
am             dd/MM/yyyy
am-ET          dd/MM/yyyy
ar             dd/MM/yy
ar-001         d/M/yyyy
ar-AE          dd/MM/yyyy
ar-BH          dd/MM/yyyy
ar-DJ          d/M/yyyy
ar-DZ          dd-MM-yyyy
ar-EG          dd/MM/yyyy
ar-ER          d/M/yyyy
ar-IL          d/M/yyyy
ar-IQ          dd/MM/yyyy
ar-JO          dd/MM/yyyy
ar-KM          d/M/yyyy
ar-KW          dd/MM/yyyy
ar-LB          dd/MM/yyyy
ar-LY          dd/MM/yyyy
ar-MA          dd-MM-yyyy
ar-MR          d/M/yyyy
ar-OM          dd/MM/yyyy
ar-PS          d/M/yyyy
ar-QA          dd/MM/yyyy
ar-SA          dd/MM/yy
ar-SD          d/M/yyyy
ar-SO          d/M/yyyy
ar-SS          d/M/yyyy
ar-SY          dd/MM/yyyy
ar-TD          d/M/yyyy
ar-TN          dd-MM-yyyy
ar-YE          dd/MM/yyyy
arn            dd-MM-yyyy
arn-CL         dd-MM-yyyy
as             dd-MM-yyyy
as-IN          dd-MM-yyyy
asa            dd/MM/yyyy
asa-TZ         dd/MM/yyyy
ast            d/M/yyyy
ast-ES         d/M/yyyy
az             dd.MM.yyyy
az-Cyrl        dd.MM.yyyy
az-Cyrl-AZ     dd.MM.yyyy
az-Latn        dd.MM.yyyy
az-Latn-AZ     dd.MM.yyyy
ba             dd.MM.yy
ba-RU          dd.MM.yy
bas            d/M/yyyy
bas-CM         d/M/yyyy
be             dd.MM.yy
be-BY          dd.MM.yy
bem            dd/MM/yyyy
bem-ZM         dd/MM/yyyy
bez            dd/MM/yyyy
bez-TZ         dd/MM/yyyy
bg             d.M.yyyy '?.'
bg-BG          d.M.yyyy '?.'
bin            d/M/yyyy
bin-NG         d/M/yyyy
bm             d/M/yyyy
bm-Latn        d/M/yyyy
bm-Latn-ML     d/M/yyyy
bn             d/M/yyyy
bn-BD          d/M/yyyy
bn-IN          dd-MM-yy
bo             yyyy/M/d
bo-CN          yyyy/M/d
bo-IN          yyyy-MM-dd
br             dd/MM/yyyy
br-FR          dd/MM/yyyy
brx            M/d/yyyy
brx-IN         M/d/yyyy
bs             d. M. yyyy.
bs-Cyrl        d.M.yyyy
bs-Cyrl-BA     d.M.yyyy
bs-Latn        d. M. yyyy.
bs-Latn-BA     d. M. yyyy.
byn            dd/MM/yyyy
byn-ER         dd/MM/yyyy
ca             d/M/yyyy
ca-AD          d/M/yyyy
ca-ES          d/M/yyyy
ca-ES-valencia d/M/yyyy
ca-FR          d/M/yyyy
ca-IT          d/M/yyyy
ccp            d/M/yyyy
ccp-Cakm       d/M/yyyy
ccp-Cakm-BD    d/M/yyyy
ccp-Cakm-IN    d/M/yyyy
ce             yyyy-MM-dd
ce-RU          yyyy-MM-dd
ceb            M/d/yyyy
ceb-Latn       M/d/yyyy
ceb-Latn-PH    M/d/yyyy
cgg            dd/MM/yyyy
cgg-UG         dd/MM/yyyy
chr            M/d/yyyy
chr-Cher       M/d/yyyy
chr-Cher-US    M/d/yyyy
co             dd/MM/yyyy
co-FR          dd/MM/yyyy
cs             dd.MM.yyyy
cs-CZ          dd.MM.yyyy
cu             yyyy.MM.dd
cu-RU          yyyy.MM.dd
cy             dd/MM/yyyy
cy-GB          dd/MM/yyyy
da             dd-MM-yyyy
da-DK          dd-MM-yyyy
da-GL          dd.MM.yyyy
dav            dd/MM/yyyy
dav-KE         dd/MM/yyyy
de             dd.MM.yyyy
de-AT          dd.MM.yyyy
de-BE          dd.MM.yyyy
de-CH          dd.MM.yyyy
de-DE          dd.MM.yyyy
de-IT          dd.MM.yyyy
de-LI          dd.MM.yyyy
de-LU          dd.MM.yyyy
dje            d/M/yyyy
dje-NE         d/M/yyyy
dsb            d. M. yyyy
dsb-DE         d. M. yyyy
dua            d/M/yyyy
dua-CM         d/M/yyyy
dv             dd/MM/yy
dv-MV          dd/MM/yy
dyo            d/M/yyyy
dyo-SN         d/M/yyyy
dz             yyyy-MM-dd
dz-BT          yyyy-MM-dd
ebu            dd/MM/yyyy
ebu-KE         dd/MM/yyyy
ee             M/d/yyyy
ee-GH          M/d/yyyy
ee-TG          M/d/yyyy
el             d/M/yyyy
el-CY          d/M/yyyy
el-GR          d/M/yyyy
en             M/d/yyyy
en-001         dd/MM/yyyy
en-029         dd/MM/yyyy
en-150         dd/MM/yyyy
en-AE          dd/MM/yyyy
en-AG          dd/MM/yyyy
en-AI          dd/MM/yyyy
en-AS          M/d/yyyy
en-AT          dd/MM/yyyy
en-AU          d/MM/yyyy
en-BB          dd/MM/yyyy
en-BE          dd/MM/yyyy
en-BI          M/d/yyyy
en-BM          dd/MM/yyyy
en-BS          dd/MM/yyyy
en-BW          dd/MM/yyyy
en-BZ          dd/MM/yyyy
en-CA          yyyy-MM-dd
en-CC          dd/MM/yyyy
en-CH          dd/MM/yyyy
en-CK          dd/MM/yyyy
en-CM          dd/MM/yyyy
en-CX          dd/MM/yyyy
en-CY          dd/MM/yyyy
en-DE          dd/MM/yyyy
en-DK          dd/MM/yyyy
en-DM          dd/MM/yyyy
en-ER          dd/MM/yyyy
en-FI          dd/MM/yyyy
en-FJ          dd/MM/yyyy
en-FK          dd/MM/yyyy
en-FM          dd/MM/yyyy
en-GB          dd/MM/yyyy
en-GD          dd/MM/yyyy
en-GG          dd/MM/yyyy
en-GH          dd/MM/yyyy
en-GI          dd/MM/yyyy
en-GM          dd/MM/yyyy
en-GU          M/d/yyyy
en-GY          dd/MM/yyyy
en-HK          d/M/yyyy
en-ID          dd/MM/yyyy
en-IE          dd/MM/yyyy
en-IL          dd/MM/yyyy
en-IM          dd/MM/yyyy
en-IN          dd-MM-yyyy
en-IO          dd/MM/yyyy
en-JE          dd/MM/yyyy
en-JM          d/M/yyyy
en-KE          dd/MM/yyyy
en-KI          dd/MM/yyyy
en-KN          dd/MM/yyyy
en-KY          dd/MM/yyyy
en-LC          dd/MM/yyyy
en-LR          dd/MM/yyyy
en-LS          dd/MM/yyyy
en-MG          dd/MM/yyyy
en-MH          M/d/yyyy
en-MO          dd/MM/yyyy
en-MP          M/d/yyyy
en-MS          dd/MM/yyyy
en-MT          dd/MM/yyyy
en-MU          dd/MM/yyyy
en-MW          dd/MM/yyyy
en-MY          d/M/yyyy
en-NA          dd/MM/yyyy
en-NF          dd/MM/yyyy
en-NG          dd/MM/yyyy
en-NL          dd/MM/yyyy
en-NR          dd/MM/yyyy
en-NU          dd/MM/yyyy
en-NZ          d/MM/yyyy
en-PG          dd/MM/yyyy
en-PH          dd/MM/yyyy
en-PK          dd/MM/yyyy
en-PN          dd/MM/yyyy
en-PR          M/d/yyyy
en-PW          dd/MM/yyyy
en-RW          dd/MM/yyyy
en-SB          dd/MM/yyyy
en-SC          dd/MM/yyyy
en-SD          dd/MM/yyyy
en-SE          yyyy-MM-dd
en-SG          d/M/yyyy
en-SH          dd/MM/yyyy
en-SI          dd/MM/yyyy
en-SL          dd/MM/yyyy
en-SS          dd/MM/yyyy
en-SX          dd/MM/yyyy
en-SZ          dd/MM/yyyy
en-TC          dd/MM/yyyy
en-TK          dd/MM/yyyy
en-TO          dd/MM/yyyy
en-TT          dd/MM/yyyy
en-TV          dd/MM/yyyy
en-TZ          dd/MM/yyyy
en-UG          dd/MM/yyyy
en-UM          M/d/yyyy
en-US          M/d/yyyy
en-VC          dd/MM/yyyy
en-VG          dd/MM/yyyy
en-VI          M/d/yyyy
en-VU          dd/MM/yyyy
en-WS          dd/MM/yyyy
en-ZA          yyyy/MM/dd
en-ZM          dd/MM/yyyy
en-ZW          d/M/yyyy
eo             yyyy-MM-dd
eo-001         yyyy-MM-dd
es             dd/MM/yyyy
es-419         d/M/yyyy
es-AR          d/M/yyyy
es-BO          d/M/yyyy
es-BR          d/M/yyyy
es-BZ          d/M/yyyy
es-CL          dd-MM-yyyy
es-CO          d/MM/yyyy
es-CR          d/M/yyyy
es-CU          d/M/yyyy
es-DO          d/M/yyyy
es-EC          d/M/yyyy
es-ES          dd/MM/yyyy
es-GQ          d/M/yyyy
es-GT          d/MM/yyyy
es-HN          d/M/yyyy
es-MX          dd/MM/yyyy
es-NI          d/M/yyyy
es-PA          MM/dd/yyyy
es-PE          d/MM/yyyy
es-PH          d/M/yyyy
es-PR          MM/dd/yyyy
es-PY          d/M/yyyy
es-SV          d/M/yyyy
es-US          M/d/yyyy
es-UY          d/M/yyyy
es-VE          d/M/yyyy
et             dd.MM.yyyy
et-EE          dd.MM.yyyy
eu             yyyy/M/d
eu-ES          yyyy/M/d
ewo            d/M/yyyy
ewo-CM         d/M/yyyy
fa             dd/MM/yyyy
fa-IR          dd/MM/yyyy
ff             dd/MM/yyyy
ff-Latn        dd/MM/yyyy
ff-Latn-BF     d/M/yyyy
ff-Latn-CM     d/M/yyyy
ff-Latn-GH     d/M/yyyy
ff-Latn-GM     d/M/yyyy
ff-Latn-GN     d/M/yyyy
ff-Latn-GW     d/M/yyyy
ff-Latn-LR     d/M/yyyy
ff-Latn-MR     d/M/yyyy
ff-Latn-NE     d/M/yyyy
ff-Latn-NG     d/M/yyyy
ff-Latn-SL     d/M/yyyy
ff-Latn-SN     dd/MM/yyyy
fi             d.M.yyyy
fi-FI          d.M.yyyy
fil            M/d/yyyy
fil-PH         M/d/yyyy
fo             dd.MM.yyyy
fo-DK          dd.MM.yyyy
fo-FO          dd.MM.yyyy
fr             dd/MM/yyyy
fr-029         dd/MM/yyyy
fr-BE          dd-MM-yy
fr-BF          dd/MM/yyyy
fr-BI          dd/MM/yyyy
fr-BJ          dd/MM/yyyy
fr-BL          dd/MM/yyyy
fr-CA          yyyy-MM-dd
fr-CD          dd/MM/yyyy
fr-CF          dd/MM/yyyy
fr-CG          dd/MM/yyyy
fr-CH          dd.MM.yyyy
fr-CI          dd/MM/yyyy
fr-CM          dd/MM/yyyy
fr-DJ          dd/MM/yyyy
fr-DZ          dd/MM/yyyy
fr-FR          dd/MM/yyyy
fr-GA          dd/MM/yyyy
fr-GF          dd/MM/yyyy
fr-GN          dd/MM/yyyy
fr-GP          dd/MM/yyyy
fr-GQ          dd/MM/yyyy
fr-HT          dd/MM/yyyy
fr-KM          dd/MM/yyyy
fr-LU          dd/MM/yyyy
fr-MA          dd/MM/yyyy
fr-MC          dd/MM/yyyy
fr-MF          dd/MM/yyyy
fr-MG          dd/MM/yyyy
fr-ML          dd/MM/yyyy
fr-MQ          dd/MM/yyyy
fr-MR          dd/MM/yyyy
fr-MU          dd/MM/yyyy
fr-NC          dd/MM/yyyy
fr-NE          dd/MM/yyyy
fr-PF          dd/MM/yyyy
fr-PM          dd/MM/yyyy
fr-RE          dd/MM/yyyy
fr-RW          dd/MM/yyyy
fr-SC          dd/MM/yyyy
fr-SN          dd/MM/yyyy
fr-SY          dd/MM/yyyy
fr-TD          dd/MM/yyyy
fr-TG          dd/MM/yyyy
fr-TN          dd/MM/yyyy
fr-VU          dd/MM/yyyy
fr-WF          dd/MM/yyyy
fr-YT          dd/MM/yyyy
fur            dd/MM/yyyy
fur-IT         dd/MM/yyyy
fy             dd-MM-yyyy
fy-NL          dd-MM-yyyy
ga             dd/MM/yyyy
ga-IE          dd/MM/yyyy
gd             dd/MM/yyyy
gd-GB          dd/MM/yyyy
gl             dd/MM/yyyy
gl-ES          dd/MM/yyyy
gn             dd/MM/yyyy
gn-PY          dd/MM/yyyy
gsw            dd.MM.yyyy
gsw-CH         dd.MM.yyyy
gsw-FR         dd/MM/yyyy
gsw-LI         dd.MM.yyyy
gu             dd-MM-yy
gu-IN          dd-MM-yy
guz            dd/MM/yyyy
guz-KE         dd/MM/yyyy
gv             dd/MM/yyyy
gv-IM          dd/MM/yyyy
ha             d/M/yyyy
ha-Latn        d/M/yyyy
ha-Latn-GH     d/M/yyyy
ha-Latn-NE     d/M/yyyy
ha-Latn-NG     d/M/yyyy
haw            d/M/yyyy
haw-US         d/M/yyyy
he             dd/MM/yyyy
he-IL          dd/MM/yyyy
hi             dd-MM-yyyy
hi-IN          dd-MM-yyyy
hr             d.M.yyyy.
hr-BA          d. M. yyyy.
hr-HR          d.M.yyyy.
hsb            d.M.yyyy
hsb-DE         d.M.yyyy
hu             yyyy. MM. dd.
hu-HU          yyyy. MM. dd.
hy             dd.MM.yyyy
hy-AM          dd.MM.yyyy
ia             dd-MM-yyyy
ia-001         dd-MM-yyyy
ibb            d/M/yyyy
ibb-NG         d/M/yyyy
id             dd/MM/yyyy
id-ID          dd/MM/yyyy
ig             d/M/yyyy
ig-NG          d/M/yyyy
ii             yyyy/M/d
ii-CN          yyyy/M/d
is             d.M.yyyy
is-IS          d.M.yyyy
it             dd/MM/yyyy
it-CH          dd.MM.yyyy
it-IT          dd/MM/yyyy
it-SM          dd/MM/yyyy
it-VA          dd/MM/yyyy
iu             d/MM/yyyy
iu-Cans        d/M/yyyy
iu-Cans-CA     d/M/yyyy
iu-Latn        d/MM/yyyy
iu-Latn-CA     d/MM/yyyy
ja             yyyy/MM/dd
ja-JP          yyyy/MM/dd
jgo            yyyy-MM-dd
jgo-CM         yyyy-MM-dd
jmc            dd/MM/yyyy
jmc-TZ         dd/MM/yyyy
jv             dd/MM/yyyy
jv-Java        dd/MM/yyyy
jv-Java-ID     dd/MM/yyyy
jv-Latn        dd/MM/yyyy
jv-Latn-ID     dd/MM/yyyy
ka             dd.MM.yyyy
ka-GE          dd.MM.yyyy
kab            d/M/yyyy
kab-DZ         d/M/yyyy
kam            dd/MM/yyyy
kam-KE         dd/MM/yyyy
kde            dd/MM/yyyy
kde-TZ         dd/MM/yyyy
kea            d/M/yyyy
kea-CV         d/M/yyyy
khq            d/M/yyyy
khq-ML         d/M/yyyy
ki             dd/MM/yyyy
ki-KE          dd/MM/yyyy
kk             dd.MM.yyyy
kk-KZ          dd.MM.yyyy
kkj            dd/MM yyyy
kkj-CM         dd/MM yyyy
kl             dd-MM-yyyy
kl-GL          dd-MM-yyyy
kln            dd/MM/yyyy
kln-KE         dd/MM/yyyy
km             dd/MM/yy
km-KH          dd/MM/yy
kn             dd-MM-yy
kn-IN          dd-MM-yy
ko             yyyy-MM-dd
ko-KP          yyyy. M. d.
ko-KR          yyyy-MM-dd
kok            dd-MM-yyyy
kok-IN         dd-MM-yyyy
kr             d/M/yyyy
kr-Latn        d/M/yyyy
kr-Latn-NG     d/M/yyyy
ks             M/d/yyyy
ks-Arab        M/d/yyyy
ks-Arab-IN     M/d/yyyy
ks-Deva        dd-MM-yyyy
ks-Deva-IN     dd-MM-yyyy
ksb            dd/MM/yyyy
ksb-TZ         dd/MM/yyyy
ksf            d/M/yyyy
ksf-CM         d/M/yyyy
ksh            d. M. yyyy
ksh-DE         d. M. yyyy
ku             yyyy/MM/dd
ku-Arab        yyyy/MM/dd
ku-Arab-IQ     yyyy/MM/dd
ku-Arab-IR     dd/MM/yyyy
kw             dd/MM/yyyy
kw-GB          dd/MM/yyyy
ky             d/M/yyyy
ky-KG          d/M/yyyy
la             dd/MM/yyyy
la-001         dd/MM/yyyy
lag            dd/MM/yyyy
lag-TZ         dd/MM/yyyy
lb             dd.MM.yy
lb-LU          dd.MM.yy
lg             dd/MM/yyyy
lg-UG          dd/MM/yyyy
lkt            M/d/yyyy
lkt-US         M/d/yyyy
ln             d/M/yyyy
ln-AO          d/M/yyyy
ln-CD          d/M/yyyy
ln-CF          d/M/yyyy
ln-CG          d/M/yyyy
lo             d/M/yyyy
lo-LA          d/M/yyyy
lrc            dd/MM/yyyy
lrc-IQ         yyyy-MM-dd
lrc-IR         dd/MM/yyyy
lt             yyyy-MM-dd
lt-LT          yyyy-MM-dd
lu             d/M/yyyy
lu-CD          d/M/yyyy
luo            dd/MM/yyyy
luo-KE         dd/MM/yyyy
luy            dd/MM/yyyy
luy-KE         dd/MM/yyyy
lv             dd.MM.yyyy
lv-LV          dd.MM.yyyy
mas            dd/MM/yyyy
mas-KE         dd/MM/yyyy
mas-TZ         dd/MM/yyyy
mer            dd/MM/yyyy
mer-KE         dd/MM/yyyy
mfe            d/M/yyyy
mfe-MU         d/M/yyyy
mg             yyyy-MM-dd
mg-MG          yyyy-MM-dd
mgh            dd/MM/yyyy
mgh-MZ         dd/MM/yyyy
mgo            yyyy-MM-dd
mgo-CM         yyyy-MM-dd
mi             dd/MM/yyyy
mi-NZ          dd/MM/yyyy
mk             dd.M.yyyy
mk-MK          dd.M.yyyy
ml             d/M/yyyy
ml-IN          d/M/yyyy
mn             yyyy.MM.dd
mn-Cyrl        yyyy.MM.dd
mn-MN          yyyy.MM.dd
mn-Mong        yyyy/M/d
mn-Mong-CN     yyyy/M/d
mn-Mong-MN     yyyy/M/d
mni            dd/MM/yyyy
mni-IN         dd/MM/yyyy
moh            M/d/yyyy
moh-CA         M/d/yyyy
mr             dd-MM-yyyy
mr-IN          dd-MM-yyyy
ms             d/MM/yyyy
ms-BN          d/MM/yyyy
ms-MY          d/MM/yyyy
ms-SG          d/MM/yyyy
mt             dd/MM/yyyy
mt-MT          dd/MM/yyyy
mua            d/M/yyyy
mua-CM         d/M/yyyy
my             dd-MM-yyyy
my-MM          dd-MM-yyyy
mzn            dd/MM/yyyy
mzn-IR         dd/MM/yyyy
naq            dd/MM/yyyy
naq-NA         dd/MM/yyyy
nb             dd.MM.yyyy
nb-NO          dd.MM.yyyy
nb-SJ          dd.MM.yyyy
nd             dd/MM/yyyy
nd-ZW          dd/MM/yyyy
nds            d.MM.yyyy
nds-DE         d.MM.yyyy
nds-NL         d.MM.yyyy
ne             M/d/yyyy
ne-IN          yyyy/M/d
ne-NP          M/d/yyyy
nl             d-M-yyyy
nl-AW          dd-MM-yyyy
nl-BE          d/MM/yyyy
nl-BQ          dd-MM-yyyy
nl-CW          dd-MM-yyyy
nl-NL          d-M-yyyy
nl-SR          dd-MM-yyyy
nl-SX          dd-MM-yyyy
nmg            d/M/yyyy
nmg-CM         d/M/yyyy
nn             dd.MM.yyyy
nn-NO          dd.MM.yyyy
nnh            dd/MM/yyyy
nnh-CM         dd/MM/yyyy
no             dd.MM.yyyy
nqo            dd/MM/yyyy
nqo-GN         dd/MM/yyyy
nr             yyyy-MM-dd
nr-ZA          yyyy-MM-dd
nso            yyyy-MM-dd
nso-ZA         yyyy-MM-dd
nus            d/MM/yyyy
nus-SS         d/MM/yyyy
nyn            dd/MM/yyyy
nyn-UG         dd/MM/yyyy
oc             dd/MM/yyyy
oc-FR          dd/MM/yyyy
om             dd/MM/yyyy
om-ET          dd/MM/yyyy
om-KE          dd/MM/yyyy
or             dd-MM-yy
or-IN          dd-MM-yy
os             dd.MM.yyyy
os-GE          dd.MM.yyyy
os-RU          dd.MM.yyyy
pa             dd-MM-yy
pa-Arab        dd-MM-yy
pa-Arab-PK     dd-MM-yy
pa-Guru        dd-MM-yy
pa-IN          dd-MM-yy
pap            d-M-yyyy
pap-029        d-M-yyyy
pl             dd.MM.yyyy
pl-PL          dd.MM.yyyy
prg            dd.MM.yyyy
prg-001        dd.MM.yyyy
prs            yyyy/M/d
prs-AF         yyyy/M/d
ps             yyyy/M/d
ps-AF          yyyy/M/d
ps-PK          yyyy/M/d
pt             dd/MM/yyyy
pt-AO          dd/MM/yyyy
pt-BR          dd/MM/yyyy
pt-CH          dd/MM/yyyy
pt-CV          dd/MM/yyyy
pt-GQ          dd/MM/yyyy
pt-GW          dd/MM/yyyy
pt-LU          dd/MM/yyyy
pt-MO          dd/MM/yyyy
pt-MZ          dd/MM/yyyy
pt-PT          dd/MM/yyyy
pt-ST          dd/MM/yyyy
pt-TL          dd/MM/yyyy
quc            dd/MM/yyyy
quc-Latn       dd/MM/yyyy
quc-Latn-GT    dd/MM/yyyy
quz            dd/MM/yyyy
quz-BO         dd/MM/yyyy
quz-EC         dd/MM/yyyy
quz-PE         dd/MM/yyyy
rm             dd-MM-yyyy
rm-CH          dd-MM-yyyy
rn             d/M/yyyy
rn-BI          d/M/yyyy
ro             dd.MM.yyyy
ro-MD          dd.MM.yyyy
ro-RO          dd.MM.yyyy
rof            dd/MM/yyyy
rof-TZ         dd/MM/yyyy
ru             dd.MM.yyyy
ru-BY          dd.MM.yyyy
ru-KG          dd.MM.yyyy
ru-KZ          dd.MM.yyyy
ru-MD          dd.MM.yyyy
ru-RU          dd.MM.yyyy
ru-UA          dd.MM.yyyy
rw             yyyy-MM-dd
rw-RW          yyyy-MM-dd
rwk            dd/MM/yyyy
rwk-TZ         dd/MM/yyyy
sa             dd-MM-yyyy
sa-IN          dd-MM-yyyy
sah            dd.MM.yyyy
sah-RU         dd.MM.yyyy
saq            dd/MM/yyyy
saq-KE         dd/MM/yyyy
sbp            dd/MM/yyyy
sbp-TZ         dd/MM/yyyy
sd             dd/MM/yyyy
sd-Arab        dd/MM/yyyy
sd-Arab-PK     dd/MM/yyyy
sd-Deva        dd/MM/yyyy
sd-Deva-IN     dd/MM/yyyy
se             yyyy-MM-dd
se-FI          d.M.yyyy
se-NO          yyyy-MM-dd
se-SE          yyyy-MM-dd
seh            d/M/yyyy
seh-MZ         d/M/yyyy
ses            d/M/yyyy
ses-ML         d/M/yyyy
sg             d/M/yyyy
sg-CF          d/M/yyyy
shi            d/M/yyyy
shi-Latn       d/M/yyyy
shi-Latn-MA    d/M/yyyy
shi-Tfng       d/M/yyyy
shi-Tfng-MA    d/M/yyyy
si             yyyy-MM-dd
si-LK          yyyy-MM-dd
sk             d. M. yyyy
sk-SK          d. M. yyyy
sl             d. MM. yyyy
sl-SI          d. MM. yyyy
sma            yyyy-MM-dd
sma-NO         dd.MM.yyyy
sma-SE         yyyy-MM-dd
smj            yyyy-MM-dd
smj-NO         dd.MM.yyyy
smj-SE         yyyy-MM-dd
smn            d.M.yyyy
smn-FI         d.M.yyyy
sms            d.M.yyyy
sms-FI         d.M.yyyy
sn             yyyy-MM-dd
sn-Latn        yyyy-MM-dd
sn-Latn-ZW     yyyy-MM-dd
so             dd/MM/yyyy
so-DJ          dd/MM/yyyy
so-ET          dd/MM/yyyy
so-KE          dd/MM/yyyy
so-SO          dd/MM/yyyy
sq             d.M.yyyy
sq-AL          d.M.yyyy
sq-MK          d.M.yyyy
sq-XK          d.M.yyyy
sr             d.M.yyyy.
sr-Cyrl        dd.MM.yyyy.
sr-Cyrl-BA     d.M.yyyy.
sr-Cyrl-ME     d.M.yyyy.
sr-Cyrl-RS     dd.MM.yyyy.
sr-Cyrl-XK     d.M.yyyy.
sr-Latn        d.M.yyyy.
sr-Latn-BA     d.M.yyyy.
sr-Latn-ME     d.M.yyyy.
sr-Latn-RS     d.M.yyyy.
sr-Latn-XK     d.M.yyyy.
ss             yyyy-MM-dd
ss-SZ          yyyy-MM-dd
ss-ZA          yyyy-MM-dd
ssy            dd/MM/yyyy
ssy-ER         dd/MM/yyyy
st             yyyy-MM-dd
st-LS          yyyy-MM-dd
st-ZA          yyyy-MM-dd
sv             yyyy-MM-dd
sv-AX          yyyy-MM-dd
sv-FI          dd-MM-yyyy
sv-SE          yyyy-MM-dd
sw             dd/MM/yyyy
sw-CD          dd/MM/yyyy
sw-KE          dd/MM/yyyy
sw-TZ          dd/MM/yyyy
sw-UG          dd/MM/yyyy
syr            dd/MM/yyyy
syr-SY         dd/MM/yyyy
ta             dd-MM-yyyy
ta-IN          dd-MM-yyyy
ta-LK          d/M/yyyy
ta-MY          d/M/yyyy
ta-SG          d/M/yyyy
te             dd-MM-yyyy
te-IN          dd-MM-yyyy
teo            dd/MM/yyyy
teo-KE         dd/MM/yyyy
teo-UG         dd/MM/yyyy
tg             dd.MM.yyyy
tg-Cyrl        dd.MM.yyyy
tg-Cyrl-TJ     dd.MM.yyyy
th             d/M/yyyy
th-TH          d/M/yyyy
ti             dd/MM/yyyy
ti-ER          dd/MM/yyyy
ti-ET          dd/MM/yyyy
tig            dd/MM/yyyy
tig-ER         dd/MM/yyyy
tk             dd.MM.yy 'ý.'
tk-TM          dd.MM.yy 'ý.'
tn             yyyy-MM-dd
tn-BW          yyyy-MM-dd
tn-ZA          yyyy-MM-dd
to             d/M/yyyy
to-TO          d/M/yyyy
tr             d.MM.yyyy
tr-CY          d.MM.yyyy
tr-TR          d.MM.yyyy
ts             yyyy-MM-dd
ts-ZA          yyyy-MM-dd
tt             dd.MM.yyyy
tt-RU          dd.MM.yyyy
twq            d/M/yyyy
twq-NE         d/M/yyyy
tzm            dd-MM-yyyy
tzm-Arab       d/M/yyyy
tzm-Arab-MA    d/M/yyyy
tzm-Latn       dd-MM-yyyy
tzm-Latn-DZ    dd-MM-yyyy
tzm-Latn-MA    dd/MM/yyyy
tzm-Tfng       dd-MM-yyyy
tzm-Tfng-MA    dd-MM-yyyy
ug             yyyy-M-d
ug-CN          yyyy-M-d
uk             dd.MM.yyyy
uk-UA          dd.MM.yyyy
ur             dd/MM/yyyy
ur-IN          d/M/yy
ur-PK          dd/MM/yyyy
uz             dd/MM/yyyy
uz-Arab        dd/MM yyyy
uz-Arab-AF     dd/MM yyyy
uz-Cyrl        dd/MM/yyyy
uz-Cyrl-UZ     dd/MM/yyyy
uz-Latn        dd/MM/yyyy
uz-Latn-UZ     dd/MM/yyyy
vai            dd/MM/yyyy
vai-Latn       dd/MM/yyyy
vai-Latn-LR    dd/MM/yyyy
vai-Vaii       dd/MM/yyyy
vai-Vaii-LR    dd/MM/yyyy
ve             yyyy-MM-dd
ve-ZA          yyyy-MM-dd
vi             dd/MM/yyyy
vi-VN          dd/MM/yyyy
vo             yyyy-MM-dd
vo-001         yyyy-MM-dd
vun            dd/MM/yyyy
vun-TZ         dd/MM/yyyy
wae            yyyy-MM-dd
wae-CH         yyyy-MM-dd
wal            dd/MM/yyyy
wal-ET         dd/MM/yyyy
wo             dd/MM/yyyy
wo-SN          dd/MM/yyyy
xh             yyyy-MM-dd
xh-ZA          yyyy-MM-dd
xog            dd/MM/yyyy
xog-UG         dd/MM/yyyy
yav            d/M/yyyy
yav-CM         d/M/yyyy
yi             dd/MM/yyyy
yi-001         dd/MM/yyyy
yo             d/M/yyyy
yo-BJ          d/M/yyyy
yo-NG          d/M/yyyy
zgh            d/M/yyyy
zgh-Tfng       d/M/yyyy
zgh-Tfng-MA    d/M/yyyy
zh             yyyy/M/d
zh-CN          yyyy/M/d
zh-Hans        yyyy/M/d
zh-Hans-HK     d/M/yyyy
zh-Hans-MO     d/M/yyyy
zh-Hant        d/M/yyyy
zh-HK          d/M/yyyy
zh-MO          d/M/yyyy
zh-SG          d/M/yyyy
zh-TW          yyyy/M/d
zu             M/d/yyyy
zu-ZA          M/d/yyyy

There are 573 cultures that prefer dd and 284 that prefer d, so I took the list of cultures with d and I added my own toFormatFixed method to luxon DateTime prototype:

declare module "luxon" {
  interface DateTime {
    toFormatFixed(format: string, options?: DateTimeFormatOptions): string;
  }
}

const oneDigitCulture = new Set([
  "agq", "agq-CM",
  "ar-001", "ar-DJ", "ar-ER", "ar-IL", "ar-KM", "ar-MR", "ar-PS", "ar-SD", "ar-SO", "ar-SS", "ar-TD",
  "ast", "ast-ES",
  "bas", "bas-CM",
  "bg", "bg-BG",
  "bin", "bin-NG",
  "bm", "bm-Latn", "bm-Latn-ML",
  "bn", "bn-BD",
  "bo", "bo-CN",
  "brx", "brx-IN",
  "bs", "bs-Cyrl", "bs-Cyrl-BA", "bs-Latn", "bs-Latn-BA",
  "ca", "ca-AD", "ca-ES", "ca-ES-valencia", "ca-FR", "ca-IT",
  "ccp", "ccp-Cakm", "ccp-Cakm-BD", "ccp-Cakm-IN",
  "ceb", "ceb-Latn", "ceb-Latn-PH",
  "chr", "chr-Cher", "chr-Cher-US",
  "dje", "dje-NE",
  "dsb", "dsb-DE",
  "dua", "dua-CM",
  "dyo", "dyo-SN",
  "ee", "ee-GH", "ee-TG",
  "el", "el-CY", "el-GR",
  "en", "en-AS", "en-AU", "en-BI", "en-GU", "en-HK", "en-JM", "en-MH", "en-MP", "en-MY", "en-NZ", "en-PR", "en-SG", "en-UM", "en-US", "en-VI", "en-ZW",
  "es-419", "es-AR", "es-BO", "es-BR", "es-BZ", "es-CO", "es-CR", "es-CU", "es-DO", "es-EC", "es-GQ", "es-GT", "es-HN", "es-NI", "es-PE", "es-PH", "es-PY", "es-SV", "es-US", "es-UY", "es-VE",
  "eu", "eu-ES",
  "ewo", "ewo-CM",
  "ff-Latn-BF", "ff-Latn-CM", "ff-Latn-GH", "ff-Latn-GM", "ff-Latn-GN", "ff-Latn-GW", "ff-Latn-LR", "ff-Latn-MR", "ff-Latn-NE", "ff-Latn-NG", "ff-Latn-SL",
  "fi", "fi-FI",
  "fil", "fil-PH",
  "ha", "ha-Latn", "ha-Latn-GH", "ha-Latn-NE", "ha-Latn-NG",
  "haw", "haw-US",
  "hr", "hr-BA", "hr-HR",
  "hsb", "hsb-DE",
  "ibb", "ibb-NG",
  "ig", "ig-NG",
  "ii", "ii-CN",
  "is", "is-IS",
  "iu", "iu-Cans", "iu-Cans-CA", "iu-Latn", "iu-Latn-CA",
  "kab", "kab-DZ",
  "kea", "kea-CV",
  "khq", "khq-ML",
  "ko-KP",
  "kr", "kr-Latn", "kr-Latn-NG",
  "ks", "ks-Arab", "ks-Arab-IN",
  "ksf", "ksf-CM",
  "ksh", "ksh-DE",
  "ky", "ky-KG",
  "lkt", "lkt-US",
  "ln", "ln-AO", "ln-CD", "ln-CF", "ln-CG",
  "lo", "lo-LA",
  "lu", "lu-CD",
  "mfe", "mfe-MU",
  "ml", "ml-IN",
  "mn-Mong", "mn-Mong-CN", "mn-Mong-MN",
  "moh", "moh-CA",
  "ms", "ms-BN", "ms-MY", "ms-SG",
  "mua", "mua-CM",
  "nds", "nds-DE", "nds-NL",
  "ne", "ne-IN", "ne-NP",
  "nl", "nl-BE", "nl-NL",
  "nmg", "nmg-CM",
  "nus", "nus-SS",
  "pap", "pap-029",
  "prs", "prs-AF",
  "ps", "ps-AF", "ps-PK",
  "rn", "rn-BI",
  "se-FI",
  "seh", "seh-MZ",
  "ses", "ses-ML",
  "sg", "sg-CF",
  "shi", "shi-Latn", "shi-Latn-MA", "shi-Tfng", "shi-Tfng-MA",
  "sk", "sk-SK",
  "sl", "sl-SI",
  "smn", "smn-FI",
  "sms", "sms-FI",
  "sq", "sq-AL", "sq-MK", "sq-XK",
  "sr", "sr-Cyrl-BA", "sr-Cyrl-ME", "sr-Cyrl-XK", "sr-Latn", "sr-Latn-BA", "sr-Latn-ME", "sr-Latn-RS", "sr-Latn-XK",
  "ta-LK", "ta-MY", "ta-SG",
  "th", "th-TH",
  "to", "to-TO",
  "tr", "tr-CY", "tr-TR",
  "twq", "twq-NE",
  "tzm-Arab", "tzm-Arab-MA",
  "ug", "ug-CN",
  "ur-IN",
  "yav", "yav-CM",
  "yo", "yo-BJ", "yo-NG",
  "zgh", "zgh-Tfng", "zgh-Tfng-MA",
  "zh", "zh-CN", "zh-Hans", "zh-Hans-HK", "zh-Hans-MO", "zh-Hant", "zh-HK", "zh-MO", "zh-SG", "zh-TW",
  "zu", "zu-ZA"
]);

DateTime.prototype.toFormatFixed = function toFormatWithFixes(this: DateTime, format: string, options ?: Intl.DateTimeFormatOptions){

  if (!oneDigitCulture.has(this.locale)) {

    if (format == "D")
      return this.toLocaleString({ year: "numeric", month: "2-digit", day: "2-digit", ...options });

    if (format == "f")
      return this.toLocaleString({ year: "numeric", month: "2-digit", day: "2-digit", hour: "numeric", minute: "numeric", ...options });

    if (format == "f")
      return this.toLocaleString({ year: "numeric", month: "2-digit", day: "2-digit", hour: "numeric", minute: "numeric", second: "numeric", ...options });
  }

  if (format == "EE") //missing
    return this.toFormat("EEE", options).substr(0, 2);

  return this.toFormat(format, options)

}

Hope it helps someone!

ksaadDE commented 12 months ago

Germany (de-DE) like most countries uses dd.MM.yyyy therefore a d.M.Y or dd.M.Y (or wtv) would is just wrong when using D in the Luxon formatter.

It does not only lead to confusion! For example, in a court case, the court could assume that all data from a system with such formatting issues is legally invalid as it is not compliant with the norm specifications of date and time formatting. Therefore it is strongly recommended to implement that either via DATE_LONG_FORMAT or qD or an additional func

The additional fix via raw settings is a bad idea, because for example Tabulator JS (a js data table tool like DataTables or GridJS) uses Luxon's outputformatter like that:

                    column.formatterParams = {
                        inputFormat:"yyyy-MM-ddTHH:ss",
                        outputFormat: "D z", //outputFormat:"dd/MM/yy HH:ss",
                        invalidPlaceholder:"(invalid date)",
                        timezone:"Europe/Berlin",
                    };

Doing this manually would require me to detect the country and localize it manually, a stupid approach that easily doubles my work! Which substantiates the previous argumentation even further. Despite I have a TZ option, which does not really help^^

At best Luxon just auto detects the right Timezone from the User's browser and determines the right datetime format based on the TZ. Basically like it already does, just a little bit more advanced. Though I agree, that is also a implementation thing on the user's side. For example, the Tabulator's devs would be required to implement it. But if it's already in the library everyone profits from it and it's one-time work for everyone. Still, there is no reason why the formatting is wrong (means 03.8 != 3.8 != 03.08)

icambron commented 12 months ago

@ksaadDE Your time zone and your locale are independent facts. Luxon uses both the system's default locale and its default time zone automatically, and gives you options to override both or either of those.

# running node with locale and TZ settings, same as the user's computer having a TZ set and a system locale set
❯ LANG=fr TZ=Australia/Sydney node                                                                                                                                                                                                                                                                                                              
Welcome to Node.js v20.5.1.                                                                                                                                                                                                                                                                                                                     
Type ".help" for more information.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
> { DateTime } = require("luxon")    
// snip                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
> DateTime.now().toFormat("DDDD")                                                                                                                                                                                                                                                                                                               
'lundi 13 novembre 2023'                                                                                                                                                                                                                                                                                                                        
> DateTime.now().toISO()                                                                                                                                                                                                                                                                                                                        
'2023-11-13T10:00:37.992+11:00'       

The whole point of "D" is that is, in fact, localized, using--by default--the user's locale. You can of course override this if for some reason you want to format something in a specific locale and make D mean the right thing there:

> DateTime.now().setLocale("de").toFormat("DDDD")                                                                                                                                                                                                                                                                                               
'Montag, 13. November 2023'      

If you want to externally specify a specific locale, you should do that independent of the zone (e.g. what happens when Germans travel?); in your case, that is presumably another parameter.

ksaadDE commented 11 months ago

@icambron Sorry if I did not point out (enough) the difference between locale and tz as well their independence. Though this was not my point.

My point was: a German wants to see the following format: 'dd.mm.YYYY HH:ii:ss' (01.02.2023 11:12:03). If a German travels they obviously wants to see this format everywhere. Although there are people, of course, wanting to see the current place's format. You are right this would be achieved by setLocale (although we were talking about D and not four-times D).

I agree to your point of view, that it is smarter to split language (locale or country wtv) and the timezone. Despite most systems automatically use the format of the region (Berlin) e.g. if you set the time to Europe/Berlin or some times Central European Time (CET) . That is why I used that argument.

Another aspect is the usage in web systems, where the user profile specifies the language (or tz) thus the format.

I looked it up in the docs of Tabulator.js and seemingly there's no option to set the locale for Luxon in that configuration: https://tabulator.info/docs/5.5/format#formatter-datetimediff and section above it - seemingly I have to ask there too.

Luxon uses both the system's default locale and its default time zone automatically, and gives you options to override both or either of those

Not in my test. For some reason it showed only the English format in a German Browser for CET / Berlin Time.

Opened issue in Tabulator for that: https://github.com/olifolkerd/tabulator/issues/4332

diesieben07 commented 11 months ago

If you do not set Settings.defaultLocale in Luxon then Luxon will not pass a locale key to any Intl.DateTimeFormat it creates. This will let the browser figure out the correct locale. If this does not have the desired effect for you, check if Intl.DateTimeFormat behaves the way you expect without a locale. If not, that would be either a browser misconfiguration or a browser bug.

ksaadDE commented 11 months ago

If you do not set Settings.defaultLocale in Luxon then Luxon will not pass a locale key to any Intl.DateTimeFormat it creates. This will let the browser figure out the correct locale. If this does not have the desired effect for you, check if Intl.DateTimeFormat behaves the way you expect without a locale. If not, that would be either a browser misconfiguration or a browser bug.

Sometimes it works, sometimes not. But I have often discovered issues with Luxon in this regard. Though I also highly criticize the way it is implemented in Tabulator, where I need the correct settings/implementation. Sadly, I can't magically modify the foundations of the Luxon implementation, as they are hidden in Tabulator's code. :(