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上阅读有关它的更多信息。