date-fns icon indicating copy to clipboard operation
date-fns copied to clipboard

Localized format needed for day and month (PPP without year)

Open juiceo opened this issue 4 years ago • 11 comments

A rather common use case is to display a date such as "May 29th", and there does not exist a standalone format for this type of day-and-month string. These localizations already exist as part of the PPP format, but that includes the year, which for many use cases is undesirable.

Is there a way to achieve this currently, and if not, can we have a new format which would be just PPP without the year? :-)

juiceo avatar Sep 15 '20 12:09 juiceo

Up.

I am also struggling to find a way to do this without having to use Intl, as adding it to a React Native app increases its size substantially.

It is possible to have a format that manually have the day and then the month, but it isn't multi-language friendly as the orders differs.

ftzi avatar Nov 28 '20 19:11 ftzi

And, unfortunately, seems that all translations files hardcodes the year into the long format.

As reworking the entire lib to allow a better control over the outputted info doesn't seem to be a viable option, maybe adding a new format for just the long day-month format and adding it to all translation files is a better option.

Edit: My use case is a section header for lists, that like Whatsapp, only displays the year of the following messages if it isn't the same as the current year.

ftzi avatar Nov 28 '20 19:11 ftzi

Yes, Localized day/month format without year is needed. My use case is in chart ticks. I don't want to repeat the year on every tick mark. takes way too much space and makes it much harder to read the chart.

jukkahuuskonen avatar Feb 16 '21 08:02 jukkahuuskonen

Seconding this, feature makes lot of sense, also for i.e. listing a birthday (without year).

When you are building a Web Application you can utilize the browser built in Date.toLocaleDateString, which has decent browser and node support.

new Date().toLocaleDateString('en-US', {
   month: 'numeric',
   day: 'numeric',
});
// en-US -> 2/18
// de -> 18.2.
new Date().toLocaleDateString('en-US', {
   month: 'long',
   day: 'numeric',
});
// en-US -> February 18
// de -> 18. Februar

robertvanhoesel avatar Feb 23 '21 09:02 robertvanhoesel

Any news on how to achieve this ?

trouba avatar Oct 26 '21 09:10 trouba

I came across this issue also.

metuuu avatar Nov 03 '21 10:11 metuuu

I also have this need, do we have some news about it?

a-audusseau avatar Apr 14 '22 08:04 a-audusseau

I also have to build a workaround just to achieve this when switching between de and en

RinZero avatar Apr 19 '22 10:04 RinZero

I was struggling with this as well, as I wanted to achieve "May 15th" and couldn't with a date-fns parse function alone. In the end however, it turns out they do have a way to do it when passing the following STRING into the date-fns format function: STRING = MMMM do format(parseISO(some-date-string), STRING)

MMMM --> as per https://date-fns.org/v2.22.1/docs/format#:~:text=MMMM,January%2C%20February%2C%20...%2C%20December

do --> as per https://date-fns.org/v2.22.1/docs/format#:~:text=do,1st%2C%202nd%2C%20...%2C%2031st

Alef5750 avatar May 18 '22 10:05 Alef5750

I was struggling with this as well, as I wanted to achieve "May 15th" and couldn't with a date-fns parse function alone. In the end however, it turns out they do have a way to do it when passing the following STRING into the date-fns format function: STRING = MMMM do format(parseISO(some-date-string), STRING)

MMMM --> as per https://date-fns.org/v2.22.1/docs/format#:~:text=MMMM,January%2C%20February%2C%20...%2C%20December

do --> as per https://date-fns.org/v2.22.1/docs/format#:~:text=do,1st%2C%202nd%2C%20...%2C%2031st

The question here was having a localized date format without year. This answer has nothing to do with localized formatting.

jukkahuuskonen avatar Aug 15 '22 07:08 jukkahuuskonen

I have a use case with users in different timezones looking at reports from devices that also can be on different timezones and I needed the date (comes from those devices in UTC time) formatted in user locale and showed in the device local time instead of user local time.

if you do not need to take into account any timezonechanges then this should be enough:

yourDate.toLocaleString(locale, { day: '2-digit', month: '2-digit });

I wrote this that seems to handle all my use case requirements. It requires the usage of date-fns-tz to get the timezoneoffset for the device timezone. Formatting options can be found from HERE. Default here is just day and month, but you can basically do anything with it. I'm using this inside a custom hook and I hope I didn't make any major mistakes converting it to regular function.

  const localizedCustomDateString = (
    utcTime = 0,                                         // device report timestamp in UTC (ms)
    {
       locale = 'en-UK',                                 // user locale
       timezone = 'Europe/London',                       // device timezone
       options = { month: '2-digit', day: '2-digit' } }  // formatting options
  ) => {
    if (typeof utcTime !== 'number') {
      const error = new Error('localizedDateWoYear: utcTime must be a number');
      throw error;
    }
    const localTimezoneOffset = new Date().getTimezoneOffset() * 60 * 1000;
    const timezoneOffset = getTimezoneOffset(timezone);
    const totalTimezoneOffset = timezoneOffset - localTimezoneOffset;
    const localizedDate = new Date(utcTime + totalTimezoneOffset);
    return localizedDate.toLocaleString(locale, options);
  };

jukkahuuskonen avatar Aug 16 '22 08:08 jukkahuuskonen

this would be indeed very useful

popoleeMaster avatar Mar 15 '23 09:03 popoleeMaster

I was struggling with this as well, as I wanted to achieve "May 15th" and couldn't with a date-fns parse function alone. In the end however, it turns out they do have a way to do it when passing the following STRING into the date-fns format function: STRING = MMMM do format(parseISO(some-date-string), STRING)

MMMM --> as per https://date-fns.org/v2.22.1/docs/format#:~:text=MMMM,January%2C%20February%2C%20...%2C%20December

do --> as per https://date-fns.org/v2.22.1/docs/format#:~:text=do,1st%2C%202nd%2C%20...%2C%2031st

unfortunately this is not localization-safe as this places Month in front of day and this won't work in all languages. What is wanted is to achieve MM/DD in localizations that naturally use this nomination and DD/MM otherwise, or even Day Mo/Mo Day.

There seems to be 2 open issues for this implementation right now :

  • https://github.com/date-fns/date-fns/issues/2929
  • https://github.com/date-fns/date-fns/issues/3298

First one description seems more general. I will try to take a look in the code to see if I can provide an implementation for this feature whenever I get some time.

dariogliendo avatar Jul 19 '23 16:07 dariogliendo