【问题标题】:DateTime conversion from string C#从字符串 C# 转换日期时间
【发布时间】:2023-03-07 10:10:02
【问题描述】:

我有一个字符串 (642014),格式为 Mdyyyy
我想将字符串转换为04062014(ddMMYYYY)。
我已经尝试了以下代码。
请帮助。

DateTime.TryParseExact("642014", "MMddyyyy",
                       CultureInfo.InvariantCulture,
                       DateTimeStyles.None, out "04062014");

【问题讨论】:

  • 1112014 的日期是什么时候?
  • 试试DateTime.TryParseExact("642014", "Mdyyyy", CultureInfo.InvariantCulture); 记住import using System.Globalization;
  • 可能你把MdyyyMMddyyy搞混了?
  • 换句话说,您的格式在 2014 年 1 月 11 日与 2014 年 11 月 11 日有何不同?
  • 看来你不明白 out parameter modifier 的工作原理。

标签: c# .net string datetime


【解决方案1】:

这不是有效的日期格式。

要突出问题是1112014 1st of Nov11th of Jan

如果您有某种约定允许您确定在这些情况下它所指的日期,您可以进行某种预处理或手动解析字符串,但您不会找到任何“内置”的东西对于那种格式

【讨论】:

    【解决方案2】:

    您的情况看起来像另一个最广泛的形式问题。

    来自DateTime.TryParseExact method

    如果您不在自定义格式模式中使用日期或时间分隔符, 对提供者参数使用不变的文化和最广泛的 每个自定义格式说明符的形式。例如,如果你想 在模式中指定小时,指定更宽的形式,“HH”,而不是 更窄的形式,“H”。

    因此,有时解析没有任何日期或时间分隔符的字符串可能会出现问题。

    例如让我们谈谈"d" custom format specifier。对于格式化部分,它会使用单个数字 格式化您的一天部分。但是对于解析,它可以同时解析404。与"M" custom format specifier 相同。我不是说你应该使用d 说明符来表示04。你可以,但你不应该。您应该始终使用最适合您的字符串的最佳格式。

    这是我对这里发生的事情的看法;

    由于 最宽形式 规则,由于您的字符串没有任何日期分隔符,因此您的格式应该期望dM 的最宽形式,它们是ddMM。但我认为这些说明符在用于单个数字时希望 带有 前导零值(例如:0604),因为它们的实际用途。我找不到任何证据来支持我的理论,但我仍在调查它。

    如果您的字符串总是 Mdyyyy 格式,我有一个解决方案。也许这不是最好的解决方案,但我认为如果您的字符串具有恒定格式,它会很有用;

    public static DateTime? ParseDate_Mdyyyy(string date)
    {
        if (date == null)
            return null;
        if (date.Length < 6)
            return null;
        if (date.Length == 6)
            date = date.Insert(0, "0").Insert(2, "0");
        DateTime dt;
        if (DateTime.TryParseExact(date, "MMddyyyy",
                                   CultureInfo.InvariantCulture,
                                   DateTimeStyles.None, out dt))
            return dt;
        return null;
    }
    

    现在你可以用这个方法了;

    string s = "642014";
    DateTime? date = ParseDate_Mdyyyy(s);
    Console.WriteLine(date.Value.ToString("ddMMyyyy")); // 04062014
    

    我就这个问题与 .NET Framework 团队联系过,他们的回应是;

    嗨,Soner,

    解析代码并没有真正寻找任何分隔符。这是什么 正在进行中:

    对于使用“MMddyyyy”的情况,在方法中开始解析 DoStrictParse 将调用 ParseByFormat。该方法将获得 格式的第一部分是“MM”,然后调用ParseDigits 从我们解析的字符串中获取等效数字 “642014” 这将 给“64”请注意,在此之前没有验证发生,如果 该数字超出所选日历中月份的范围 (在我们这里是公历)。解析代码会重复 “dd” 的相同过程将得到等效部分 “20” 然后 将为“yyyy” 重复它,但这会失败,因为它期望4 数字和 我们只有两个 (“14”)。

    对于使用“Mdyyyy”的情况,它失败了,因为几乎相同的原因 在解析 “M” 部分时,我们知道月份可以是 2 数字所以 我们将其映射到“64” 并将对“d” 执行相同的操作,将其映射到“20” 然后一年将失败。我相信这就是原因 文档说总是使用最宽的形式。

    这里的建议是要么使用2 数字形式 像"06042014" 这样的字符串,解析应该成功“MMddyyyy” 还有“Mdyyyy”。其他选项是插入分隔符"6/4/2014""06/04/2014" 并解析为"M/d/yyyy"

    谢谢,塔雷克

    特别感谢; Tarek Mahmoud Sayed、Wes Haggard 和 Richard Lander。

    【讨论】:

    • @Downvoter 至少愿意发表评论,这样我才能知道我可能错在哪里?
    • 我不是这里的反对者,但是...我认为 cmets 和我的回答中的 1112014 示例显示了 OP 有问题的格式的症结所在。您自己的答案(尽管它从您对.TryParseExact() 方法的目标和实现的了解中带来了无可置疑的价值)并没有真正解决这个问题。在这个例子中,date.Length == 7 所以它错过了你所有的预处理,仍然到达.TryParseExact(),对于它是代表 11 月 1 日还是 1 月 11 日具有同样的歧义
    • @Stewart_R 对不起,你错了。 1112014 没有显示 OP 的问题。你说会是1st of Nov 还是11th of Jan?您对1112014 字符串是正确的,但这不会影响642014 字符串。为什么?因为自从 OP 解析这个MMddyyyy 格式。我们应该说好的,MM 解析 6dd 解析 4(即使它们不用于解析单个数字)和 yyyy 解析 2014。一切看起来都不错。但事实并非如此。正如我在回答中提到的那样,当字符串没有日期分隔符时,我们将面临widest form 规则。
    • @Stewart_R ...我的方法仅用于解析字符串Mdyyyy 格式。它不考虑其他格式。这就是为什么我说如果您的字符串始终具有 Mdyyyy 格式,我有一个解决方案。使用更广泛的说明符是一项规则,但他们仍然期望这些值是他们真正的用途。
    【解决方案3】:

    要解析你的字符串,首先在相关位置添加斜杠然后解析它

    string str = "642014";
    str = str.Insert(2,"/").Insert(1,"/"); 
    var result = DateTime.ParseExact(str, "M/d/yyyy",CultureInfo.InvariantCulture);
    

    【讨论】:

    • @Stewart_R 当然是。但这就是 OP 所要求的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多