【问题标题】:How can I parse a datetime with a nonstandard format (yyyyMMdd:Hmm)?如何解析具有非标准格式 (yyyyMMdd:Hmm) 的日期时间?
【发布时间】:2021-10-04 14:21:00
【问题描述】:

我们有一个集成合作伙伴,他坚持以yyyyMMdd:Hmm 格式的字符串形式向我们发送日期时间,例如“20211029:102”。请注意,小时没有前导零。

我试着像这样解析它:

Datetime datetime = DateTime.ParseExact(
   "20211029:102", 
   "yyyyMMdd:hmm", 
   CultureInfo.InvariantCulture, 
   DateTimeStyles.None
);

但这会导致

FormatException••• 字符串“20211029:102”未被识别为有效 日期时间。

我可以通过重新添加缺失的零来使其工作,例如:

string datetimeParts = "20211029:102".Split(":");
string value = datetimeParts[0] + datetimeParts[1].PadLeft(4, '0');
Datetime dt = DateTime.ParseExact(
    value, 
    "yyyyMMddHHmm", 
    CultureInfo.InvariantCulture, 
    DateTimeStyles.None
);

但我觉得我不需要“预解析”该值。是否可以不经过预处理就解析这种格式?

【问题讨论】:

    标签: c# datetime parsing formatting cultureinfo


    【解决方案1】:

    问题出在格式字符串的时间部分,所以我的回答将解释为什么您不能用格式字符串Hmm 解析102(我知道你写了 hmm,但由于你没有 AM/PM 指示符,我假设你打算改写 Hmm。同样的推理适用于 hmm。)

    如果我们查看the reference source,我们可以看到DateTime 解析器是“贪婪的”:如果parser encounters a single-letter format specifier (such as H),它将still try to consume 2 digits, if two digits are available

    在您的情况下,两位数字可用,因此H 将消耗10102。这只会留下2 一分钟,它不会匹配mm(因为它只有一位数字)。

    鉴于此限制,无法使用DateTime.ParseExact 解析格式为Hmm 的日期时间值。 The documentation 注意到以下几点:

    注意

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

    【讨论】:

    • 为“yyyyMMdd:Hmm”和“yyyyMMdd:hmm”为什么不能工作的最佳答案干杯。 :-) 所以剩下的问题是是否有任何替代 Datetime.ParseExact 可以接受“H”?但考虑到反馈的要点,似乎有人会想......
    • @BrianKessler:我怀疑是否有替代方案,而且由于您有一个可读、有效的解决方案,我怀疑是否值得进一步努力寻找替代方案。
    • @BrianKessler:附带说明:正则表达式 do 支持回溯,所以像 (?<hour>[0-9]?[0-9])(?<minute>[0-9][0-9]) 这样的东西应该可以工作。但这也不会比您当前的解决方案更短。
    猜你喜欢
    • 2011-03-09
    • 2014-01-13
    • 2017-12-31
    • 2016-07-31
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    相关资源
    最近更新 更多