JavaScript new Date Ordinal (st, nd, rd, th)
JavascriptDateOrdinal IndicatorJavascript 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")
};
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
.
-
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):
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')));