Pregunta

Así, por ejemplo, digamos que cuando String.Format una fecha y utilizar la cadena "o" en el modelo de formato que quiero que convierte al valor ordinal de la fecha.

es decir,

string.Format("{0:ddor MMM yyyy}.", DateTime.Now)

debe ser la salida

1st Jan 2010

Vea a continuación la forma de obtener los números ordinales

¿hay una manera fácil de conseguir en .NET 'c', 'nd', 'r' y 'th' finales para los números?

¿Fue útil?

Solución

Parece que no hay algo parecido.

La forma más recomendable hacerlo:

var d = DateTime.Now;
var result2 = String.Format("{0:dd}{1} {2:MMM yyyy}", d, Ordinal(d.Day), d);

Una forma poco limpia para lograrlo es crear un IFormatProvider personalizado. OMI es sólo un montón de problemas, pero sólo para mostrar una forma alternativa ... (no tengo mucha experiencia con esto, puede que no sea muy "correcta")

using System;

namespace Test
{
    class Program
    {
        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 = @"\t\h";
            }
            else
            {
                switch (ones)
                {
                    case 1:
                        suffix = @"\s\t";
                        break;

                    case 2:
                        suffix = @"\n\d";
                        break;

                    case 3:
                        suffix = @"\r\d";
                        break;

                    default:
                        suffix = @"\t\h";
                        break;
                }
            }
            return suffix;
        }

        public class MyFormat : IFormatProvider, ICustomFormatter
        {
            public object GetFormat(Type formatType)
            {
                return (formatType == typeof(ICustomFormatter)) ? this : null;

            }

            public string Format(string format, object arg, IFormatProvider formatProvider)
            {
                var d = (DateTime)arg;

                var or = Ordinal(d.Day);

                format = format.Replace("or", or);

                return d.ToString(format);
            }
        }
        static void Main(string[] args)
        {
            var result = String.Format(new MyFormat(), "{0:ddor MMM yyyy}.", DateTime.Now);

            return;
        }
    }
}

Más información sobre IFormatProvider personalizada

Otros consejos

proveedores de formato son conectables, pero por lo que yo sé, no se puede establecer un proveedor de formato predeterminado para un tipo dado. Métodos que toman las cadenas de formato, por convención, normalmente también tienen una sobrecarga que toma un IFormatProvider. Se puede implementar dos clases como MyFormatProvider: IFormatProvider y MyCustomFormatter: ICustomFormatter .

Cuando una cadena de formato, tales como "{0: dd} {0: o} {0: MMM} {0: aaaa}" se procesa, su ICustomFormatter será llamado 4 veces, con "dd", "o" "MMM", y "aaaa", como los parámetros de lo que puede dar formato a cada parte por separado. Usted simplemente tiene que manejar la "o" caso y pasar el resto en el proveedor de formato por defecto.

Sin embargo, la persona que llama todavía tendrá que pasar en una instancia de su proveedor de formato personalizado al formatear. Por ejemplo:

string str = String.Format(MyFormatProvider.Default, "{0:dd}{0:or} {0:MMM} {0:yyyy}", date);

Por lo que yo sé, no hay escape ese requisito. Busqué una manera mejor de un tiempo atrás cuando había creado una cadena de DateTime "relativo" formato que aparece como DateTime "Hace 1 día", "Hace 3 días", etc. No se pudo encontrar una manera de evitar tener que explícitamente pasar mi IFormatProvider personalizado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top