我想根据环境中的当前文化自动显示日期时间。
例如,如果我DateTime.ToShortDateString()
用来转换“May 4 2013” ,Datetime
它将4/5/2013
在 en-us 和5/4/2013
.en-gb
但我想展示的是04/05/2013
en-us 和05/04/2013
en-gb。零是无法隐藏的。
请注意,该软件可能在各种文化中运行,而不仅仅是在美国和英国。我不想为每种文化设置日期时间格式。
鉴于 .NET 对每种文化的格式应该是什么有自己的想法,除了决定对现有格式进行“改进”之外,您无能为力。
我要做的是创建一个IValueConverter
我将采用当前(或所需)文化的短日期格式的方法:
CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern
并将任何出现的 singled
替换为dd
.
如果您需要几个月的两位数和年的四位数长,我会用 single 替换M
并MM
确保总是有四个y
's。
这种方法利用了 .NET 认为在每种文化中日期-月份-年份的正确顺序,并使用了 .NET 认为是正确的分隔符。
转换器可能如下所示:
class ShortDateConverter : IValueConverter
{
public object Convert(object data, Type type, object parameter, CultureInfo culture)
{
string format = PrepareFormat(culture.DateTimeFormat.ShortDatePattern);
DateTime date = (DateTime)data;
return date.ToString(format, culture);
}
public object ConvertBack(object data, Type type, object parameter, CultureInfo culture)
{
return DateTime.ParseExact((string)data, PrepareFormat(culture.DateTimeFormat.ShortDatePattern), culture);
}
private string PrepareFormat(string format)
{
if (!format.Contains("dd"))
format = format.Replace("d", "dd");
if (!format.Contains("MM"))
format = format.Replace("M", "MM");
if (!format.Contains("yyyy"))
format = format.Replace("yy", "yyyy");
return format;
}
}
特定于区域性的格式将定义是否存在前导零。要更改这一点,您需要解析由区域性指定的日期格式,查找非前导零说明符并合成包含前导零的格式。
例如:
static string ShortDateFormat(string culture = null)
{
CultureInfo ci = CultureInfo.CurrentCulture;
if (!string.IsNullOrEmpty(culture))
ci = CultureInfo.GetCultureInfo(culture);
DateTimeFormatInfo fmtinfo = ci.DateTimeFormat;
if (string.IsNullOrEmpty(fmtinfo.DateSeparator))
return fmtinfo.ShortDatePattern;
string fmt = fmtinfo.ShortDatePattern.Replace(fmtinfo.DateSeparator, "!");
string[] parts = fmt.Split('!');
for (int i = 0; i < parts.Length; ++i)
{
if (parts[i] == "d")
parts[i] = "dd";
else if (parts[i] == "M")
parts[i] = "MM";
}
return string.Join(fmtinfo.DateSeparator, parts);
}
也许有点过火......我不知道是否有任何文化使用超过单个字符的日期分隔符:)
将结果作为参数传递DateTime.ToString()
以获取输出。