The 2-digit
option in the Intl.DateTimeFormat
API doesn't always do what you might expect. In particular, this piece of code doesn't produce a 2-digit number:
new Intl.DateTimeFormat('en-US', {minute: '2-digit'}).format(dt) === "4" // doesn't this look like it should be "04"?
However, it turns out this is not strictly a bug.
Internally, this is looking for a "best fit" pattern from the locale data. Apparently, patterns are only available for commonly used date formats, so for example "year/month/day" or "hour:minute", and when it can't find one for, in this case, "only the month value", it doesn't actually format the month with 2 digits. Why it still returns the single digit is, to me, a mystery.
So, a possible solution could be using the formatToParts
method, which returns each part of the formatted date string in a data structure we can use:
const formatter = new Intl.DateTimeFormat('en-US', {
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false,
});
const dt = Date.parse('2000-01-02T03:04:05');
// This looks like: [{"type":"month","value":"01"}, {"type":"literal","value":"/"}, {"type":"day","value":"02"}...]
const parts = formatter.formatToParts(dt);
// Some "reduce" magic to extract the parts
const {year, month, day, hour, minute, second} = parts.reduce((acc, cur) => {acc[cur.type] = cur.value; return acc;}, {});
// Let's render it however we want now! three guesses as to what file format this is part of.
`${year}/${month}/${day}/${hour}:${minute}:${second}` === "2000/01/02/03:04:05"
And then they wonder why we use Moment.js...