¿Hay alguna manera fácil en .NET para obtener las terminaciones “st”, “nd”, “rd” y “th” para los números?

Me pregunto si existe un método o cadena de formato que me falta en .NET para convertir lo siguiente:

1 to 1st 2 to 2nd 3 to 3rd 4 to 4th 11 to 11th 101 to 101st 111 to 111th 

Este enlace tiene un mal ejemplo del principio básico involucrado en escribir su propia función, pero tengo más curiosidad si me falta una capacidad incorporada.

Solución

La respuesta de Scott Hanselman es la aceptada porque responde la pregunta directamente.

Para una solución, sin embargo, vea esta gran respuesta .

No, no hay capacidad incorporada en la Biblioteca de clases .NET Base.

Es una función que es mucho más simple de lo que piensas. Aunque puede existir una función .NET para esto, la siguiente función (escrita en PHP) hace el trabajo. No debería ser demasiado difícil trasladarlo.

 function ordinal($num) { $ones = $num % 10; $tens = floor($num / 10) % 10; if ($tens == 1) { $suff = "th"; } else { switch ($ones) { case 1 : $suff = "st"; break; case 2 : $suff = "nd"; break; case 3 : $suff = "rd"; break; default : $suff = "th"; } } return $num . $suff; } 

@nickf: Aquí está la función de PHP en C #:

 public static string Ordinal(int number) { string suffix = String.Empty; int ones = number % 10; int tens = (int)Math.Floor(number / 10M) % 10; if (tens == 1) { suffix = "th"; } else { switch (ones) { case 1: suffix = "st"; break; case 2: suffix = "nd"; break; case 3: suffix = "rd"; break; default: suffix = "th"; break; } } return String.Format("{0}{1}", number, suffix); } 

Simple, limpio, rápido

  private static string GetOrdinalSuffix(int num) { if (num.ToString().EndsWith("11")) return "th"; if (num.ToString().EndsWith("12")) return "th"; if (num.ToString().EndsWith("13")) return "th"; if (num.ToString().EndsWith("1")) return "st"; if (num.ToString().EndsWith("2")) return "nd"; if (num.ToString().EndsWith("3")) return "rd"; return "th"; } 

O mejor aún, como un método de extensión

 public static class IntegerExtensions { public static string DisplayWithSuffix(this int num) { if (num.ToString().EndsWith("11")) return num.ToString() + "th"; if (num.ToString().EndsWith("12")) return num.ToString() + "th"; if (num.ToString().EndsWith("13")) return num.ToString() + "th"; if (num.ToString().EndsWith("1")) return num.ToString() + "st"; if (num.ToString().EndsWith("2")) return num.ToString() + "nd"; if (num.ToString().EndsWith("3")) return num.ToString() + "rd"; return num.ToString() + "th"; } } 

Ahora puedes simplemente llamar

 int a = 1; a.DisplayWithSuffix(); 

o incluso tan directo como

 1.DisplayWithSuffix(); 

Esto ya se ha cubierto, pero no estoy seguro de cómo vincularlo. Aquí está el snippit de código:

  public static string Ordinal(this int number) { var ones = number % 10; var tens = Math.Floor (number / 10f) % 10; if (tens == 1) { return number + "th"; } switch (ones) { case 1: return number + "st"; case 2: return number + "nd"; case 3: return number + "rd"; default: return number + "th"; } } 

FYI: Esto es como un método de extensión. Si su versión de .NET es menor a 3.5 simplemente elimine la palabra clave this

[EDIT]: Gracias por señalar que fue incorrecto, eso es lo que obtienes para copiar / pegar el código 🙂

Aquí hay una versión de la función Microsoft SQL Server:

 CREATE FUNCTION [Internal].[GetNumberAsOrdinalString] ( @num int ) RETURNS nvarchar(max) AS BEGIN DECLARE @Suffix nvarchar(2); DECLARE @Ones int; DECLARE @Tens int; SET @Ones = @num % 10; SET @Tens = FLOOR(@num / 10) % 10; IF @Tens = 1 BEGIN SET @Suffix = 'th'; END ELSE BEGIN SET @Suffix = CASE @Ones WHEN 1 THEN 'st' WHEN 2 THEN 'nd' WHEN 3 THEN 'rd' ELSE 'th' END END RETURN CONVERT(nvarchar(max), @num) + @Suffix; END 

Sé que esto no es una respuesta a la pregunta del OP, pero como encontré útil levantar la función de SQL Server de este hilo, aquí hay un equivalente de Delphi (Pascal):

 function OrdinalNumberSuffix(const ANumber: integer): string; begin Result := IntToStr(ANumber); if(((Abs(ANumber) div 10) mod 10) = 1) then // Tens = 1 Result := Result + 'th' else case(Abs(ANumber) mod 10) of 1: Result := Result + 'st'; 2: Result := Result + 'nd'; 3: Result := Result + 'rd'; else Result := Result + 'th'; end; end; 

¿Tiene …, el 1er, el 0º sentido?

 public static string OrdinalSuffix(int ordinal) { //Because negatives won't work with modular division as expected: var abs = Math.Abs(ordinal); var lastdigit = abs % 10; return //Catch 60% of cases (to infinity) in the first conditional: lastdigit > 3 || lastdigit == 0 || (abs % 100) - lastdigit == 10 ? "th" : lastdigit == 1 ? "st" : lastdigit == 2 ? "nd" : "rd"; } 

Otro sabor:

 ///  /// Extension methods for numbers ///  public static class NumericExtensions { ///  /// Adds the ordinal indicator to an integer ///  /// The number /// The formatted number public static string ToOrdinalString(this int number) { // Numbers in the teens always end with "th" if((number % 100 > 10 && number % 100 < 20)) return number + "th"; else { // Check remainder switch(number % 10) { case 1: return number + "st"; case 2: return number + "nd"; case 3: return number + "rd"; default: return number + "th"; } } } } 
 else if (choice=='q') { qtr++; switch (qtr) { case(2): strcpy(qtrs,"nd");break; case(3): { strcpy(qtrs,"rd"); cout<<"End of First Half!!!"; cout<<" hteam "<<"["< 

Creo que el sufijo ordinal es difícil de conseguir … básicamente tienes que escribir una función que use un interruptor para probar los números y agregar el sufijo.

No hay razón para que un idioma lo proporcione internamente, especialmente cuando es específico de la configuración regional.

Puedes hacer un poco mejor que ese enlace cuando se trata de la cantidad de código para escribir, pero tienes que codificar una función para esto …