[英]Is String.Format and DateTimeFormatInfo pluggable/extensible?
因此,举例来说,当我对日期进行string.format格式化并在格式模式中使用字符串“或”时,我希望将其转换为Date的序数值。
即
string.Format("{0:ddor MMM yyyy}.", DateTime.Now)
应该输出
1st Jan 2010
有关如何导出序数的信息,请参见下文
似乎没有类似的东西。
推荐的方法:
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}”之类的格式字符串时,您的ICustomFormatter将被调用4次,并带有“ dd”,“ or”,“ MMM” ”和“ yyyy”作为参数,因此它可以分别格式化每个部分。 您只需要处理“或”情况,并将其余的情况传递给默认格式提供程序。
但是,在格式化时,调用方仍然需要传递自定义格式提供程序的实例。 例如:
string str = String.Format(MyFormatProvider.Default, "{0:dd}{0:or} {0:MMM} {0:yyyy}", date);
据我所知,没有逃避这一要求。 当我创建了一个“相对” DateTime格式字符串,该字符串显示DateTimes(例如“ 1小时前”,“ 3天前”等)时,我寻找了一种更好的方法。无法找到避免显式使用的方法通过我的自定义IFormatProvider。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.