Add St, Nd, Rd and Th (Ordinal) Suffix to a Number

Add st, nd, rd and th (ordinal) suffix to a number

The rules are as follows:

  • st is used with numbers ending in 1 (e.g. 1st, pronounced first)
  • nd is used with numbers ending in 2 (e.g. 92nd, pronounced ninety-second)
  • rd is used with numbers ending in 3 (e.g. 33rd, pronounced thirty-third)
  • As an exception to the above rules, all the "teen" numbers ending with 11, 12 or 13 use -th (e.g. 11th, pronounced eleventh, 112th,
    pronounced one hundred [and] twelfth)
  • th is used for all other numbers (e.g. 9th, pronounced ninth).

The following JavaScript code (rewritten in Jun '14) accomplishes this:

function ordinal_suffix_of(i) {
var j = i % 10,
k = i % 100;
if (j == 1 && k != 11) {
return i + "st";
}
if (j == 2 && k != 12) {
return i + "nd";
}
if (j == 3 && k != 13) {
return i + "rd";
}
return i + "th";
}

Sample output for numbers between 0-115:

  0  0th
1 1st
2 2nd
3 3rd
4 4th
5 5th
6 6th
7 7th
8 8th
9 9th
10 10th
11 11th
12 12th
13 13th
14 14th
15 15th
16 16th
17 17th
18 18th
19 19th
20 20th
21 21st
22 22nd
23 23rd
24 24th
25 25th
26 26th
27 27th
28 28th
29 29th
30 30th
31 31st
32 32nd
33 33rd
34 34th
35 35th
36 36th
37 37th
38 38th
39 39th
40 40th
41 41st
42 42nd
43 43rd
44 44th
45 45th
46 46th
47 47th
48 48th
49 49th
50 50th
51 51st
52 52nd
53 53rd
54 54th
55 55th
56 56th
57 57th
58 58th
59 59th
60 60th
61 61st
62 62nd
63 63rd
64 64th
65 65th
66 66th
67 67th
68 68th
69 69th
70 70th
71 71st
72 72nd
73 73rd
74 74th
75 75th
76 76th
77 77th
78 78th
79 79th
80 80th
81 81st
82 82nd
83 83rd
84 84th
85 85th
86 86th
87 87th
88 88th
89 89th
90 90th
91 91st
92 92nd
93 93rd
94 94th
95 95th
96 96th
97 97th
98 98th
99 99th
100 100th
101 101st
102 102nd
103 103rd
104 104th
105 105th
106 106th
107 107th
108 108th
109 109th
110 110th
111 111th
112 112th
113 113th
114 114th
115 115th

NSNumberFormatter and 'th' 'st' 'nd' 'rd' (ordinal) number endings

Since the question asked for a number formatter, here's a rough one I made.

//
// OrdinalNumberFormatter.h
//

#import <Foundation/Foundation.h>

@interface OrdinalNumberFormatter : NSNumberFormatter {

}

@end

and the implementation:

//
// OrdinalNumberFormatter.m
//

#import "OrdinalNumberFormatter.h"

@implementation OrdinalNumberFormatter

- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error {
NSInteger integerNumber;
NSScanner *scanner;
BOOL isSuccessful = NO;
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];

scanner = [NSScanner scannerWithString:string];
[scanner setCaseSensitive:NO];
[scanner setCharactersToBeSkipped:letters];

if ([scanner scanInteger:&integerNumber]){
isSuccessful = YES;
if (anObject) {
*anObject = [NSNumber numberWithInteger:integerNumber];
}
} else {
if (error) {
*error = [NSString stringWithFormat:@"Unable to create number from %@", string];
}
}

return isSuccessful;
}

- (NSString *)stringForObjectValue:(id)anObject {
if (![anObject isKindOfClass:[NSNumber class]]) {
return nil;
}

NSString *strRep = [anObject stringValue];
NSString *lastDigit = [strRep substringFromIndex:([strRep length]-1)];

NSString *ordinal;

if ([strRep isEqualToString:@"11"] || [strRep isEqualToString:@"12"] || [strRep isEqualToString:@"13"]) {
ordinal = @"th";
} else if ([lastDigit isEqualToString:@"1"]) {
ordinal = @"st";
} else if ([lastDigit isEqualToString:@"2"]) {
ordinal = @"nd";
} else if ([lastDigit isEqualToString:@"3"]) {
ordinal = @"rd";
} else {
ordinal = @"th";
}

return [NSString stringWithFormat:@"%@%@", strRep, ordinal];
}

@end

Instantiate this as an Interface Builder object and attach the Text Field's formatter outlet to it. For finer control (such as setting maximum and minimum values, you should create an instance of the formatter, set the properties as you wish and attach it to text field using it's setFormatter: method.

You can download the class from GitHub (including an example project)

Append ordinal suffixes ('-st', '-nd', '-rd', '-th') based on the item index

You may put necessary suffixes into array and pick the one that corresponds to your index:

const arr = [...'abcdefghijklmnopqrstuvwxyz'];const suffixes = ['th', 'st', 'nd', 'rd'];
const result = arr.map((item, i) => (idx = ~~(i % 10) + 1 > 3 || ~~(i / 10) == 1 ? 0 : ~~(i % 10) + 1, `${i+1}-${suffixes[idx]} options is '${item}'`));
console.log(result);
.as-console-wrapper {min-width: 100%}

Is there an easy way in .NET to get st, nd, rd and th endings for numbers?

No, there is no inbuilt capability in the .NET Base Class Library.

How do I retrieve an integer's ordinal suffix in Perl (like st, nd, rd, th)

Try this:

my $ordinal;
if ($foo =~ /(?<!1)1$/) {
$ordinal = 'st';
} elsif ($foo =~ /(?<!1)2$/) {
$ordinal = 'nd';
} elsif ($foo =~ /(?<!1)3$/) {
$ordinal = 'rd';
} else {
$ordinal = 'th';
}

Format for ordinal dates (day of month with suffixes -st, -nd, -rd, -th)

Enjoy the power of lubridate:

library(lubridate)    
mdy(ord_dates)

[1] "2016-09-01" "2016-09-02" "2016-09-03" "2016-09-04"

Internally, lubridate doesn't have any special conversion specifications which enable this. Rather, lubridate first uses (by smart guessing) the format "%B %dst, %Y". This gets the first element of ord_dates.

It then checks for NAs and repeats its smart guessing on the remaining elements, settling on "%B %dnd, %Y" to get the second element. It continues in this way until there are no NAs left (which happens in this case after 4 iterations), or until its smart guessing fails to turn up a likely format candidate.

You can imagine this makes lubridate slower, and it does -- about half the speed of just using the smart regex suggested by @alistaire above:

set.seed(109123)
ord_dates <- sample(
c("September 1st, 2016", "September 2nd, 2016",
"September 3rd, 2016", "September 4th, 2016"),
1e6, TRUE
)

library(microbenchmark)

microbenchmark(times = 10L,
lubridate = mdy(ord_dates),
base = as.Date(sub("\\D+,", "", ord_dates),
format = "%B %e %Y"))
# Unit: seconds
# expr min lq mean median uq max neval cld
# lubridate 2.167957 2.219463 2.290950 2.252565 2.301725 2.587724 10 b
# base 1.183970 1.224824 1.218642 1.227034 1.228324 1.229095 10 a

The obvious advantage in lubridate's favor being its conciseness and flexibility.

How do I print ordinal indicators in a C program? Can't print numbers with 'st', 'nd', 'rd'. (Beginner)

You can mod by 10 to get the last digit. Then based on that you can use "st", "nd", "rd", or "th". You'll also need special cases for 11, 12, and 13.

    if ((i % 10 == 1) && (i % 100 != 11))
printf("%dst value : ", i);
else if ((i % 10 == 2) && (i % 100 != 12))
printf("%dnd value : ", i);
else if ((i % 10 == 3) && (i % 100 != 13))
printf("%drd value : ", i);
else
printf("%dth value : ", i);

How to append th, st, nd and rd for dates of the day in rdlc report?

Using the suggestion in Is there an easy way to create ordinals in C#? you can create a Custom Code for your rdlc report and use it with the expression.

  1. In the rdlc properties add the following function in Code tab

    Public Shared Function AddOrdinal(num As Integer) As String
    If num <= 0 Then
    Return num.ToString()
    End If
    Select Case num Mod 100
    Case 11, 12, 13
    Return num & "th"
    End Select
    Select Case num Mod 10
    Case 1
    Return num & "st"
    Case 2
    Return num & "nd"
    Case 3
    Return num & "rd"
    Case Else
    Return num & "th"
    End Select
    End Function
  2. Then modify your Expression as follows

    =Code.AddOrdinal(Day(Fields!Date.value))


Related Topics



Leave a reply



Submit