Skip to content

Conversation

@rodrigost23
Copy link
Contributor

Description

Adds locale-aware dates, fixes #470.

Demo

image image

Checklist

  • I have read CONTRIBUTING.md in its entirety
  • I have performed a self-review of my own code
  • I have added unit tests to cover my changes
  • The last commit successfully passed pre-commit checks
  • Any AI code was thoroughly reviewed by me

Comment on lines +41 to +44
return format(date, 'MMM dd', {
locale: getSupportedLanguages().find((lang) => lang.code === todayTranslation.usedLng)
?.dateLocale,
});
Copy link
Collaborator

@krokosik krokosik Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we could just use new Intl.DateTimeFormat(todayTranslation.usedLng, {day: '2-digit', month: 'short'}).format(date)?

Copy link
Contributor Author

@rodrigost23 rodrigost23 Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that, but this Intl API is kind of weird. At least for pt-BR and pt-PT, the results are awful, so I'm not sure what other languages would look like to native speakers.

pt-PT:

I don't know why it would format "short" month to "11" (we have "numeric" for that, right?). 

pt-BR:

The word "de" here is just a preposition that we can totally ignore when we want it to be shorter.


Maybe we could have a specific function only for this expense date prefix and use the Intl for other places, which would probably make this look better:
 

Copy link
Collaborator

@krokosik krokosik Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a native speaker in either of these, but maybe it is simply the proper way to format this in Portugal? For the brazilian version, yeah it looks kind of bad.

Personally I would prefer fixing locale specific edge cases rather than to import the bulky date-fns locale and pass it around.

For the expense list, we could format the day and month separately and remove dots for now?

new Intl.DateTimeFormat('pt-PT', {month: 'short'}).format(new Date()).replace('.', '')

Actually returns the month name, so we could just built this in a consistent format. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting day and month separately makes sense.

Do we need to care about the order, though? Some locales use MM/DD, others DD/MM.

There’s a way to detect that order if we really want to (expand for an example)
function formatDayMonth(locale: string, date: Date): string {
  // Format day and short month separately
  const day = new Intl.DateTimeFormat(locale, { day: 'numeric' }).format(date);
  const monthName = new Intl.DateTimeFormat(locale, { month: 'short' }).format(date)
    .replace('.', '');

  // Detect whether day comes before month for this locale
  const orderParts = new Intl.DateTimeFormat(locale, {
    day: 'numeric',
    month: 'numeric'
  }).formatToParts(date);

  const dayIndex = orderParts.findIndex(p => p.type === 'day');
  const monthIndex = orderParts.findIndex(p => p.type === 'month');

  const isDayFirst = dayIndex < monthIndex;

  return isDayFirst ? `${day} ${monthName}` : `${monthName} ${day}`;
}

// Examples:
formatDayMonth('pt-BR', new Date('2025-10-11'));
// "11 out"
formatDayMonth('pt-PT', new Date('2025-10-11'));
// "11 out"
formatDayMonth('de', new Date('2025-10-11'));
// "11 Okt" 
formatDayMonth('en-GB', new Date('2025-10-11'))
// "11 Oct" 
formatDayMonth('en-US', new Date('2025-10-11'));
// "Oct 11"
formatDayMonth('en', new Date('2025-10-11'));
// "Oct 11" 
formatDayMonth('zh', new Date('2025-10-11'))
// "10月 11日"

Feels a bit over-engineered, but it works.

In pt-BR I wouldn't mind if it stayed as "MM DD", since the layout stacks them on top of each other in the expense list.

Not sure how that reads in other locales...

What do you think? We just keep "MM DD" specifically in the expenses list for now? In that case, the following should be enough:

const day = new Intl.DateTimeFormat(todayTranslation.usedLng, { day: 'numeric' }).format(date);
const monthName = new Intl.DateTimeFormat(todayTranslation.usedLng, { month: 'short' }).format(date).replace('.', '');

return `${monthName} ${day}`;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. One change would be to change day to 2-digit maybe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dates are not localized

2 participants