# Display numbers with ordinal suffix

**04/06/2020 17:30:01**

**ArK**

I want to display numbers as follows

- 1 as 1st,
- 2 as 2nd,
- ...,
- 150 as 150th.

How should I find the correct ordinal suffix (st, nd, rd or th) for each number in my code?

# Verified Answer (276 Votes) ✓

**06/24/2010 17:49:04**

**Iacopo**

```
$ends = array('th','st','nd','rd','th','th','th','th','th','th');
if (($number %100) >= 11 && ($number%100) <= 13)
$abbreviation = $number. 'th';
else
$abbreviation = $number. $ends[$number % 10];
```

Where `$number`

is the number you want to write. Works with any natural number.

As a function:

```
function ordinal($number) {
$ends = array('th','st','nd','rd','th','th','th','th','th','th');
if ((($number % 100) >= 11) && (($number%100) <= 13))
return $number. 'th';
else
return $number. $ends[$number % 10];
}
//Example Usage
echo ordinal(100);
```

# Answer #2 (137 Votes)

**12/09/2010 02:43:26**

**Jeremy Kauffman**

PHP has built-in functionality for this. It even handles internationalization!

```
$locale = 'en_US';
$nf = new NumberFormatter($locale, NumberFormatter::ORDINAL);
echo $nf->format($number);
```

Note that this functionality is only available in PHP 5.3.0 and later.

# Answer #3 (20 Votes)

**12/01/2011 23:11:57**

**Andrew Kozak**

This can be accomplished in a single line by leveraging similar functionality in PHP's built-in date/time functions. I humbly submit:

**Solution:**

```
function ordinalSuffix( $n )
{
return date('S',mktime(1,1,1,1,( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
}
```

**Detailed Explanation:**

The built-in `date()`

function has suffix logic for handling nth-day-of-the-month calculations. The suffix is returned when `S`

is given in the format string:

```
date( 'S' , ? );
```

Since `date()`

requires a timestamp (for `?`

above), we'll pass our integer `$n`

as the `day`

parameter to `mktime()`

and use dummy values of `1`

for the `hour`

, `minute`

, `second`

, and `month`

:

```
date( 'S' , mktime( 1 , 1 , 1 , 1 , $n ) );
```

This actually fails gracefully on values out of range for a day of the month (i.e. `$n > 31`

) but we can add some simple inline logic to cap `$n`

at 29:

```
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20))*10 + $n%10) ));
```

~~The only positive value~~(*May 2017*) this fails on is `$n == 0`

, but that's easily fixed by adding 10 in that special case:

```
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
```

**Update, May 2017**

As observed by @donatJ, the above fails above 100 (e.g. "111st"), since the `>=20`

checks are always returning true. To reset these every century, we add a filter to the comparison:

```
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n%100>=20)+($n==0))*10 + $n%10) ));
```

Just wrap it in a function for convenience and off you go!