Question

Ainsi, par exemple permet de dire quand je String.Format une date et utilisez la chaîne « ou » dans le modèle de format que je veux que converti à la valeur ordinale de la date.

soit

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

devrait afficher

1st Jan 2010

Voir ci-dessous pour savoir comment calculer les nombres ordinaux

Est-il un moyen facile dans .NET pour obtenir « st », « e », « e » et « e » pour fins chiffres?

Était-ce utile?

La solution

Il semble qu'il n'y ait pas quelque chose comme ça.

La façon la plus recommandé de le faire:

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

Une façon très hacky pour y parvenir est de créer un IFormatProvider personnalisé. L'OMI, il est juste beaucoup de mal, mais juste pour montrer une autre façon ... (je n'ai pas beaucoup d'expérience avec cela, il pourrait ne pas être très « correct »)

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;
        }
    }
}

Plus d'informations sur mesure IFormatProvider

Autres conseils

Les fournisseurs de format sont connectables, mais pour autant que je sache, vous ne pouvez pas mettre en place un fournisseur de format par défaut pour un type donné. Les méthodes qui prennent les chaînes de format par convention ont généralement aussi une surcharge qui prend un IFormatProvider. Vous pouvez mettre en œuvre deux classes telles que MyFormatProvider: IFormatProvider et MyCustomFormatter: ICustomFormatter .

Quand une chaîne de format tel que "{0: dd} {0: ou} {0: MMM} {0: yyyy}" est traitée, votre ICustomFormatter sera appelé 4 fois, avec "dd", "ou" , « mmm » et « yyyy » les paramètres afin qu'il puisse formater chaque partie séparément. Vous auriez tout simplement de gérer le « ou » cas et passer le reste sur le fournisseur de format par défaut.

Toutefois, l'appelant devra encore passer dans une instance de votre fournisseur de format personnalisé lors du formatage. Par exemple:

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

Pour autant que je sache, il n'y a pas moyen d'échapper à cette exigence. Je recherchais une meilleure façon un certain temps quand j'avais créé « il y a 3 jours » une chaîne « relative » de format DateTime qui affiche DateTimes comme « il y a 1 heure », etc. Impossible de trouver un moyen d'éviter d'avoir explicitement passer mon IFormatProvider personnalisé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top