【发布时间】:2021-06-29 07:51:53
【问题描述】:
编辑:因为我有很多关于使用单一格式而不是数组的 TryParseExact 的 cmets:
- 我必须测试数组中的所有格式 - 输入可能是这些格式,而我对这些其他格式的单元测试确实有效。我必须全部使用它们。
- 我知道 DateTime.TryParse 将匹配第一个而不是进一步迭代。因此我使用 TryParseExact as Microsoft shows。它应该完全匹配。但它在这种情况下不起作用。
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" 作为日期时间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;
}
这可行,但显然,这还有其他问题(产生输入格式等)。所以我宁愿不用这个。
【问题讨论】:
-
你的意思是什么确切“返回与格式的匹配”?
DateTime总是有一个时间组件,默认是午夜。此外,DateTime没有格式,它是一个表示日期和时间的值,将其转换为字符串涉及格式。只需在调试器中查看DateTime值通常也会显示时间组件。 .NET 6 将获得TimeOnly和DateOnly类型,不会有这个,但DateTime总是 有日期和时间组件。 -
请edit your post,以便它包含正确的minimal reproducible example,以及对代码的作用、与您的预期有何不同以及确切 你需要帮助。除了您似乎混淆了
TryParse()和TryParseExact()(您在上面提到了两者)这一事实之外,您似乎对DateTime值的工作方式有一些不合理/不正确的期望。 -
正如其他人所说,
DateTime没有格式。在内部,它只是one 64-bit integer。 -
我指的是从我的函数返回的时间格式。我将对其进行编辑以使其更加清晰。我认为 TLDR 说它以该值返回已经很清楚了。
-
@Karlsen 我了解两者的工作原理,并且我绝对在寻找与 TryParseExact 完全匹配的方法。我在这里指的是 TryParse 和 TryParse 的同义词,因为两者都与我的问题无关:如何确保格式为“dd/MM/yyyy”的字符串与格式“dd/MM/”匹配返回使用 TryParseExact 时使用 yyyy" 而不是 "dd/MM/yyyy hh:mm tt"?