Morgs
Morgs

Reputation: 1746

To 1st, 2nd, 3rd, 4th (Month days)

I have written an extension function to determine if a month day/number is 1st/31st, 2nd/22nd, 3rd or 4th....30th.

I would like to find out if there is a better/shorter or elegant way I could've written it? My function:

/// <summary>
/// To 1st, 2nd, 3rd, 4th (Month days)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static string To1st2nd3rd4th( this double n )
{
    // nFirst
    if ( new double[] { 1, 21, 31 }.Contains( n ) )
    {
        return $"{n}st";
    }

    // nSecond
    if ( new double[] { 2, 22 }.Contains( n ) )
    {
        return $"{n}nd";
    }

    // nThird
    if ( n == 3 )
    {
        return $"{n}rd";
    }

    //n-th/ n > 3
    if ( n > 3 )
    {
        return $"{n}th";
    }

    return n.ToString();
}

Upvotes: 0

Views: 479

Answers (3)

Jeff
Jeff

Reputation: 654

I think this will work for you as a general method:

        static void Main(string[] args)
    {
        Console.WriteLine(String.Join(" ", Enumerable.Range(0, 24).Select(NumberSuffix)));
        Console.WriteLine(String.Join(" ", Enumerable.Range(250, 24).Select(NumberSuffix)));
        Console.WriteLine(String.Join(" ", Enumerable.Range(10001, 24).Select(NumberSuffix)));

        Console.ReadKey();
    }

    public static string NumberSuffix2(int n)
    {
        //                           0     1     2     3     4     5     6     7     8     9      10    11    12
        string[] nth = new string[] {"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "th", "th"};

        int n2 = Math.Abs(n);

        return n + nth[(n2 % 100) % (n2 % 100 > 13 ? 10 : 13)];
    }

Output is:

0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd

250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 266th 267th 268th 269th 270th 271st 272nd 273rd

0001st 10002nd 10003rd 10004th 10005th 10006th 10007th 10008th 10009th 10010th 10011th 10012th 10013th 10014th 10015th 10016th 10017th 10018th 10019th 10020th 10021st 10022nd 10023rd 10024th

Upvotes: 0

Sach
Sach

Reputation: 10393

Your solution has few problems.

First of all, why does the day (seeing as it is a date) has to be double? So I'd use an int there.

Second, your if statements can be if-else. You'll have to add a case for it being negative or zero.

But this has the problem of not working for numbers such as 33 (sure, there isn't a 33rd day of the month, but a function should be self sufficient).

I'd rather use the Humanizer library which can do this and much more.

You can get the NuGet package, and once done it's as easy as:

Console.WriteLine("{0} ==> {1}", 1, 1.Ordinalize());
Console.WriteLine("{0} ==> {1}", 21, 21.Ordinalize());
Console.WriteLine("{0} ==> {1}", 31, 31.Ordinalize());
Console.WriteLine("{0} ==> {1}", 33, 33.Ordinalize());
Console.WriteLine("{0} ==> {1}", 2, 22.Ordinalize());
Console.WriteLine("{0} ==> {1}", 3, 3.Ordinalize());
Console.WriteLine("{0} ==> {1}", 4, 4.Ordinalize());
Console.WriteLine("{0} ==> {1}", 55, 55.Ordinalize());
Console.WriteLine("{0} ==> {1}", 1237, 1237.Ordinalize());
Console.WriteLine("{0} ==> {1}", 0, 0.Ordinalize());

Output

1 ==> 1st

21 ==> 21st

31 ==> 31st

33 ==> 33rd

2 ==> 22nd

3 ==> 3rd

4 ==> 4th

55 ==> 55th

1237 ==> 1237th

0 ==> 0th

Upvotes: 1

Raja
Raja

Reputation: 56

  private string NumberSuffix(double n)
    {
        var below100 = n % 10;
        var above100 = n % 100;

        if (below100 == 1 && above100 != 11)
        {
            return n + "st";
        }
        if (below100 == 2 && above100 != 12)
        {
            return n + "nd";
        }
        if (below100 == 3 && above100 != 13)
        {
            return n + "rd";
        }
        return n + "th";
    }

Upvotes: 0

Related Questions