在C#中解析日期/时间的最松散的方法是什么?

时间:2018-05-17 15:31:19

标签: c# .net date datetime time

我正在解析各种各样的RSS源 - 显然他们都用自己的方式来显示文章的时间戳。

现在我们甚至找到了一个使用本地字词的字词,例如Donderdag 17 juli 2018

目前我们有一个后备机制,当我们无法解析日期时,我们会回到DateTime.UtcNow。

我仍然想做出最好的尝试。在C#中真正松散地解析DateTime的最佳方法是什么?所以它可以处理即:。

  
      
  • 13-11-2018 14.32
  •   
  • donderdag,2018年11月13日,14:32
  •   
  • 2011年11月13日
  •   
  • 14:32 13.11.2018
  •   
  • 2018-11-13T16:32:00 + 2:00
  •   

等。我知道这不是万无一失的,但我还是想做出最好的尝试。

有推荐方法吗?或者我必须自己滚动?

4 个答案:

答案 0 :(得分:3)

您可以使用DateTime.TryParseExact并包含所有预期的formats

DateTime result;
if( DateTime.TryParseExact(input, new [] {"dd-MM-yyyy HH.mm", "dddd dd MMMM yyyy, HH:mm", "more formats here"}, CultureInfo.CreateSpecificCulture("nl-NL"), DateTimeStyles.None, out result)) {
  Console.WriteLine("Succeeded " + result);
}

这里唯一的大问题是日期格式,日期和月份处于不明确的位置。我在你的例子中没有看到任何内容,但如果你要将文化混合在一个流中,那么它可能会成为一个问题。例如,美国通常会在月份开始格式化日期,而荷兰则在月份的某一天开始。如果这是一个问题,那么在上面的用例中无法动态处理这个问题,除非您还从RSS流中获取文化,在这种情况下您可以尝试创建一组特定于文化的解析规则

答案 1 :(得分:0)

此建议并非特定于日期时间,但您可以尝试使用parser combinators,尤其是在您决定推出自己的解决方案时。 例如,.net,Sprache有多个库。

答案 2 :(得分:0)

如果数据可能不是一个好主意,则可以从混合源中轻松解析日期时间。像微软的文本到语音可能会尝试一些东西,但它有时会产生读取连续日期的效果

10月1日,11月1日,12月1日,1月13日等。

松散解析的唯一方法是可以使用,如果可以使用的话 其他提示将日期与写入日期的内容相关联。如果您在特定订阅源的顶级有一堆日期,并且您发现适用于所有这些的所有解析模式产生相同的结果,那么该解析模式可能正确地解析日期。然而,这种努力的最大部分可能不会解析日期,而是(1)确保以不同格式编写的日期分别进行分组,以及(2)提供运营商可以协助的日期。程序在有麻烦的地方。

顺便说一下,我不知道解析程序的任何日期是否使用附加的工作日作为格式验证的一部分,但它们通常可以提供帮助。例如,“2-1-2018”可以是1月2日或2月1日,但“2-1-2018周四”只能是后者。从未完全建立格式的源解析数字日期以确定每个解析方法的工作日时间并检查输入是否包含与工作日匹配而不是另一个工作日的内容时,它可能会有所帮助。 / p>

答案 3 :(得分:0)

您可以使用TryParse方法尝试解析字符串,同时循环遍历所有文化以捕获字符串中的任何文化差异。以下方法将解析所有文化的所有标准格式,并在out参数中返回日期(如果已找到)。

请注意,此处的危险是某些日期的月和日值不明确(任何小于13的数字可能是一个月或一天)。在这种情况下,结果将是找到匹配的第一个文化,这可能不正确。

以下是代码:

public static bool TryParseAllCultures(string formattedDate, 
    out DateTime result)
{
    // First try in our local culture
    if (DateTime.TryParse(formattedDate, out result)) return true;

    foreach (var cultureInfo in CultureInfo.GetCultures(CultureTypes.AllCultures))
    {
        if (DateTime.TryParse(formattedDate, cultureInfo, DateTimeStyles.None, 
            out result))
        {
            return true;
        }
    }

    return false;
}

示例用法

注意:我修改了您的一个日期,因为日期本身无效!第二个日期曾经是“donderdag 13 2018年11月”,除了13日是dienstag(星期二),而不是donderdag(星期四)。

private static void Main()
{
    DateTime date;

    var dateFormats = new List<string>
    {
        "13-11-2018 14.32",
        "donderdag 15 november 2018, 14:32",
        "13 nov 2018",
        "14:32 13.11.2018",
        "2018-11-13T16:32:00+2:00"
    };

    DateTime result;

    foreach (var dateFormat in dateFormats)
    {
        if (TryParseAllCultures(dateFormat, out result))
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"SUCCESS: {dateFormat.PadRight(36, '.')} {result}");
        }
        else
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine($"ERROR: Unable to parse format: {dateFormat}");
        }

        Console.ResetColor();
    }

    GetKeyFromUser("\nDone! Press any key to exit...");
}

<强>输出

enter image description here