Ordinal date formatting (st/nd/rd/th)

Hello -just getting started with Tinderbox and trying my hand at making a blog with it.

I’d like to create a string attribute that is the date of the note but with ordinals on the number, i.e. the final date looking like: Friday, 7th January, 2021.

I have a container with an OnAdd attribute $Date|=today;$NiceDate=date($Date).format("W, d MM, y"); which gets me everything except the th etc.

I have a feeling it may be a little complex for such a tiny detail but perhaps someone has solved it before or there’s a nice way. I did try searching but didn’t come across the same problem.

Thanks.

  1. Assuming $Date is a date attribute, there’s no need to say date($Date). $Date is fine. (You need to coerce the value if it’s a string, or if Tinderbox doesn’t know what it is.)

  2. As you say, the easy approach gets you MOST of the way there!

  3. What we need is function that takes a number and returns an ordinal string: “1st” or “3rd” or “25th”. That should not be too hard to write. Let’s suppose we’ve already done that. We’ll call the function ordinal().

  4. Now, you’re going to say something like $NiceDate=$Date.format("W, ")+ordinal($Date.day)+$Date.format(" MM, y");. I haven’t tested this so there may be typos, but you’re going to want something like that.

  5. I think this might be sort of fun to do — a good Czerny exercise! If you (or someone) does this, do share the result.

  6. This only works in English. A better way to do this would be to build a localized solution into date.formatter — perhaps the format code “od” for "ordinal date. I’ll look into that if there’s interest.

Thanks for that. Makes sense to concat things.

I have a function but something isn’t working. It could be all sorts of things as this is literally my first use of Tinderbox and functions. :sweat_smile:

I made one that just returns the ordinal.

function fGetOrdinal(date){
var ord:string;
var day(date.day);
if(day == 1 | day == 21 | day == 31) {ord = "st";}
if(day == 2 | day == 22) {ord = "nd";}
if(day == 3 | day == 23) {ord = "rd";}
else {ord = "th";}
return ord;
};

I also adjusted my OnAdd on the prototype to use $Created as it’s built in.

$NiceDate=$Created.format("W, d”)+fGetOrdinal($Created)+$Created.format(" MM, y");

It seems the function just returns “ord”. Further testing shows it thinks day is 15 when the date is 1/1/2022.

For now I’ll use David’s answer below and come back to figuring this out.

Sorry, I deleted it because it needed refining to take account of 11, 12 and 13…

Here’s the function:

function ordinal(iDay) {

if(iDay.substr(-1) == "1" & iDay != "11")
	{return iDay + "st";}
	
if(iDay.substr(-1) == "2" & iDay != "12")
	{return iDay + "nd";}

if(iDay.substr(-1) == "3" & iDay != "13") 
	{return iDay + "rd";}

	return iDay + "th";
}

I think that works properly now… Sorry about the confusion. Here’s the screenshot again:

3 Likes

Cheers for that. It’s unrelated but seeing how you’ve tested it is useful for me :slight_smile:

I’m actually considering making the function just return the whole string I want as it’ll be useful elsewhere.

2 Likes

and my way to do it - just another one :wink:

function ordinalFormat_db(aNumber){
	var:string myDay = aNumber.format("0");
	return myDay + ordinal_db(aNumber);
};

function ordinal_db(x){
	var:string result = "th";
	var testVal = mod(x,10);

	if(x >= 11 && x <= 13){
		result = "th";
	}
	
	if(testVal == 1){
		result = "st";
	};
	if(testVal == 2){
		result = "nd";
	};
	if(testVal == 3){
		result = "rd";
	};

	return result; 
};
1 Like