如何验证日期时间格式?

22

我需要让用户输入一个日期时间格式,但我需要对其进行验证以检查其是否可接受。用户可能会输入"yyyy-MM-dd"并且一切正常,但他们也可以输入"MM/yyyyMM/ddd"或任何其他组合。是否有一种方法可以验证这个格式?

9个回答

24

你是在寻找类似这样的东西吗?

DateTime expectedDate;
if (!DateTime.TryParse("07/27/2012", out expectedDate))
{
    Console.Write("Luke I am not your datetime.... NOOO!!!!!!!!!!!!!!");
}
如果您的用户知道所需格式的确切内容...
string[] formats = { "MM/dd/yyyy", "M/d/yyyy", "M/dd/yyyy", "MM/d/yyyy" };
DateTime expectedDate;
if (!DateTime.TryParseExact("07/27/2012", formats, new CultureInfo("en-US"), 
                            DateTimeStyles.None, out expectedDate))
{
    Console.Write("Thank you Mario, but the DateTime is in another format.");
}

2
这仅验证特定的日期时间。用户实际上正在输入“格式”本身。 - Kevin Cho
你对我来说不是很清楚...你希望用户以任何格式输入日期,并且希望它能够猜测正确的格式进行验证?你确定你的格式不会产生歧义吗?直接向用户建议使用特定的日期格式不是更好吗? - Diego D
3
Mindquake想要验证一个格式字符串,而不是日期字符串。 - Tergiver
2
+1 是为了 nerdy console writes,也是因为这是我在寻找的答案。 - Simon Tower
只是一个小提示:在匈牙利,人们使用“合并”的欧洲和美国日期格式:dd/MM/yyyy。因此,“18/02/2020”在那里完全有效。 - Alexander Khomenko

12

我不知道是否有任何方法可以实际验证用户输入的格式,因为有时您想故意包含可以转换为任何字符的字符。您可以考虑的一件事是允许用户通过显示其输入格式的预览来进行自我验证。


+1 这是我认为最好的答案。因为有效格式字符串的定义非常宽松,与用户确认是最好的解决方案。 - Tergiver
你不需要进行验证即可显示预览,因为如果你执行类似 DateTime.Now.ToString("This is made up and won't work"); 这样的操作,预览将显示 T1i30 i30 14a4e up an4 will noP work。你可以使用 try/catch 块来处理任何非常奇怪的情况。 - Jason

9

我假设您想知道指定的格式字符串是否有效...

为此,您可以回传它:

private bool IsValidDateFormat(string dateFormat)
{
    try
    {
        String dts=DateTime.Now.ToString(dateFormat, CultureInfo.InvariantCulture);
        DateTime.ParseExact(dts, dateFormat, CultureInfo.InvariantCulture);
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

这个不起作用。 - Gayan

4

除非我记错了,仅一个字符长的DateTime格式字符串是无效的。您可以假设任何2个或更多字符的DateTime格式字符串都是有效的。

DateTime.ParseExact("qq", "qq", null) == DateTime.Today
DateTime.ParseExact("myy", "501", null) == "05/01/2001"

标准(1个字符)
自定义(>1个字符)

参考,允许用作格式的单个字符字符串:

d,D,f,F,g,G,m,M,o,O,r,R,s,T,u,U,y,Y

任何其他字符(如单独的q)都是无效的。所有其他字符串都将被成功解析为格式化字符串。

1
你也可以在前面加上“%”来使单个字符的字符串有效。DateTime.Now.ToString("%x") == "x" - Markus Jarderot
@MarkusJarderot:没错,我试图强调“无效的DateTime格式”非常罕见,因为它非常灵活。实际上,任何无效格式的唯一原因是您不能将y视为h并获得奇怪的结果。 - Guvante

1
ZipXap的答案接受任何不抛出异常的格式,但是像“aaaa”这样的东西将通过验证并在午夜时给出当前日期(在编写此文时为“22年4月26日00:00:00”)。
更好的方法是使用DateTimeStyles.NoCurrentDateDefault选项,并将结果与default进行比较:
using System.Globalization;

var format = "aaaaa";
try {
    var dt = DateTime.ParseExact(
        DateTime.Now.ToString(format, CultureInfo.InvariantCulture),
        format,
        CultureInfo.InvariantCulture,
        DateTimeStyles.NoCurrentDateDefault);
    return dt != default;
} catch {
    return false;
}
/*
"aaaaa" -> false
"h" -> false
"hh" -> true
"fff" -> true
"gg" -> false
"yyyy gg" -> true
"'timezone: 'K" -> false
"zzz" -> false
*/

0
static private bool IsValidDateFormat(string dateFormat)
{
  try
  {
    DateTime pastDate = DateTime.Now.Date.Subtract(new TimeSpan(10, 0, 0, 0, 0));
    string pastDateString = pastDate.ToString(dateFormat, CultureInfo.InvariantCulture);
    DateTime parsedDate = DateTime.ParseExact(pastDateString, dateFormat, CultureInfo.InvariantCulture);
    if (parsedDate.Date.CompareTo(pastDate.Date) ==0)
    {
      return true;
    }
    return false;
  }
  catch
  {
    return false;
  }
}

我使用这段代码 - 这是对Shapiro Yaacov发布的代码进行修改。 看起来"DateTime.ParseExact"在使用无效的日期格式字符串时不会抛出异常 - 它只会返回"DateTime.Now"。 我的方法是将过去的日期转换为字符串,然后检查ParseExact()是否返回该字符串。


0

你没有谈论你的验证策略。无论如何,你应该使用涉及正则表达式的东西,然后应用允许的模式。这将有助于防止形式上的有效性..然后你必须关心实际内容,并确保值根据月份、日期和年份是正确的。

无论如何,有几个人建议使用DateTime.TryParse()方法让基质为你处理。但你仍然必须指定格式!所以没有魔法!否则你会陷入歧义


-1

这对我有效 -

try
{
  String formattedDate = DateTime.Now.ToString(dateFormat);
  DateTime.Parse(formattedDate);
  return true;
}
catch (Exception)
{
  return false;
}

-2
我的解决方案是将输入字段标记为只读,并允许用户仅通过jqueryui datepicker更改值。
这很直观。您可以指定所需的格式,只需要验证此格式即可。
否则,您可能会遇到麻烦。对于美国来说,"02/03/2020"是二月三日,但对于南美洲来说,则是三月二日。而且全球还有很多其他日期格式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接