fix(common): include minutes in the short GMT timezone format#69239
fix(common): include minutes in the short GMT timezone format#69239erkamyaman wants to merge 1 commit into
Conversation
The short localized GMT format (`z`, `zz`, `zzz`, `O`) returned the hours only, so in zones with a non-zero minute offset it dropped them, for example `GMT+5` in India instead of `GMT+5:30`. Per CLDR (UTS angular#35), the short localized GMT format omits the leading zero on the hours but still includes the minutes when they are non-zero; this also affects the named `long` and `longTime` formats, which use `z`. The format now appends the minutes when they are non-zero, leaving whole-hour zones (such as `GMT-4`) unchanged. While in the same timezone-format area, this also corrects the `DatePipe` JSDoc format table, where the `ZZZZ` ("Long localized GMT format") example showed `GMT-8:00` instead of the zero-padded `GMT-08:00` that the format actually produces (and that the `OOOO` row already shows).
| case ZoneWidth.ShortGMT: { | ||
| // The short localized GMT format omits a leading zero on the hours but, | ||
| // per CLDR, still includes the minutes when they are non-zero (e.g. | ||
| // `GMT+5:30` for India, `GMT-4` for New York). | ||
| const minutes = Math.abs(zone % 60); | ||
| return ( | ||
| 'GMT' + | ||
| (zone >= 0 ? '+' : '') + | ||
| padNumber(hours, 1, minusSign) + | ||
| (minutes ? ':' + padNumber(minutes, 2, minusSign) : '') | ||
| ); | ||
| } |
There was a problem hiding this comment.
Is that true for every locale ? (the CLDR is a funny rabbithole)
There was a problem hiding this comment.
Good question, it is a bit of a rabbit hole indeed. No, the full format isn't identical across locales. I checked Intl short offsets for a +5:30 zone:
- most locales (en, de, ja, hi, tr, …): GMT+5:30
- fr: UTC+5:30 (UTC, not GMT)
- fi: UTC+5.30 (UTC and a . separator)
- ar: غرينتش+5:30 (translated label)
- fa: +۵:۳۰ گرینویچ (Persian digits, label after the offset, RTL)
So the literal, separator, digits and order are all locale-dependent. What is universal is that the minutes are kept when they're non-zero, and that's the only thing this change touches.
timeZoneGetter already renders a locale-independent GMT±H[:mm] for every locale (same as the Long/Extended widths), so this doesn't add locale divergence, it just stops the short form dropping the minutes the long form already keeps.
I can reword the code comment to call that out if you think it's worth it.
There was a problem hiding this comment.
My point is more : This is not worth fixing and users should rely on Intl if they want top-tier date i18n.
There was a problem hiding this comment.
It makes sense, agreed that Intl is the right call for proper date i18n. I'll close this out. Thanks for the look, I appreciate it.
The short localized GMT format (
z,zz,zzz,O) returned the hours only, so in zones with a non-zero minute offset it dropped them, for exampleGMT+5in India instead ofGMT+5:30. Per CLDR (UTS #35), the short localized GMT format omits the leading zero on the hours but still includes the minutes when they are non-zero; this also affects the namedlongandlongTimeformats, which usez. The format now appends the minutes when they are non-zero, leaving whole-hour zones (such asGMT-4) unchanged.While in the same timezone-format area, this also corrects the
DatePipeJSDoc format table, where theZZZZ("Long localized GMT format") example showedGMT-8:00instead of the zero-paddedGMT-08:00that the format actually produces (and that theOOOOrow already shows).PR Checklist
Please check that your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
formatDate/DatePiperenders the short localized GMT timezone format (z,zz,zzz,O, and the namedlong/longTimeformats that usez) with the hours only. In a timezone whose offset has non-zero minutes, the minutes are dropped:+5:30rendersGMT+5(should beGMT+5:30)+5:45rendersGMT+5(should beGMT+5:45)This diverges from CLDR /
Intl, whose short localized GMT format keeps non-zero minutes (Intl.DateTimeFormat('en', {timeZoneName: 'shortOffset', timeZone: 'Asia/Kolkata'})→GMT+5:30).What is the new behavior?
The short GMT format appends the minutes when they are non-zero:
+5:30→GMT+5:30+5:45→GMT+5:45-3:30→GMT-3:30GMT-4,GMT-5)The PR also fixes a small typo in the
DatePipeJSDoc format table (ZZZZexampleGMT-8:00→GMT-08:00) in the same timezone-format area.Does this PR introduce a breaking change?