在C#中编写IsDate()等价物?

时间:2010-10-15 13:08:10

标签: c# validation datetime

如果之前有人问过,请道歉。我有一些数据需要存储为字符串,其中一些数据是日期。数据以“01/02/10”(英国格式)等字符串开头。现在,稍后,这个数据被解析,并且根据解析的不同,结果是不同的(例如,01-Feb-10对比02-Jan-10)。鉴于数据以字符串形式开始,在我存储它之前,我想说,“如果这看起来像日期,请将其格式化为dd-mmm-yy”

很多事情看起来像是DateTime.Parse()函数的日期。

所以,我应用了一些规则,只接受了我的检查的“合理”日期格式,并写了一个IsDate()函数。我正在寻求关于如何做到这一点的建议,因为虽然它有效,但我的解决方案看起来非常笨重。

如果你曾经开始在它上面抛出随机字符串(比如“3/4”和“6.12”),那么为什么我这样做而不是通常使用DateTime.TryParse例程的原因很明显。

这是我到目前为止所拥有的:

class Program
{
  static void Main(string[] args)
  {
     Debug.Assert(IsDate(6.12) == false);
     Debug.Assert(IsDate("3/4") == false);
     Debug.Assert(IsDate(010210) == false);
     Debug.Assert(IsDate("010210") == false);
     Debug.Assert(IsDate("12-jan-2000") == true);
     Debug.Assert(IsDate("12-12-20") == true);
     Debug.Assert(IsDate("1/1/34") == true);
     Debug.Assert(IsDate("09/30/20") == false);
     Debug.Assert(IsDate(DateTime.Now) == true);
  }

  static Boolean IsDate(Object value)
  {
     DateTimeFormatInfo DateTimeFormatGB = new CultureInfo("en-GB").DateTimeFormat; // new CultureInfo("en-US").DateTimeFormat;
     return IsDate(value, DateTimeFormatGB);
  }

  static private List<String> AcceptableDateFormats = new List<String>(72);
  static Boolean IsDate(Object value, DateTimeFormatInfo formatInfo)
  {
     if (AcceptableDateFormats.Count == 0)
     {
        foreach (var dateFormat in new[] { "d", "dd" })
        {
           foreach (var monthFormat in new[] { "M", "MM", "MMM" })
           {
              foreach (var yearFormat in new[] { "yy", "yyyy" })
              {
                 foreach (var separator in new[] { "-", "/" }) // formatInfo.DateSeparator ?
                 {
                    String shortDateFormat;
                    shortDateFormat = dateFormat + separator + monthFormat + separator + yearFormat;
                    AcceptableDateFormats.Add(shortDateFormat);
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH:mm"); // formatInfo.TimeSeparator
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH:mm:ss");
                 }
              }
           }
        }
     }

     String sValue = value.ToString().Trim();
     DateTime unused;

     foreach (String format in AcceptableDateFormats)
     {
        if (DateTime.TryParseExact(sValue, format, formatInfo, DateTimeStyles.None, out unused) == true) return true;
     }

     return false;
  }
}

我没有使用文化信息中的日期/时间分隔符,因为我想同时接受“/”和“ - ”。我想我可以使用时间,因为这不太可能改变(对我而言)。

9 个答案:

答案 0 :(得分:7)

您是否检查了DateTime.TryParse()的替代覆盖,它可以让您更好地控制它认为是日期的内容?

答案 1 :(得分:6)

答案 2 :(得分:6)

将字符串转换为日期您可以指定使用该特定格式的区域性: 我们想将字符串日期“dd / MM / yyyy”转换为Date ..

datetime mydate = Convert.ToDateTime(
txtdate.Text, CultureInfo.GetCulture("en-GB")
);

或使用ParseExact方法:

datetime mydate = DateTime.ParseExact(
txtdate.Text, "dd/MM/yyyy", CultureInfo.Invariant
);

ParseExact方法只接受该特定格式,而Convert.ToDateTime方法仍然允许格式的某些变体,并且还接受一些其他日期格式。

要捕获非法输入,可以使用TryParseExact方法:

DateTime d;
if (DateTime.TryParseExact(txtdate.Text, "dd/MM/yyyy", CultureInfo.Invariant, DateTimeStyles.None, out d)) {
datetime mydate = d;
} else {
// communcate the failure to the user
} 

我希望以下链接可以为您提供一些帮助:

http://dotnetacademy.blogspot.com/2010/09/convert-string-to-date.html

http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx

http://msdn.microsoft.com/en-us/library/9h21f14e.aspx

http://dotnetacademy.blogspot.com/2009/10/get-current-system-date-format.html

这是tryParse的示例: http://dotnetperls.com/datetime-tryparse

答案 3 :(得分:1)

您是否检查过尝试接受DateTime.TryParseIFormatProvider参数的DateTimeStyles重载?您可以使用它来更加挑剔您接受的实际日期,同时不必为了测试字符串而不必要地抛出异常。

答案 4 :(得分:1)

尝试

DateTime result;
DateTime.TryParseExact(value.ToString(), new string[] { "dd/MM/yyyy", "d/M/yyyy" }, null, DateTimeStyles.None, out result)

答案 5 :(得分:1)

最后,我选择了以下版本:

  static private List<String> AcceptableDateFormats = new List<String>(180);
  static Boolean IsDate(Object value, DateTimeFormatInfo formatInfo)
  {
     if (AcceptableDateFormats.Count == 0)
     {
        foreach (var dateFormat in new[] { "d", "dd" })
        {
           foreach (var monthFormat in new[] { "M", "MM", "MMM" })
           {
              foreach (var yearFormat in new[] { "yy", "yyyy" })
              {
                 foreach (var separator in new[] { "-", "/", formatInfo.DateSeparator  })
                 {
                    String shortDateFormat;
                    shortDateFormat = dateFormat + separator + monthFormat + separator + yearFormat;
                    AcceptableDateFormats.Add(shortDateFormat);
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH:mm");
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH:mm:ss");
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH" + formatInfo.TimeSeparator + "mm");
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH" + formatInfo.TimeSeparator + "mm" + formatInfo.TimeSeparator + "ss");
                 }
              }
           }
        }
        AcceptableDateFormats = AcceptableDateFormats.Distinct().ToList();
     }

     DateTime unused;
     return DateTime.TryParseExact(value.ToString(), AcceptableDateFormats.ToArray(), formatInfo, DateTimeStyles.AllowWhiteSpaces, out unused);
  }

答案 6 :(得分:1)

这显然是一个hack,但我最终做的是添加VisualBasic Reference并只使用C#中的IsDate函数:

using Microsoft.VisualBasic;
//...other code...
if (Information.IsDate(YourDateObject)) {
   //...more code...
}

答案 7 :(得分:0)

或者,如果您需要更高程度的控制,您可以在找到潜在日期后进行自己的正则表达式检查。 像这样的东西。

^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$

根据您的要求涵盖xx-yy-zz和xx / yy / zz

答案 8 :(得分:0)

using System.Globalization;

CultureInfo ukCI = CultureInfo.CreateSpecificCulture("en-GB");
Console.WriteLine(DateTime.Parse("1/2/2010", ukCI).ToString("dd-MMM-yyyy"));

如果您要验证参数是否为日期,则可以使用TryParse代替Parse

相关问题