هل String.Format و DateTimeFormatinfo قابلة للتجانس/قابلية التوسيع؟
-
29-09-2019 - |
سؤال
لذلك ، على سبيل المثال ، دعنا نقول عندما أقوم بتاريخ.
بمعنى آخر
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. يمكنك تنفيذ فئتين مثل 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 المخصص الخاص بي.