【问题标题】:C# DateTime ToString Standard culture formatC# DateTime ToString 标准文化格式
【发布时间】:2018-03-27 14:19:50
【问题描述】:

我可以更改特定文化的 DateTime 的标准输出格式吗?示例:

class Program
{
    static void Main(string[] args)
    {
        PrintCultureDateTime("ca-ES");
        PrintCultureDateTime("es-ES");
        PrintCultureDateTime("en-US");
        PrintCultureDateTime("en-GB");
        PrintCultureDateTime("pt-PT");
    }

    public static void PrintCultureDateTime(string culture)
    {
        string result = new DateTime(2017, 10, 1).ToString("d", 
            CultureInfo.GetCultureInfo(culture));
        Console.WriteLine(string.Format("{0}: {1}", culture, result));
    }
}

输出:

ca-ES: 1/10/2017
es-ES: 01/10/2017
en-US: 10/1/2017
en-GB: 01/10/2017
pt-PT: 01/10/2017

我想要的是使用标准“d”格式或另一种标准格式使用两位数表示日期和月份,以修复 DateTime 字符串的大小。类似这样的输出:

ca-ES: 01/10/2017
es-ES: 01/10/2017
en-US: 10/01/2017
en-GB: 01/10/2017
pt-PT: 01/10/2017

【问题讨论】:

标签: c# datetime culture


【解决方案1】:

您可以使用DateTimeFormatInfo.ShortDatePattern 来获取模式,然后如果您真的想用dd 替换d。您可能需要考虑转义或引用d 模式等极端情况 - 以及显然不将dd 替换为dddd。 (请注意,来自系统文化的格式信息将是只读的;克隆文化以获得具有读/写格式信息的文化。)当然,您也可以这样做几个月。您甚至可能需要更改年份部分。

我不清楚这样做是个好主意 - 当您更改格式时,它不再是真正的“文化的标准短日期格式”了。

即使完成了所有这些,也不能保证所有文化的长度都相同。没有什么可以阻止一种文化使用"'Year:' yyyy '; Month: ' MM '; 'Day: 'dd" 的短日期格式。这将是非常不寻常的,但并非无效。

【讨论】:

  • @Marc:恐怕我现在不太确定你在说什么。
  • 对不起@Jon-skeet,我误解了你的回答。没关系!
【解决方案2】:

基于@Jon Skeet 的回答,我实施了以下解决方案。我认为必须存在具有单次迭代的更好的正则表达式替换指令,但我没有更多时间找到它。

它不适用于格式“'Year:'yyyy'; Month:'MM';'Day:'dd”,但我会假设“错误”。

    public static void PrintCultureDateTime(string culture)
    {
        string result = new DateTime(2017, 10, 1).ToString(FixedSizeShortDatePattern(culture));
        Console.WriteLine(string.Format("{0}: {1}", culture, result));
    }

    public static string FixedSizeShortDatePattern(string culture)
    {
        var cultureInfo = CultureInfo.GetCultureInfo(culture);
        string format = cultureInfo.DateTimeFormat.ShortDatePattern;
        return ReplaceSingleChar(ReplaceSingleChar(format, 'd'), 'M');
    }

    public static string ReplaceSingleChar(string input, char c)
    {
        string cStr = c.ToString();
        string strRegex = string.Format(@"^({0})[^{0}]|[^{0}]({0})[^{0}]|[^{0}]({0})$", cStr);
        return Regex.Replace(input, strRegex, (match) =>
        {
            string token = match.Groups[0].Value;
            if (!string.IsNullOrEmpty(token))
            {
                return match.Value.Replace(cStr, string.Concat(cStr, cStr));
            }
            return token;
        });
    }

【讨论】:

    【解决方案3】:

    这样的东西可能适用于大多数日期格式,但正如 Jon Skeet 所说,可能存在一些难以处理的奇怪格式。

    public class CustomFormatProvider : IFormatProvider
    {
        private string _culture;
    
        public CustomFormatProvider(string culture)
        {
            _culture = culture;
        }
    
        public object GetFormat(Type formatType)
        {
            if (formatType.Equals(typeof(DateTimeFormatInfo)))
            {
                var format = 
    CultureInfo.GetCultureInfo(_culture).DateTimeFormat;
                var info = new DateTimeFormatInfo();
                switch (format.ShortDatePattern.ToString())
                {
                    case "d/M/yyyy":
                    case "d/MM/yyyy":
                    case "dd/M/yyyy":
                    case "dd/MM/yyyy":
                        info.ShortDatePattern = "dd/MM/yyyy";
                        return info;
                    case "M/dd/yyyy":
                    case "MM/dd/yyyy":
                    case "M/d/yyyy":
                    case "MM/d/yyyy":
                        info.ShortDatePattern = "MM/dd/yyyy";
                        return info;
                    default:
                        //This is just example for default handling
                        info.ShortDatePattern = "dd/MM/yyyy";
                        return info;
                }
            }
            else return null;
        }
    }
    

    用法:

    public static void PrintCultureDateTime(string culture)
        {
            string result = new DateTime(2017, 10, 1).ToString("d", new 
    CustomFormatProvider(culture));
            Console.WriteLine(string.Format("{0}: {1}", culture, result));
        }
    

    输出:

    【讨论】:

    • 他可以简单地检查format.ShortDatePattern.ToString() 是否以m 开头,然后使用MM/dd/yyyy 否则使用dd/MM/yyyy 更短,并且适用于所有情况
    • @Franck 是的,它肯定可以重构。
    • 因为灵感还不错,但它不适用于没有'/'作为分隔符或以年份开头的严重情况。如果需要,请查看我的解决方案并发表评论。
    猜你喜欢
    • 2010-10-22
    • 2014-09-30
    • 2021-07-09
    • 2010-12-22
    • 2010-11-19
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 2015-12-12
    相关资源
    最近更新 更多