非美国文化中带有 DateTime 的 String.FormatException

Posted

技术标签:

【中文标题】非美国文化中带有 DateTime 的 String.FormatException【英文标题】:String.FormatException with DateTime in non US Culture 【发布时间】:2010-02-25 22:06:18 【问题描述】:

当文化不是非美国时,我收到 String.FormatException 试图转换/解析字符串。奇怪的是,字符串是通过应用与将其解析回字符串完全相同的格式和文化生成的。在下面的代码中,所有这些版本都会失败:

常量字符串文化=“ja-JP”; 常量字符串格式=“dd MMM yyyy”; //原始帖子中的错误包括 0: 文化信息信息 = 新文化信息(文化); Thread.CurrentThread.CurrentCulture = 信息; Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(culture); //string toParse = String.Format(info, format, DateTime.Now); //原帖中的错误 字符串 toParse = DateTime.Now.ToString(format); System.Diagnostics.Debug.WriteLine(string.Format("文化格式 = 0, 日期 = 1",culture, toParse)); 尝试 DateTime 输出 = DateTime.ParseExact(toParse, format, CultureInfo.InvariantCulture); //日期时间输出 = DateTime.ParseExact(toParse, format, info); //日期时间输出 = DateTime.ParseExact(toParse, format, info, DateTimeStyles.None); //日期时间输出 = Convert.ToDateTime(toParse, info); 捕捉(例外前) System.Diagnostics.Debug.WriteLine(ex.Message);

请注意,en-US 的字符串是“2010 年 2 月 25 日”。 ja-JP 的字符串是“25 2 2010”。

知道如何将“25 2 2010”恢复为日期吗?

提前致谢。

Edit1:我应该注意,日本文化在这里被硬编码只是作为一个例子。我真的需要它来处理用户设置的任何文化。我需要的是一个解决方案,无论用户的文化如何,日期时间格式都可以工作。我认为单 M 做到了。

编辑 2:M 不适用于英语。有人知道适用于所有文化的格式字符串吗?

【问题讨论】:

【参考方案1】:

如果你改变:

DateTime output = DateTime.ParseExact(
    toParse, format, CultureInfo.InvariantCulture);

DateTime output = DateTime.ParseExact(toParse, "dd MMM yyyy", info);

日期已正确解析。

请注意,在您的示例中,您使用一种文化 (ja-JP) 来转换为字符串,但使用另一种文化来从字符串转换。另一个问题是 String.Format 接受复合格式字符串 ("My string to format - 0:dd MMM yyyy"),但 DateTime.ParseExact 只需要日期时间格式。

【讨论】:

如果您想将DateTime.ParseExactCultureInfo.InvariantCulture 一起使用,那么是的,您是对的。但是,如果您使用 JP 文化,则不需要。 是的,很好地抓住了 0: 的东西 - 这不是最终的问题,但它是我的测试脚本中的一个错误(现已修复)。在解析过程中,我也尝试过使用 ja-JP 文化——其中有很多尝试。仅在不起作用时才使用 Invariant。【参考方案2】:

在解析日期时尝试使用单个 M。这就是用于日本文化的MonthDayPattern 示例中的内容。

const string format = "0:dd M yyyy";

【讨论】:

这真的不是问题。 OP 正在尝试使用复合格式字符串作为DateTime.ParseExact 的格式,它只需要日期时间格式。【参考方案3】:
string text = "25 2 2009";
DateTime date = DateTime.ParseExact(text, "d M yyyy", CultureInfo.InvariantCulture);

【讨论】:

【参考方案4】:

您传递给DateTime.ParseExact 的格式模式必须只是日期模式,没有占位符。对于 JP 文化,您只需要使用一个 M,因为即使在转换为字符串时指定了 MMM,日期也由数字表示。

        const string culture = "ja-JP";
        const string FROM_STRING_FORMAT = "dd M yyyy";
        const string TO_STRING_FORMAT = "0:" + FROM_STRING_FORMAT + "";
        CultureInfo info = new CultureInfo(culture);
        Thread.CurrentThread.CurrentCulture = info;
        Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(culture);

        string toParse = String.Format(info, TO_STRING_FORMAT, DateTime.Now);
        Console.WriteLine(string.Format("Culture format = 0, Date = 1", culture, toParse));
        try
        
            DateTime output = DateTime.ParseExact(toParse, FROM_STRING_FORMAT, CultureInfo.InvariantCulture);
            Console.WriteLine(output);
        
        catch (Exception ex)
        
            Console.WriteLine(ex.Message);
        

【讨论】:

这看起来像是答案 - 这适用于所有文化吗? 不,这不适用于 英语。日语有点不寻常,即使您指定了MMM,您得到的结果也只有M。因此,在将 ParseExact 与日语一起使用时,字符串格式 MMM 不兼容往返。我能给你的最佳建议是使用接受多种格式的ParseExact 重载,如下所示:DateTime.ParseExact(toParse, new [] "d M yyyy", "d MMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None); João Angelo 在他的帖子中是正确的。您的原始文件的真正问题是您正在使用特定文化格式化 to-string,然后尝试使用不变文化解析它。格式字符串不匹配。如果您在格式和解析中使用相同的文化信息,它就可以工作。

以上是关于非美国文化中带有 DateTime 的 String.FormatException的主要内容,如果未能解决你的问题,请参考以下文章

Azure ServiceBus的消息中带有@strin3http//schemas.microsoft.com/2003/10/Serialization/?

如何创建不在当前文化中的 DateTime 对象

将来自不同文化的 DateTime 字符串传递给服务

DateTime 格式没有正确的文化 WP8

如何在不同的系统文化中转换 DateTime?

DateTime.Parse 美国日期格式 C#