【问题标题】:How to parse a date with spaces?如何解析带空格的日期?
【发布时间】:2021-11-01 16:05:08
【问题描述】:

我有这个日期:" 1 21998",这是 1998 年 2 月 1 日。它的格式有点不正确,因为应该有零而不是空格,但它在我必须处理的一些文本文件中。我不知道如何用 C# 解析它。谁能给我一个线索?

我尝试了以下方法,但没有得到任何结果:

DateTime date;
string input = " 1 21998";

if (DateTime.TryParseExact(input, "ddMMyyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out date))
{
    Console.WriteLine("1: " + date);
}
else if (DateTime.TryParseExact(input, "ddMMyyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date))
{
    Console.WriteLine("2: " + date);
}
else if (DateTime.TryParseExact(input, "dMyyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out date))
{
    Console.WriteLine("3: " + date);
}
else if (DateTime.TryParseExact(input, "dMyyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date))
{
    Console.WriteLine("4: " + date);
}
else if (DateTime.TryParseExact(input, " d Myyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out date))
{
    Console.WriteLine("5: " + date);
}
else if (DateTime.TryParseExact(input, " d Myyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date))
{
    Console.WriteLine("6: " + date);
}

if (DateTime.TryParse(input, out date))
{
    Console.WriteLine("7: " + date);
}
else if (DateTime.TryParse(input, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date))
{
    Console.WriteLine("8: " + date);
}

【问题讨论】:

  • 您可以在解析字符串之前对其进行处理。从右侧取 4 个字符,然后将左侧部分与空格分开,您将获得所需的部分。然后您可以以可解析的方式连接这些部分或将它们转换为整数并直接创建DateTime
  • 你能在尝试解析它们之前将空格替换为零吗?
  • 你能给出 2 个符号月份和日期的例子吗?如果它们不包含空格 - 那么用零替换空格并使用 "ddMMyyyy" 应该可以解决问题。
  • 当然可以先替换空格。但我想知道是否没有办法直接使用TryParseExact()TryParse()

标签: c# .net datetime


【解决方案1】:

模式" d Myyyy" 对输入" 1 21998" 是正确的;只是解析器为了可变长度的连接而举手。

我没有查看源代码,但我猜解析器首先尝试将字符串分解为与模式匹配的单个组件,然后再尝试解析实际值。

所以解析器不会知道你的五位字符串“21998”的前 one 或前 2 位是否属于月份,即使有不是第 21 个月,并且您指定年份为四位数。

如果你在月份前面加上零或一,它就会起作用:

  • " 1 021998" -> 02/01/1998
  • " 1 121998" -> 12/01/1998

docs 说,在“备注”下:

如果 format 是不包含日期或时间分隔符的自定义格式模式(例如“yyyyMMddHHmm”),请使用提供程序参数的不变区域性和每个自定义格式说明符的最宽形式。例如,如果您想在格式模式中指定小时,请指定较宽的格式“HH”,而不是较窄的格式“H”。

不确定这是什么意思,但 " dd MMyyyy""ddMMyyyy" 都适用于原始输入。我猜他们的意思是你应该在不写分隔符的时候日期。

问题不在于空格;这是缺乏的。这些工作:

  • "dMyyyy"" 1 2 1998"(与DateTimeStyles.AllowWhiteSpaces
  • "ddMMyyyy""01021998"(与DateTimeStyles.None
  • " dd MM yyyy"" 01 02 1998"(与DateTimeStyles.None

鉴于您的输入是固定长度的,如果月份大于 9,则该模式将再次中断(" 1102021" 也不会因为与以前相同的原因进行解析)。

最简单的解决方案是通过分解字符串来手动解析它,将它们解析为整数并将它们传递给new DateTime(year, month, day)

var day = int.Parse(input[0..2], NumberStyles.AllowLeadingWhite);
var month = int.Parse(input[2..4], NumberStyles.AllowLeadingWhite);
var year = int.Parse(input[4..8], NumberStyles.AllowLeadingWhite);

var date = new DateTime(year, month, day);

【讨论】:

  • 感谢您的精彩解释。如果无法解析,将日期字段分成三部分是我已经做过的。所以我会保留我的解决方案。
【解决方案2】:

你能不能把输入中的所有空格都变成0,然后它应该是一个有效的日期格式?

input.Replace(" ", "0");

可能还想在第 2 和第 4 索引之后放置 /。

input.Insert(2, "/");

【讨论】:

    猜你喜欢
    • 2011-08-18
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多