Generating an ordinal number for the day of the month I am relatively new to programming and came across an if statement that I believe to be a bit verbose. I have tested my code and it appears to work without any issues, but I am wanting to know if there is a more efficient means or better shorthand of an if statement checking "day".

NSDate *now = [[NSDate alloc] init];
NSLog(@"The date is %@", now);

double seconds = [now timeIntervalSince1970];
NSLog(@"It has been %f seconds since the start of 1970.", seconds);

NSCalendar *cal = [NSCalendar currentCalendar];
NSLog(@"My calendar is %@", [cal calendarIdentifier]);

unsigned long day = [cal ordinalityOfUnit:NSCalendarUnitDay
                         inUnit:NSCalendarUnitMonth
                         forDate:now];

if (day == 1 || day == 21 || day == 31) {
        NSLog(@"Today is the %lust day of the month", day);
    } else if (day == 2 || day == 22) {
        NSLog(@"Today is the %lund day of the month", day);
    } else if (day == 3 || day == 23) {
        NSLog(@"Today is the %lurd day of the month", day);
    } else {
        NSLog(@"Today is the %luth day of the month", day);
    }
The problem of formatting an ordinal number is a general one that applies to more than just 31 days of a month.  You also have repetition of much of the string @"Today is the %lu?? day of the month".  Therefore, I suggest defining a separate function for handling this problem.  Taking inspiration from NSNumberFormatter and 'th' 'st' 'nd' 'rd' (ordinal) number endings, I would write:

NSString* const ordinalNumberSuffix(NSUInteger num) {
    if ((num / 10) % 10 == 1) {
        return @"th";       // Special cases 11th, 12th, 13th
    } 
    switch (num % 10) {
        case 1:  return @"st";
        case 2:  return @"nd";
        case 3:  return @"rd";
        default: return @"th";
    }
}


Then you can call

NSLog(@"Today is the %lu%@ day of the month", day, ordinalNumberSuffix(day));