C# WPF中的日期时间格式
我想根据环境中的当前区域性自动显示日期时间 比如说 如果我使用C# WPF中的日期时间格式,c#,wpf,C#,Wpf,我想根据环境中的当前区域性自动显示日期时间 比如说 如果我使用DateTime.toSortDateString()转换“2013年5月4日”的DateTime,则在美国英语中为2013年5月4日,在英国英语中为2013年4月5日 但我想显示的是en us中的04/05/2013,以及en gb中的05/04/2013。零不能被隐藏 请注意,该软件可能在不同的文化中运行,而不仅仅是在美国和英国。我不想为每个区域性设置datetime格式。鉴于.NET对每个区域性的格式都有自己的想法,除了决定对现
DateTime.toSortDateString()
转换“2013年5月4日”的DateTime
,则在美国英语中为2013年5月4日
,在英国英语中为2013年4月5日
但我想显示的是en us中的04/05/2013
,以及en gb中的05/04/2013
。零不能被隐藏
请注意,该软件可能在不同的文化中运行,而不仅仅是在美国和英国。我不想为每个区域性设置datetime格式。鉴于.NET对每个区域性的格式都有自己的想法,除了决定对现有格式进行“改进”之外,您没有什么可以做的 我要做的是创建一个
IValueConverter
,其中我将采用当前(或所需)文化的短日期格式:
CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern
并用dd
替换任何出现的d
如果您要求月的长度为两位数,年的长度为四位数,我会将单个M
替换为MM
,并确保始终有四个y
这种方法利用了.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);
}
静态字符串ShortDateFormat(字符串区域性=null)
{
CultureInfo ci=CultureInfo.CurrentCulture;
如果(!string.IsNullOrEmpty(区域性))
ci=CultureInfo.GetCultureInfo(文化);
DateTimeFormatInfo fmtinfo=ci.DateTimeFormat;
if(string.IsNullOrEmpty(fmtinfo.DateSeparator))
返回fmtinfo.ShortDatePattern;
字符串fmt=fmtinfo.ShortDatePattern.Replace(fmtinfo.DateSeparator,“!”);
string[]parts=fmt.Split(“!”);
对于(int i=0;i
也许有点过火了。。。我不知道是否有任何区域性使用的日期分隔符不止一个字符:)
将该结果作为参数传递给
DateTime.ToString()
以获得输出。如果可以让框架决定如何显示DateTime
对象,为什么要使用IValueConverter使问题变得如此复杂?因为OP不想让框架决定。例如,他希望确保日期有一个前导零,这在所有文化的.NET日期模式中并不总是如此。使用IValueConverter
他将获得正确的顺序和分隔符,并在需要的地方引入零。一点。。。年有4种格式说明符:y
,yy
,yyy
,yyy
。如果存在yyy
表单,则format.Replace(“yy”,“yyyy”)
将产生难以辨认的结果。除此之外。。。回答得好+1Indeed,替换部分可能有点幼稚,可能看起来更像Corey的。我不知道是否有任何文化中使用了不止一个字符的日期分隔符-确实有!但不多。有些区域性使用分隔符,如代码>(注意句点后的空格)例如。@Petradulin,幸好我当时没有假设没有:P