هل String.Format و DateTimeFormatinfo قابلة للتجانس/قابلية التوسيع؟

StackOverflow https://stackoverflow.com/questions/3920164

سؤال

لذلك ، على سبيل المثال ، دعنا نقول عندما أقوم بتاريخ.

بمعنى آخر

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

يجب الإخراج

1st Jan 2010

انظر أدناه للحصول على كيفية استخلاص الأرقام الترتيبية

هل هناك طريقة سهلة في .NET للحصول على "ST" و "ND" و "RD" و "TH" للأرقام؟

هل كانت مفيدة؟

المحلول

يبدو أنه لا يوجد شيء مثل ذلك.

الطريقة الأكثر موصى بها للقيام بذلك:

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

طريقة الاختراق للغاية لتحقيق ذلك هي إنشاء العرف IFormatProvider. IMO إنها مجرد مشكلة كبيرة ، ولكن فقط لإظهار طريقة بديلة ... (ليس لدي الكثير من الخبرة في هذا ، قد لا يكون "صحيحًا")

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

مزيد من المعلومات حول IformatProvider المخصص

نصائح أخرى

مقدمي الخدمات التنسيق قابلة للتوصيل ، ولكن على حد علمي ، لا يمكنك إعداد مزود تنسيق افتراضي لنوع معين. الأساليب التي تأخذ سلاسل التنسيق حسب الاتفاقية عادة ما يكون لها أيضا تحميل زائد يأخذ iformatprovider. يمكنك تنفيذ فئتين مثل MyFormatProvider: iformatprovider و myCustomFormatter: iCustomFormatter.

عندما يتم معالجة سلسلة تنسيق مثل "{0: dd} {0: or} {0: mmm} {0: yyyy}" "، و" yyyy "كمعلمات بحيث يمكن تنسيق كل جزء بشكل منفصل. سيكون عليك ببساطة التعامل مع العلبة "أو" وتمرير الباقي على مزود التنسيق الافتراضي.

ومع ذلك ، سيظل المتصل بحاجة إلى تمرير في مثيل من مزود التنسيق المخصص عند التنسيق. فمثلا:

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

على حد علمي ، لا يوجد هروب من هذا المطلب. لقد بحثت عن طريقة أفضل لبعض الوقت عندما قمت بإنشاء سلسلة تنسيق "نسبية" لوقت البيانات التي تعرض أوقات البيانات مثل "1 ساعة" ، "منذ 3 أيام" ، وما إلى ذلك. تمرير Iformatprovider المخصص الخاص بي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top