Generating Well Formatted Ordinal Suffixes
I’ve got no plans on the 25st

Handling dates, whether in code or even in a PowerPoint presentation, can be surprisingly tricky. Even the way we read dates aloud is peculiar — we instinctively add the word “the” and “of” even though they are not written: “Today is Wednesday the 5th of June.”
As a teacher, I’m particular about how dates appear in my materials. It bothers me when the ordinal indicators (st, nd, rd, th) are missing, which often happens when dates are automatically inserted into slides.
The Quirk of Dates and the Quest for Clarity
As we encounter dates on our computers and across the web, we humans are generally adept at deciphering the numbers and slashes to determine the actual date. Here in the UK, we’re unphased by the US format of placing the month first — for instance, seeing “6/5/2024” on my Windows taskbar and understanding it’s not the 6th of May.
However, I’m currently developing a website where I want the date displayed exactly as I’d write it on my classroom whiteboard. A simple “Wednesday 5 June” won’t cut it.
JavaScript Function to Create Ordinal Numbers
1const getOrdinalSuffix = (inputNumber) => {2 const ordinalSuffixes = ["th", "st", "nd", "rd"];3 const lastTwoDigits = inputNumber % 100;4 return (5 inputNumber +6 (ordinalSuffixes[(lastTwoDigits - 20) % 10] ||7 ordinalSuffixes[lastTwoDigits] ||8 ordinalSuffixes[0])9 );10};Interactive Ordinal Suffix Tester
How the Logic Works:
- Setting Up the Suffixes:
ordinalSuffixes = ["th", "st", "nd", "rd"];: This array stores the four possible ordinal suffixes in English. - Finding the Relevant Digits:
lastTwoDigits = inputNumber % 100;: The modulo operator (%) calculates the remainder wheninputNumberis divided by 100. This gives us the last two digits of the number, which are the key to determining the suffix.For example, if
inputNumberis 123,lastTwoDigitswill be 23. - Adjusting for Special Cases (11, 12, 13):
(lastTwoDigits - 20) % 10: This calculation addresses the special cases where numbers ending in 11, 12, or 13 use “th” instead of the usual pattern.If
lastTwoDigitsis between 11 and 13 (inclusive), this calculation results in a negative number or zero, which fails the first lookup and falls through cleanly. - Selecting the Correct Suffix:
ordinalSuffixes[(lastTwoDigits - 20) % 10] || ordinalSuffixes[lastTwoDigits] || ordinalSuffixes[0]: This part is the core logic for selecting the suffix:- First Attempt: It tries to access the suffix using
(lastTwoDigits - 20) % 10as the index. IflastTwoDigitsis 21, 22, 23, or 31, this evaluates to 1, 2, or 3, giving the correct index for “st”, “nd”, or “rd”. - Second Attempt (Fallback): If the first attempt fails (because the index is out of bounds or points to
undefined), it tries to access the suffix directly usinglastTwoDigits. This handles single-digit numbers (1st, 2nd, 3rd). - Default: If both previous attempts fail, it defaults to
ordinalSuffixes[0], which is “th”. This handles numbers ending in 0, 4, 5, 6, 7, 8, or 9, as well as 11, 12, and 13.
- First Attempt: It tries to access the suffix using
- Returning the Ordinal Number:
inputNumber + (...): Finally, the original inputNumber is combined with the selected suffix using string concatenation (+), and the resulting ordinal number (e.g., “21st”) is returned.
Next step — superscript to the rescue
Having generated the correct ordinal suffix, the next step is to refine the presentation. After all, a well-formatted date should not only be accurate but also visually pleasing. It irks me when these ordinal indicators are not presented correctly, so this means ensuring the letters are small and raised, just as we’d write them on a whiteboard.
The below tweak builds this in with the <sup> HTML tag:
1const getOrdinalSuffix = (inputNumber) => {2 const ordinalSuffixes = ["th", "st", "nd", "rd"];3 const lastTwoDigits = inputNumber % 100;4
5 // Select the correct suffix and wrap it in <sup> tags6 const suffix =7 ordinalSuffixes[(lastTwoDigits - 20) % 10] ||8 ordinalSuffixes[lastTwoDigits] ||9 ordinalSuffixes[0];10
11 const superscriptSuffix = `<sup>${suffix}</sup>`;12
13 // Combine the input number and superscripted suffix14 return `${inputNumber}${superscriptSuffix}`;15};As someone with a mild case of typographical OCD, seeing those letters not raised and reduced in size is the digital equivalent of nails on a chalkboard. Hopefully, this exploration into the intricacies of date formatting has been as enlightening for you as it’s been therapeutic for me!