dayjs icon indicating copy to clipboard operation
dayjs copied to clipboard

Dayjs: r.ordinal is not a function at advanceFormat.js

Open Kashish-Chaudhary opened this issue 2 years ago • 15 comments

Describe the bug When I try to format the date to show ordinal for date it breaks the app and shows error r.ordinal is not a function. Code: import dayjs from 'dayjs'; import advancedFormat from 'dayjs/plugin/advancedFormat'; dayjs.extend(advancedFormat); const formattedDate = dayjs(endDate).format("MMMM Do, YYYY");

Expected behavior It should format date in this format => December 31st, 2022

Information

  • Day.js Version [1.10.7]
  • OS: [iOS]
  • Browser [chrome [100.0.4896.127]] Screenshot (116)

Kashish-Chaudhary avatar May 09 '22 22:05 Kashish-Chaudhary

@iamkun ^^

Kashish-Chaudhary avatar May 10 '22 00:05 Kashish-Chaudhary

'Do' format seems broken. Getting the same error as above

tziyang-lum avatar May 11 '22 10:05 tziyang-lum

That's correct as when we remove 'Do' in format error goes away.

Kashish-Chaudhary avatar May 13 '22 00:05 Kashish-Chaudhary

I didn't try the code in Chrome, but only on my node.js system. At least in your code above there is a typo in the second line:

import advancedFormat from 'dayjs/plugin/advanceFormat';

should be import advancedFormat from 'dayjs/plugin/advancedFormat'; (you see the 'd' before the 'Format'?)

Perhaps this was the culprit - otherwise I will have to test it on chrome ;-)

BePo65 avatar Jun 06 '22 13:06 BePo65

@BePo65 In actual implementation I used import advancedFormat from 'dayjs/plugin/advancedFormat' only but while posting I typed it wrong. I've updated it though.

Kashish-Chaudhary avatar Jun 10 '22 15:06 Kashish-Chaudhary

So I will have to test it on Chrome - will be back soon 😄

BePo65 avatar Jun 10 '22 16:06 BePo65

Tested the following code in chrome (v102.0) and Firefox (v101.0) and got this result: issue1891

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>dayjs issue 1891</title>
</head>
<body>
  <h1 id="header">dayjs issue 1891</h1>
  <p id="result">waiting...</p>
  <script src="https://unpkg.com/[email protected]/dayjs.min.js"></script>
  <script src="https://unpkg.com/[email protected]/plugin/advancedFormat.js"></script>
  <script>
    dayjs.extend(window.dayjs_plugin_advancedFormat)

    const endDate = '2022-12-31'
    const formattedDate = dayjs(endDate).format("MMMM Do, YYYY");
    document.getElementById("result").innerHTML = formattedDate;
    console.log(formattedDate)
</script>
</body>
</html>

BePo65 avatar Jun 11 '22 04:06 BePo65

@BePo65 In your implementation, it seems to work fine but I used it in React application, not sure if that affects the working. But I still see that error.

Kashish-Chaudhary avatar Jun 13 '22 14:06 Kashish-Chaudhary

HM, perhaps a type definition thing. Do you have a small demo e.g. in CodeSandbox or something like this?

BePo65 avatar Jun 26 '22 08:06 BePo65

Same problem 'Do' format seems broken. Getting the same error as above

uaday avatar Jul 05 '22 12:07 uaday

Can anybody try to fork and modify this demo to reproduce the issue? I can't reproduce this too.

Bykiev avatar Jul 14 '22 07:07 Bykiev

Perhaps @Kashish-Chaudhary could create a demo of the problem in a sandbox react playground?

I tested it with plain typescript (in my repo dayjs-typescript-demo calling npm run start:issue1891) and got no error.

BePo65 avatar Jul 14 '22 17:07 BePo65

HM, perhaps a type definition thing. Do you have a small demo e.g. in CodeSandbox or something like this?

@BePo65 FYI, here is a code to reproduce the issue.

You can reproduce this when you change the locale globally. It also happens only if you set 'en' as the locale. I tried using 'nn', 'nb', 'de' locales and the code work fine for those but not for 'en'.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>dayjs issue 1891</title>
</head>
<body>
  <h1 id="header">dayjs issue 1891</h1>
  <p id="result">waiting...</p>
  <script src="https://unpkg.com/[email protected]/dayjs.min.js"></script>
  <script src="https://unpkg.com/[email protected]/plugin/advancedFormat.js"></script>
  <script src="https://unpkg.com/[email protected]/locale/en"></script>
  <script>
    var customLocale = window.dayjs_locale_en; // this happens only when 'en' is used as the locale
    dayjs.locale({...customLocale})

    dayjs.extend(window.dayjs_plugin_advancedFormat)

    const endDate = '2022-12-31'
    const formattedDate = dayjs(endDate).format("MMMM Do, YYYY");
    document.getElementById("result").innerHTML = formattedDate;
    console.log(formattedDate)
</script>
</body>
</html>

csath avatar Aug 31 '22 04:08 csath

I can reproduce the effect with your code. The problem is the way you activate the locale.
I didn't completely find out, why the dayjs.locale({...customLocale}) works in node but not in the browser. In node it adds the ordinal function to the used locale data, in the browser it does not.

But anyway this is not the recommended way to activate a locale. IMHO the code should look like this (works on my system):

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>dayjs issue 1891</title>
</head>
<body>
  <h1 id="header">dayjs issue 1891</h1>
  <p id="result-de">waiting...</p>
  <p id="result-iso">waiting...</p>
  <p id="result-en">waiting...</p>
  <script src="https://unpkg.com/[email protected]/dayjs.min.js"></script>
  <script src="https://unpkg.com/[email protected]/plugin/advancedFormat.js"></script>
  <script src="https://unpkg.com/[email protected]/locale/de"></script>
  <script src="https://unpkg.com/[email protected]/locale/en"></script>
  <script>
    dayjs.extend(window.dayjs_plugin_advancedFormat)

    const endDate = '2022-12-31'

    dayjs.locale('de');
    const formattedDateDe = dayjs(endDate).format("MMMM Do, YYYY");
    console.log(formattedDateDe)
    document.getElementById("result-de").innerHTML = formattedDateDe;

    const formattedDateIso = dayjs(endDate).format("MMM D YYYY");
    console.log(formattedDateIso)
    document.getElementById("result-iso").innerHTML = formattedDateIso;

    dayjs.locale('en');
    const formattedDateDo = dayjs(endDate).format("MMMM Do, YYYY");
    console.log(formattedDateDo)
    document.getElementById("result-en").innerHTML = formattedDateDo;
</script>
</body>
</html>

Perhaps this helps you solve your issue :-)

BePo65 avatar Sep 01 '22 16:09 BePo65

//dayjs has an error where if you need to use the 'Do' date format, 
//there's a bug where some of locales in dayjs do not provide an ordinal, 
//so we can manually fix it by using the updateLocalePlugin and providing the ordinal:

dayjs.updateLocale('en', {
    ...
    ordinal: (n) => {
        const s = ['th', 'st', 'nd', 'rd'];
        const v = n % 100;
        return `[${n}${(s[(v - 20) % 10] || s[v] || s[0])}]`;
    ....
});

bjois avatar Sep 09 '22 21:09 bjois

I checked all locale files in the dev branch of dayjs and all contain a 'ordinal' function besides 'en' that gets a 'ordinal' function by the 'AdvancedFormat' plugin.

Did I miss a locale?

IMHO the 'ordinal' function of 'en' should be part of the core dayjs file and not of the 'AdvancedFormat' plugin.

BePo65 avatar Sep 25 '22 05:09 BePo65