DateTime.TryParseExact解析日期值但添加默认时间值(没有的地方)

c#

c#-8.0

编辑:因为我有很多关于使用 TryParseExact 与单一格式而不是数组的评论:

  • 我必须测试数组中的所有格式 - 输入可能是这些格式,我对这些其他格式的单元测试实际上有效。我必须全部使用它们。
  • 我知道 DateTime.TryParse 将匹配第一个而不是进一步迭代。因此我使用 TryParseExact作为 Microsoft 显示。它应该完全匹配。但它在这种情况下不起作用。

TLDR:给定一个"dd/MM/yyyy"具有值"29/11/2019"DateTime.TryParseExact的格式字符串,返回具有格式"dd/MM/yyyy hh:mm tt"和值的匹配项29/11/2019 12:00 AM。为什么?

问题:如何确保格式字符串作为与格式"dd/MM/yyyy"匹配"dd/MM/yyyy"而不是"dd/MM/yyyy hh:mm tt"在使用 TryParseExact 时返回?

Context的长解释;

我有以下问题。我需要将多种日期格式从字符串解析为日期时间值。它们(输入字符串)可以以下列格式出现:

{ "dd/MM/yyyy hh:mm tt", "dd/M/yyyy hh:mm tt", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:m", "dd/MM/yyyy", "dd-MM-yyyy", "d-M-yyyy", "dddd, d MMMM yyyy"};

为了解决这个问题,我编写了一个字符串扩展来解析给定的输入字符串并返回一个 bool 成功和一个潜在的匹配格式。

  private static readonly string[] _DateFormats = new string[] { "dd/MM/yyyy hh:mm tt", "dd/M/yyyy hh:mm tt", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:m", "dd/MM/yyyy", "dd-MM-yyyy", "d-M-yyyy", "dddd, d MMMM yyyy"};

  public static bool StringToDateTime(this string dateTimeString, out DateTime dateTimeValue, out string matchingFormat)
  {
      matchingFormat = ""; // defaults
      dateTimeValue = new DateTime();
      if (string.IsNullOrEmpty(dateTimeString)) return false;
      foreach (string format in DateFormats)
      {
          matchingFormat = format;
          if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue)) return true;
      }
      return false;
  }

这将字符串输入"29/11/2019 successfully"作为 DateTime返回,29/11/2019 12:00 AM匹配格式为"dd/MM/yyyy hh:mm tt",而不是与原始输入匹配的格式29/11/2019

鉴于这个问题,我能想到的唯一(管道胶带)解决方案是:

public static bool StringToDateTime(this string dateTimeString, out DateTime dateTimeValue, out string matchingFormat)
{
    matchingFormat = ""; // defaults
    dateTimeValue = new DateTime();
    if (string.IsNullOrEmpty(dateTimeString)) return false;
    foreach (string format in DateFormats)
    {
        matchingFormat = format;
        if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue))
        {
            // ensure the datetime format is consistent with the dateTimeString passed to us.
            if(dateTimeString.Length != matchingFormat.Length)
            {
                var _matchingFormat = DateFormats.First(d => d.Length == dateTimeString.Length);
                matchingFormat = string.IsNullOrEmpty(_matchingFormat) ? matchingFormat : _matchingFormat;
            }
            return true;
        }
    }
    return false;
}

哪个有效,但显然,这还有其他问题(产生输入格式等)。所以我宁愿不使用这个。

回答

System.DateTime 不能在没有时间组件的情况下存在,因此不可能将日期解析为 DateTime 而不是时间组件。它将默认为一天的开始,例如 12:00 AM,这与调用 的结果相同dateTime.Date()。这将允许您在不考虑一天中的时间的情况下比较两个日期。

如果拥有或存储时间元素真的让您感到困扰,那么您可以创建自己的struct来存储日期,或者考虑使用像NodaTime这样提供仅日期结构的东西。

此外,Dotnet 6 将引入 DateOnly 和 TimeOnly 结构来做到这一点。您可以在MS devblogs上阅读有关它的更多信息。


以上是DateTime.TryParseExact解析日期值但添加默认时间值(没有的地方)的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>