Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF中的日期时间格式_C#_Wpf - Fatal编程技术网

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