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



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

  • 我必须测试数组中的所有格式-输入可能是这些格式,而我对这些其他格式的单元测试实际上可以工作。我必须全部使用
  • 我知道DateTime.TryParse会匹配第一个,不会进一步迭代。因此,我使用TryParseExact,正如微软所展示的那样。它应该与完全匹配。但在这种情况下是行不通的

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

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

上下文的详细解释;

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

{ "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"返回为DateTime29/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,这与调用dateTime.Date()的结果相同。这将允许您在不考虑一天中的时间的情况下比较两个日期。

如果拥有或存储时间元素确实让您感到困扰,那么您可以创建自己的struct来存储日期,也可以考虑使用NodaTime之类的只提供日期结构的东西。

此外,Dotnet6将引入DateOnly和TimeOnly结构来实现这一点。您可以在MS开发博客上阅读更多关于它的信息。

您正在传递整个格式数组,因此它将匹配其中任何一个

由于您处于foreach而非DateFormats,因此您只需要与当前值相匹配。

所以更换这条线路

if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue))
return true;

用这个

if (DateTime.TryParseExact(dateTimeString, format, AUSCulture, DateTimeStyle, out dateTimeValue))
return true;

相关内容

  • 没有找到相关文章

最新更新