JavaScript new Date Ordinal (st, nd, rd, th)

JavascriptDateOrdinal Indicator

Javascript Problem Overview


If at all possible, without JavaScript libraries or lots of clunky code I am looking for the simplest way to format a date two weeks from now in the following format:

13th March 2013

The code I am using is:

var newdate = new Date(+new Date + 12096e5);
document.body.innerHTML = newdate;

which returns the date and time two weeks from now, but like this: Wed Mar 27 2013 21:50:29 GMT+0000 (GMT Standard Time)

Here is the code in jsFiddle.

Any help would be appreciated!

Javascript Solutions


Solution 1 - Javascript

Note this works for day numbers from 1 to 31.

const nth = function(d) {
  if (d > 3 && d < 21) return 'th';
  switch (d % 10) {
    case 1:  return "st";
    case 2:  return "nd";
    case 3:  return "rd";
    default: return "th";
  }
}

// test code

const fortnightAway = new Date(+new Date + 12096e5);
const date = fortnightAway.getDate();
const month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][fortnightAway.getMonth()];

document.getElementById("date").innerHTML = `In two weeks it will be the ${date}<sup>${nth(date)}</sup> of ${month} ${fortnightAway.getFullYear()}`;

// test
const dates = [...Array(32).keys()].slice(1).map(i => `${i}${nth(i)}`)
console.log(dates.join(", "))

sup {
  font-size: x-small
}

<span id="date"></span>

Here is a version for any number

const nth = function(d) {
  const dString = String(d);
  const last = +dString.slice(-2);
  if (last > 3 && last < 21) return 'th';
  switch (last % 10) {
    case 1:  return "st";
    case 2:  return "nd";
    case 3:  return "rd";
    default: return "th";
  }
}

// test
const numbers = [...Array(1225).keys()].map(i => `${i}${nth(i)}`)
console.log(numbers.join(", "))

sup {
  font-size: x-small
}

<span id="date"></span>

Solution 2 - Javascript

Here is a one liner inspired by the other answers. It is tested and will take 0 and negative numbers.

function getOrdinalNum(n) {
  return n + (n > 0 ? ['th', 'st', 'nd', 'rd'][(n > 3 && n < 21) || n % 10 > 3 ? 0 : n % 10] : '');
}

Update 2020-06-23. The following is a better readable answer of the function above:

const getOrdinalNum = (number) => {
  let selector;

  if (number <= 0) {
    selector = 4;
  } else if ((number > 3 && number < 21) || number % 10 > 3) {
    selector = 0;
  } else {
    selector = number % 10;
  }

  return number + ['th', 'st', 'nd', 'rd', ''][selector];
};


Solution 3 - Javascript

I was doing this for dates as well, but because the day of month can only be between 1 and 31, I ended up with a simplified solution.

function dateOrdinal(dom) {
    if (dom == 31 || dom == 21 || dom == 1) return dom + "st";
    else if (dom == 22 || dom == 2) return dom + "nd";
    else if (dom == 23 || dom == 3) return dom + "rd";
    else return dom + "th";
};

or compact version using conditional operators

function dateOrdinal(d) {
    return d+(31==d||21==d||1==d?"st":22==d||2==d?"nd":23==d||3==d?"rd":"th")
};

http://jsben.ch/#/DrBpl

Solution 4 - Javascript

Lots of formatting answers, so I'll just work on the nth of any integer-

Number.prototype.nth= function(){
	if(this%1) return this;
	var s= this%100;
	if(s>3 && s<21) return this+'th';
	switch(s%10){
		case 1: return this+'st';
		case 2: return this+'nd';
		case 3: return this+'rd';
		default: return this+'th';
	}
}

Solution 5 - Javascript

Here's a simple function that works with any number:

function getOrdinal(n) {
    let ord = ["st", "nd", "rd"]
    let exceptions = [11, 12, 13]
    let nth = 
    ord[(n % 10) - 1] == undefined || exceptions.includes(n % 100) ? "th" : ord[(n % 10) - 1]
    return n + nth
}

It can accept a number or number as a string. For example:

getOrdinal(28)        //Outputs: 28th
getOrdinal('108')     //Outputs: 108th

Solution 6 - Javascript

If you are a fan of moment.js, then you can make it with format("Do")

Examples

var newdate = new Date();
moment(newdate).format("Do MMMM YYYY")
//Returns 1st January 2020

moment("01/01/2020", "MM/DD/YYYY").format("Do")
//Returns 1st

moment("01/01/2020", "MM/DD/YYYY").format("Do MMM YYYY")
//Returns 1st Jan 2020

Solution 7 - Javascript

Lots of answers, here's another:

function addOrd(n) {
  var ords = [, 'st', 'nd', 'rd'];
  var ord, m = n % 100;
  return n + ((m > 10 && m < 14) ? 'th' : ords[m % 10] || 'th');
}

// Return date string two weeks from now (14 days) in 
// format 13th March 2013
function formatDatePlusTwoWeeks(d) {
  var months = ['January', 'February', 'March', 'April', 'May', 'June',
    'July', 'August', 'September', 'October', 'November', 'December'
  ];

  // Copy date object so don't modify original
  var e = new Date(d);

  // Add two weeks (14 days)
  e.setDate(e.getDate() + 14);
  return addOrd(e.getDate()) + ' ' + months[e.getMonth()] + ' ' + e.getFullYear();
}

console.log(formatDatePlusTwoWeeks(new Date()));

// Alternative using Intl.DateTimeFormat
function datePlusTwoWeeks(date = new Date()) {
  let d = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 14);
  let parts = new Intl.DateTimeFormat('en',{
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  }).formatToParts(d).reduce((acc, part) => {
    acc[part.type] = part.value;
    return acc;
  }, Object.create(null));
  return `${addOrd(parts.day)} ${parts.month} ${parts.year}`;
}

console.log(datePlusTwoWeeks())

Solution 8 - Javascript

One more solution in the sea of solutions.

let suffix = (day >= 4 &&  day <= 20) || (day >= 24 && day <= 30)
    ? "th"
    : ["st", "nd", "rd"][day % 10 - 1];

Solution 9 - Javascript

I'm a bit late to the party, but this should work:

function ordinal(number) {
  number = Number(number)
  if(!number || (Math.round(number) !== number)) {
    return number
  }
  var signal = (number < 20) ? number : Number(('' + number).slice(-1))
  switch(signal) {
    case 1:
      return number + 'st'
    case 2:
      return number + 'nd'
    case 3:
      return number + 'rd'
    default:
      return number + 'th'
  }
}

function specialFormat(date) {
  // add two weeks
  date = new Date(+date + 12096e5)
  var months = [
    'January'
    , 'February'
    , 'March'
    , 'April'
    , 'May'
    , 'June'
    , 'July'
    , 'August'
    , 'September'
    , 'October'
    , 'November'
    , 'December'
  ]
  var formatted = ordinal(date.getDate())
  formatted += ' ' + months[date.getMonth()]
  return formatted + ' ' + date.getFullYear()
}

document.body.innerHTML = specialFormat(new Date())

Solution 10 - Javascript

This works great for me

ordinal(n) {
    var s = ["th", "st", "nd", "rd"];
    var v = n%100;
    return n + (s[(v-20)%10] || s[v] || s[0]);
}

usage:

console.log(ordinal(11))
OUTPUT: 11th

Solution 11 - Javascript

There are a lot of good answers here already, although one that makes use of Intl.PluralRules, which standardises the classification of ordinals across locales, may still be useful.

Below are some implementations for en-GB.

jsfiddle

  • a one liner:

    console.log({one:'st',two:'nd',few:'rd',other:'th'}[new Intl.PluralRules('en-GB', { type: 'ordinal' }).select(new Date().getDate())])
    
  • a verbose example:

    const suffixMap = {
      one: 'st',
      two: 'nd',
      few: 'rd',
      other: 'th',
    };
    const locale = 'en-GB';
    const moment = new Date();
    const dayOfMonth = moment.getDate();
    const pluralRuleOptions = {
      type: 'ordinal',
    };
    const pluralRule = new Intl.PluralRules(locale, pluralRuleOptions);
    const ordinal = pluralRule.select(dayOfMonth);
    console.log(suffixMap[ordinal])
    

const suffix = { one: 'st', two: 'nd', few: 'rd', other: 'th', };

document.getElementById("tomorrow-month").innerHTML = new Intl.DateTimeFormat('en-GB', { month: 'long' }).format(new Date(Date.now() + 86400000)); document.getElementById("tomorrow-day").innerHTML = new Intl.DateTimeFormat('en-GB', { day: 'numeric' }).format(new Date(Date.now() + 86400000)); document.getElementById("tomorrow-ordinal").innerHTML = suffix[new Intl.PluralRules('en-GB', { type: 'ordinal' }).select(new Date(Date.now() + 86400000).getDate())];

document.getElementById("yesterday-month").innerHTML = new Intl.DateTimeFormat('en-GB', { month: 'long' }).format(new Date(Date.now() - 86400000)); document.getElementById("yesterday-day").innerHTML = new Intl.DateTimeFormat('en-GB', { day: 'numeric' }).format(new Date(Date.now() - 86400000)); document.getElementById("yesterday-ordinal").innerHTML = suffix[new Intl.PluralRules('en-GB', { type: 'ordinal' }).select(new Date(Date.now() - 86400000).getDate())];

Tomorrow, on , I ordered a time machine. It arrived yesterday on .

Solution 12 - Javascript

As many has mentioned, here is another answer.

This is directly based on @kennebec's answer, which I found the most simplest way to get this date Ordinal generated for given JavaScript date:

I created two prototype function as follows:

Date.prototype.getDateWithDateOrdinal = function() {
	var d = this.getDate();  // from here on I've used Kennebec's answer, but improved it.
    if(d>3 && d<21) return d+'th';
    switch (d % 10) {
        case 1:  return d+"st";
        case 2:  return d+"nd";
        case 3:  return d+"rd";
        default: return d+"th";
    }
};

Date.prototype.getMonthName = function(shorten) {
	var monthsNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
	var monthIndex = this.getMonth();
	var tempIndex = -1;
    if (monthIndex == 0){ tempIndex = 0 };
    if (monthIndex == 1){ tempIndex = 1 };
    if (monthIndex == 2){ tempIndex = 2 };
    if (monthIndex == 3){ tempIndex = 3 };
    if (monthIndex == 4){ tempIndex = 4 };
    if (monthIndex == 5){ tempIndex = 5 };
    if (monthIndex == 6){ tempIndex = 6 };
    if (monthIndex == 7){ tempIndex = 7 };
    if (monthIndex == 8){ tempIndex = 8 };
    if (monthIndex == 9){ tempIndex = 9 };
    if (monthIndex == 10){ tempIndex = 10 };
    if (monthIndex == 11){ tempIndex = 11 };

    if (tempIndex > -1) {
		this.monthName = (shorten) ? monthsNames[tempIndex].substring(0, 3) : monthsNames[tempIndex];
    } else {
    	this.monthName = "";
    }

    return this.monthName;
};

Note: just include the above prototype functions within your JS Script and use it as described bellow.

And whenever there is a JS date I need to generate the date with date ordinal I use that prototype method as follows on that JS date:

var myDate = new Date();
// You may have to check your JS Console in the web browser to see the following
console.log("date with date ordinal: "+myDate.getDateWithDateOrdinal()+" "+myDate.getMonthName()+" "+myDate.getFullYear());

// or I will update the Div. using jQuery
$('#date').html("date with date ordinal: "+myDate.getDateWithDateOrdinal()+" "+myDate.getMonthName()+" "+myDate.getFullYear());

And it will print out date with date ordinal as shown in the following live demo:

	Date.prototype.getMonthName = function(shorten) {
		var monthsNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
		var monthIndex = this.getMonth();
		var tempIndex = -1;
	    if (monthIndex == 0){ tempIndex = 0 };
	    if (monthIndex == 1){ tempIndex = 1 };
	    if (monthIndex == 2){ tempIndex = 2 };
	    if (monthIndex == 3){ tempIndex = 3 };
	    if (monthIndex == 4){ tempIndex = 4 };
	    if (monthIndex == 5){ tempIndex = 5 };
	    if (monthIndex == 6){ tempIndex = 6 };
	    if (monthIndex == 7){ tempIndex = 7 };
	    if (monthIndex == 8){ tempIndex = 8 };
	    if (monthIndex == 9){ tempIndex = 9 };
	    if (monthIndex == 10){ tempIndex = 10 };
	    if (monthIndex == 11){ tempIndex = 11 };

	    if (tempIndex > -1) {
			this.monthName = (shorten) ? monthsNames[tempIndex].substring(0, 3) : monthsNames[tempIndex];
	    } else {
	    	this.monthName = "";
	    }

	    return this.monthName;
	};

    Date.prototype.getDateWithDateOrdinal = function() {
		var d = this.getDate();  // from here on I've used Kennebec's answer, but improved it.
	    if(d>3 && d<21) return d+'th';
	    switch (d % 10) {
            case 1:  return d+"st";
            case 2:  return d+"nd";
            case 3:  return d+"rd";
            default: return d+"th";
        }
	};

	var myDate = new Date();
    // You may have to check your JS Console in the web browser to see the following
	console.log("date with date ordinal: "+myDate.getDateWithDateOrdinal()+" "+myDate.getMonthName()+" "+myDate.getFullYear());
    
    // or I will update the Div. using jQuery
    $('#date').html("date with date ordinal: "+myDate.getDateWithDateOrdinal()+" "+myDate.getMonthName()+" "+myDate.getFullYear());

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="date"></p>

.

Solution 13 - Javascript

A short and compact solution:

function format(date, tmp){
  return [
    (tmp = date.getDate()) + 
      ([, 'st', 'nd', 'rd'][/1?.$/.exec(tmp)] || 'th'),
    [ 'January', 'February', 'March', 'April',
      'May', 'June', 'July', 'August',
      'September', 'October', 'November', 'December'
    ][date.getMonth()],
    date.getFullYear()
  ].join(' ')
}


// 14 days from today

console.log('14 days from today: ' + 
  format(new Date(+new Date + 14 * 864e5)));

// test formatting for all dates within a month from today

var day = 864e5, today = +new Date;
for(var i = 0; i < 32; i++) {
  console.log('Today + ' + i + ': ' + format(new Date(today + i * day)))
}

(The compact regex-based approach for getting the ordinal suffix appears several places around the web, original source unknown)

Solution 14 - Javascript

	Date.prototype.getMonthName = function(shorten) {
		var monthsNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
		var monthIndex = this.getMonth();
		var tempIndex = -1;
	    if (monthIndex == 0){ tempIndex = 0 };
	    if (monthIndex == 1){ tempIndex = 1 };
	    if (monthIndex == 2){ tempIndex = 2 };
	    if (monthIndex == 3){ tempIndex = 3 };
	    if (monthIndex == 4){ tempIndex = 4 };
	    if (monthIndex == 5){ tempIndex = 5 };
	    if (monthIndex == 6){ tempIndex = 6 };
	    if (monthIndex == 7){ tempIndex = 7 };
	    if (monthIndex == 8){ tempIndex = 8 };
	    if (monthIndex == 9){ tempIndex = 9 };
	    if (monthIndex == 10){ tempIndex = 10 };
	    if (monthIndex == 11){ tempIndex = 11 };

	    if (tempIndex > -1) {
			this.monthName = (shorten) ? monthsNames[tempIndex].substring(0, 3) : monthsNames[tempIndex];
	    } else {
	    	this.monthName = "";
	    }

	    return this.monthName;
	};

    Date.prototype.getDateWithDateOrdinal = function() {
		var d = this.getDate();  // from here on I've used Kennebec's answer, but improved it.
	    if(d>3 && d<21) return d+'th';
	    switch (d % 10) {
            case 1:  return d+"st";
            case 2:  return d+"nd";
            case 3:  return d+"rd";
            default: return d+"th";
        }
	};

	var myDate = new Date();
    // You may have to check your JS Console in the web browser to see the following
	console.log("date with date ordinal: "+myDate.getDateWithDateOrdinal()+" "+myDate.getMonthName()+" "+myDate.getFullYear());
    
    // or I will update the Div. using jQuery
    $('#date').html("date with date ordinal: "+myDate.getDateWithDateOrdinal()+" "+myDate.getMonthName()+" "+myDate.getFullYear());

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="date"></p>

Solution 15 - Javascript

function getSuffixForDate(day) {
  const lastNumberOfTheDay = day[day.length];

  const suffixes = {
    1: () => 'st',
    21: () => 'st',
    31: () => 'st',
    2: () => 'nd',
    22: () => 'nd',
    3: () => 'rd',
    23: () => 'rd',
  };

  return suffixes[lastNumberOfTheDay] !== undefined ? `${day}${suffixes[lastNumberOfTheDay]()}` : `${day}th`;
}

const date = new Date();
const formattedDate = `${getSuffixForDate(date.getDate())} ${monthNames[date.getMonth()]} ${date.getFullYear()}`;

A human readable version...

Solution 16 - Javascript

Here's a readable, ES+ kinda version.

const getDateSuffix = (date) => {
  const thExpections = date => [11, 12, 13].some(exception => exception === date);
  const lastDigit = date % 10;

  if (thExpections(date) || lastDigit === 0 || lastDigit > 3) return `${date}th`;
  if (lastDigit === 1) return `${date}st`;
  if (lastDigit === 2) return `${date}nd`;
  return `${date}rd`;
};

const monthNames = [
  "January",
  "February",
  "March",
  "April",
  "May",
  "June",
  "July",
  "August",
  "September",
  "October",
  "November",
  "December",
];

const twoWeeksFromNow = new Date(+new Date + 12096e5);
console.log(`Two weeks from now: ${getDateSuffix(twoWeeksFromNow.getDate())} ${monthNames[twoWeeksFromNow.getMonth()]} ${twoWeeksFromNow.getFullYear()}`)

console.log(`
=================
Test date suffixes:`);
const logOutDates = new Array(31).fill(0).forEach((_, index) => console.log(getDateSuffix(index + 1)))

Solution 17 - Javascript

> without JavaScript libraries or lots of clunky code

One simple approach to achieve this is in vanilla javascript would be to use a series of three ternary statements to determine the ordinal, like this:

let dateOrdinal = 'th';

dateOrdinal = ([1, 21, 31].indexOf(dateNumber) > -1) ? 'st' : dateOrdinal;
dateOrdinal = ([2, 22].indexOf(dateNumber) > -1) ? 'nd' : dateOrdinal;
dateOrdinal = ([3, 23].indexOf(dateNumber) > -1) ? 'rd' : dateOrdinal;

It's not quite as human-readable, but you could also use a switch/case statement to make the same determination:

switch (true) {
  
  case ([1, 21, 31].indexOf(dateNumber) > -1) : let dateOrdinal = 'st'; break;
  case ([2, 22].indexOf(dateNumber) > -1) : let dateOrdinal = 'nd'; break;
  case ([3, 23].indexOf(dateNumber) > -1) : let dateOrdinal = 'rd'; break;
  default : let dateOrdinal = 'th';
}

Working Example:

// GET DATE PARTS
const dateInTwoWeeks = new Date(+new Date + 12096e5);
const dateNumber = dateInTwoWeeks.getDate();
const dateMonth = dateInTwoWeeks.toLocaleString('default', {month: 'long'});
const dateYear = dateInTwoWeeks.getFullYear();

// DETERMINE DATE ORDINAL
let dateOrdinal = 'th';

dateOrdinal = ([1, 21, 31].indexOf(dateNumber) > -1) ? 'st' : dateOrdinal;
dateOrdinal = ([2, 22].indexOf(dateNumber) > -1) ? 'nd' : dateOrdinal;
dateOrdinal = ([3, 23].indexOf(dateNumber) > -1) ? 'rd' : dateOrdinal;

// FORMAT DATE AS STRING
const dateInTwoWeeksString = `${dateNumber}${dateOrdinal} ${dateMonth} ${dateYear}`; 

document.body.textContent = dateInTwoWeeksString;

Solution 18 - Javascript

If you are a fan of dayjs, which is now preferred over moment, here is an example:

you can just do dayjs(date).format('Do') but I've included an example to show how you can use it with any format you want.

Note that date ordinality is available with Dayjs advanced formats.

var advancedFormat = require('dayjs/plugin/advancedFormat')
dayjs.extend(advancedFormat)

// date variable - your date to format eg:- 2022-04-01T21:27:00
dayjs(date).format('dddd, MMMM Do [at] h:mma')

Output for above example (2022-04-01T21:27:00):

enter image description here

Solution 19 - Javascript

I think this is pretty cool way to get the date suffix

      getDateSuffix(datePart: number): string {
        const stAr = [1, 21, 31];
        const ndAr = [2, 22];
        const rdAr = [3, 23];
    
        const suffixesRaw = [
          { suffix: 'st', numbers: stAr },
          { suffix: 'nd', numbers: ndAr },
          { suffix: 'rd', numbers: rdAr },
        ];
    
        const suffixes = suffixesRaw
          .filter(x => x.numbers.filter(y => y == datePart).length > 0)
          .map(z => z.suffix);
    
        return suffixes.length > 0 ? suffixes[0] : 'th';
      }

Solution 20 - Javascript

Super simple functional implementation:

const ordinal = (d) => {
  const nth = { '1': 'st', '2': 'nd', '3': 'rd' }
  return `${d}${nth[d] || 'th'}`
}

const monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December']

const dateString = (date) => `${ordinal(date.getDate())} ${monthNames[date.getMonth()]} ${date.getFullYear()}`

// Use like this: 
dateString(new Date()) // 18th July 2016

Solution 21 - Javascript

Strongly inspired by @user2309185's.

const ordinal = (d) => {
  return d + (['st', 'nd', 'rd'][d % 10 - 1] || 'th')
}

Solution 22 - Javascript

Here is an easy solution:

var date = today.getDate() + (today.getDate() % 10 == 1 && today.getDate() != 11 ? + 'st': (today.getDate() % 10 == 2 && today.getDate() != 12 ? + 'nd': 

(today.getDate() % 10 == 3 && today.getDate() != 13 ? + 'rd':'th')));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1635828View Question on Stackoverflow
Solution 1 - JavascriptmplungjanView Answer on Stackoverflow
Solution 2 - JavascriptThe MartinView Answer on Stackoverflow
Solution 3 - Javascriptfredli74View Answer on Stackoverflow
Solution 4 - JavascriptkennebecView Answer on Stackoverflow
Solution 5 - Javascriptcrazyideas27View Answer on Stackoverflow
Solution 6 - JavascriptAnees HameedView Answer on Stackoverflow
Solution 7 - JavascriptRobGView Answer on Stackoverflow
Solution 8 - JavascriptRutwick GangurdeView Answer on Stackoverflow
Solution 9 - JavascriptGabeView Answer on Stackoverflow
Solution 10 - JavascriptKevin MuchwatView Answer on Stackoverflow
Solution 11 - JavascriptgrenadeView Answer on Stackoverflow
Solution 12 - JavascriptRandika VishmanView Answer on Stackoverflow
Solution 13 - JavascriptTomas LangkaasView Answer on Stackoverflow
Solution 14 - Javascriptuser3516819View Answer on Stackoverflow
Solution 15 - JavascriptMatt ClaffeyView Answer on Stackoverflow
Solution 16 - JavascriptthathurtabitView Answer on Stackoverflow
Solution 17 - JavascriptRounin - Standing with UkraineView Answer on Stackoverflow
Solution 18 - JavascriptJolly GoodView Answer on Stackoverflow
Solution 19 - JavascriptArun KumarView Answer on Stackoverflow
Solution 20 - Javascriptuser2309185View Answer on Stackoverflow
Solution 21 - JavascriptAdán Sánchez de Pedro CrespoView Answer on Stackoverflow
Solution 22 - JavascriptJayView Answer on Stackoverflow