Obteniendo sufijo de día cuando usa DateTime.ToString ()

¿Es posible incluir el sufijo del día al formatear una fecha usando DateTime.ToString ()?

Por ejemplo, me gustaría imprimir la fecha en el siguiente formato: el lunes 27 de julio de 2009. Sin embargo, el ejemplo más cercano que puedo encontrar usando DateTime.ToString () es el lunes 27 de julio de 2009.

¿Puedo hacer esto con DateTime.ToString () o tendré que recurrir a mi propio código?

Como referencia, siempre utilizo / me refiero a SteveX String Formatting y no parece haber ninguna “th” en ninguna de las variables disponibles, pero podría construir fácilmente una cadena con

string.Format("{0:dddd dd}{1} {0:MMMM yyyy}", DateTime.Now, (?)); 

Tendría que proporcionar un “st” para 1, “nd” para 2, “rd” para 3 y “th” para todos los demás y podría estar alineado con una statement “?:”.

 (DateTime.Now.Day % 10 == 1 && DateTime.Now.Day != 11) ? "st" : (DateTime.Now.Day % 10 == 2 && DateTime.Now.Day != 12) ? "nd" : (DateTime.Now.Day % 10 == 3 && DateTime.Now.Day != 13) ? "rd" : "th" 

Otra opción usando el interruptor:

 string GetDaySuffix(int day) { switch (day) { case 1: case 21: case 31: return "st"; case 2: case 22: return "nd"; case 3: case 23: return "rd"; default: return "th"; } } 

Usando un par de métodos de extensión:

 namespace System { public static class IntegerExtensions { public static string ToOccurrenceSuffix(this int integer) { switch (integer % 100) { case 11: case 12: case 13: return "th"; } switch (integer % 10) { case 1: return "st"; case 2: return "nd"; case 3: return "rd"; default: return "th"; } } } public static class DateTimeExtensions { public static string ToString(this DateTime dateTime, string format, bool useExtendedSpecifiers) { return dateTime.ToString(format) .Replace("nn", dateTime.Day.ToOccurrenceSuffix().ToLower()) .Replace("NN", dateTime.Day.ToOccurrenceSuffix().ToUpper()); } } } 

Uso:

 return DateTime.Now.ToString("dddd, dnn MMMM yyyy", useExtendedSpecifiers: true); // Friday, 7th March 2014 

Nota: El método de extensión entero se puede usar para cualquier número, no solo de 1 a 31. Ejemplo:

 return 332211.ToOccurrenceSuffix(); // th 

Otra opción es usar el operador de módulo :

 public string CreateDateSuffix(DateTime date) { // Get day... var day = date.Day; // Get day modulo... var dayModulo = day%10; // Convert day to string... var suffix = day.ToString(CultureInfo.InvariantCulture); // Combine day with correct suffix... suffix += (day == 11 || day == 12 || day == 13) ? "th" : (dayModulo == 1) ? "st" : (dayModulo == 2) ? "nd" : (dayModulo == 3) ? "rd" : "th"; // Return result... return suffix; } 

Aquí está la versión extendida incluyendo 11, 12 y 13:

 DateTime dt = DateTime.Now; string d2d = dt.ToString("dd").Substring(1); string daySuffix = (dt.Day == 11 || dt.Day == 12 || dt.Day == 13) ? "th" : (d2d == "1") ? "st" : (d2d == "2") ? "nd" : (d2d == "3") ? "rd" : "th"; 

Aquí hay un método de extensión (porque a todos les encantan los métodos de extensión), con la respuesta de Lazlow como base (escogió Lazlow porque es fácil de leer).

Funciona igual que el método ToString() normal en DateTime con la excepción de que si el formato contiene una d o dd , entonces el sufijo se agregará automáticamente.

 ///  /// Return a DateTime string with suffix eg "st", "nd", "rd", "th" /// So a format "dd-MMM-yyyy" could return "16th-Jan-2014" ///  public static string ToStringWithSuffix(this DateTime dateTime, string format, string suffixPlaceHolder = "$") { if(format.LastIndexOf("d", StringComparison.Ordinal) == -1 || format.Count(x => x == 'd') > 2) { return dateTime.ToString(format); } string suffix; switch(dateTime.Day) { case 1: case 21: case 31: suffix = "st"; break; case 2: case 22: suffix = "nd"; break; case 3: case 23: suffix = "rd"; break; default: suffix = "th"; break; } var formatWithSuffix = format.Insert(format.LastIndexOf("d", StringComparison.InvariantCultureIgnoreCase) + 1, suffixPlaceHolder); var date = dateTime.ToString(formatWithSuffix); return date.Replace(suffixPlaceHolder, suffix); } 

Tomando la respuesta de @ Lazlow a una solución completa, el siguiente es un método de extensión completamente reutilizable, con uso de ejemplo;

 internal static string HumanisedDate(this DateTime date) { string ordinal; switch (date.Day) { case 1: case 21: case 31: ordinal = "st"; break; case 2: case 22: ordinal = "nd"; break; case 3: case 23: ordinal = "rd"; break; default: ordinal = "th"; break; } return string.Format("{0:dddd dd}{1} {0:MMMM yyyy}", date, ordinal); } 

Para usar esto, simplemente llámalo a un objeto DateTime ;

 var myDate = DateTime.Now(); var myDateString = myDate.HumanisedFormat() 

Lo cual te dará:

Viernes 17 de junio de 2016

Creo que esta es una buena solución, que abarca números como 111th, etc.

 private string daySuffix(int day) { if (day > 0) { if (day % 10 == 1 && day % 100 != 11) return "st"; else if (day % 10 == 2 && day % 100 != 12) return "nd"; else if (day % 10 == 3 && day % 100 != 13) return "rd"; else return "th"; } else return string.Empty; } 

Lo hice así, soluciona algunos de los problemas que se dan en los otros ejemplos.

  public static string TwoLetterSuffix(this DateTime @this) { var dayMod10 = @this.Day % 10; if (dayMod10 > 3 || dayMod10 == 0 || (@this.Day >= 10 && @this.Day <= 19)) { return "th"; } else if(dayMod10 == 1) { return "st"; } else if (dayMod10 == 2) { return "nd"; } else { return "rd"; } } 

Una solución VB barata y alegre:

 litDate.Text = DatePart("dd", Now) & GetDateSuffix(DatePart("dd", Now)) Function GetDateSuffix(ByVal dateIn As Integer) As String '// returns formatted date suffix Dim dateSuffix As String = "" Select Case dateIn Case 1, 21, 31 dateSuffix = "st" Case 2, 22 dateSuffix = "nd" Case 3, 23 dateSuffix = "rd" Case Else dateSuffix = "th" End Select Return dateSuffix End Function 

Para lo que vale aquí es mi solución final usando las respuestas a continuación

  DateTime dt = DateTime.Now; string d2d = dt.ToString("dd").Substring(1); string suffix = (dt.Day == 11 || dt.Day == 12 || dt.Day == 13) ? "th" : (d2d == "1") ? "st" : (d2d == "2") ? "nd" : (d2d == "3") ? "rd" : "th"; Date.Text = DateTime.Today.ToString("dddd d") + suffix + " " + DateTime.Today.ToString("MMMM") + DateTime.Today.ToString(" yyyy"); 

public static String SuffixDate (DateTime date) {string ordinal;

  switch (date.Day) { case 1: case 21: case 31: ordinal = "st"; break; case 2: case 22: ordinal = "nd"; break; case 3: case 23: ordinal = "rd"; break; default: ordinal = "th"; break; } if (date.Day < 10) return string.Format("{0:d}{2} {1:MMMM yyyy}", date.Day, date, ordinal); else return string.Format("{0:dd}{1} {0:MMMM yyyy}", date, ordinal); } 

Obtenga el sufijo de fecha. (Función estática)

 public static string GetSuffix(this string day) { string suffix = "th"; if (int.Parse(day) < 11 || int.Parse(day) > 20) { day = day.ToCharArray()[day.ToCharArray().Length - 1].ToString(); switch (day) { case "1": suffix = "st"; break; case "2": suffix = "nd"; break; case "3": suffix = "rd"; break; } } return suffix; } 

Referencia: https://www.aspsnippets.com/Articles/Display-st-nd-rd-and-th-suffix-after-day-numbers-in-Formatted-Dates-using-C-and-VBNet.aspx

en la documentación de MSDN no hay referencia a una cultura que pueda convertir ese 17 en 17º. entonces deberías hacerlo manualmente a través de código subyacente. O construir uno … podrías construir una función que lo haga.

 public string CustomToString(this DateTime date) { string dateAsString = string.empty;  return dateAsString; } 

Otra opción usando el último carácter de cadena:

 public static string getDayWithSuffix(int day) { string d = day.ToString(); if (day < 11 || day > 13) { if (d.EndsWith("1")) { d += "st"; } else if (d.EndsWith("2")) { d += "nd"; } else if (d.EndsWith("3")) { d += "rd"; } else { d += "th"; } else { d += "th"; } return d; }