如果没有指定年份,如何使DateTime.TryParse()失败?

时间:2014-03-18 16:24:52

标签: c# parsing datetime

考虑以下代码来解析日期。 (请注意,我在EN-gb语言环境中):

const DateTimeStyles DATE_TIME_STYLES = DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowWhiteSpaces;
DateTime dt;

// Current culture for this example is "EN-gb".

if (DateTime.TryParse("31/12", CultureInfo.CurrentUICulture, DATE_TIME_STYLES, out dt))
    Console.WriteLine("Parsed correctly"); // Do not want!
else
    Console.WriteLine("Did not parse correctly.");

我故意省略这一年。但是,TryParse()将对此进行解析而不会出现任何错误,并将替换当前年份。

我希望能够强制用户输入日期的所有组件(使用他们的本地格式),所以我希望上面的解析失败 - 或者能够检测到用户没有进入一年。

我真的不想使用DateTime.TryParseExact()因为那时我必须添加代码来为所有不同支持的语言环境指定所有不同的有效格式,这是非常重要的并且可能容易出错。我怀疑这可能是我唯一理智的选择。

有人有任何想法吗? (在这里工作的人已经实施了一个“解决方案”,涉及不允许当年,这显然不是一个好的解决方案......)

3 个答案:

答案 0 :(得分:3)

您可以像这样使用解析并捕获异常。

CurrentUICulture.DateTimeFormat.ShortDatePattern会为您提供短日期模式。

还有DateTime.TryParseExact

DateTime.ParseExact(value.ToString(), cultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern.ToString, cultureInfo.CurrentUICulture)

答案 1 :(得分:3)

您可以查询文化模式,过滤掉那些没有一年的模式,然后对其余模式使用TryParseExact

var allPatterns = culture.DateTimeFormat.GetAllDateTimePatterns();
var patternsWithYear = allPatterns.Where(s => s.Contains("y")).ToArray();
bool success = TryParseExact(input, patternsWithYear, culture, styles, out dateTime);

已知错误:这不会考虑转义,您需要使用正确的解析来替换Contains("y")调用以解决此问题。

如果您对格式限制更严格,那么您可以只使用LongDatePatternShortDatePattern

答案 2 :(得分:2)

我想的越多,我认为这是一个糟糕的解决方案,但鉴于你没有得到其他答案,我会发布它。

DateTime temp;
DateTime.TryParse(input, CultureInfo.CurrentUICulture, DATE_TIME_STYLES, out temp);

if (temp.Year == DateTime.Now.Year)
{
    if (!input.Contains(DateTime.Now.Year))
    {
        if (temp.Days != int.Parse(DateTime.Now.Year.ToString().SubString(2)))
        {
             // my god that's gross but it tells you if the day is equal to the last two
             // digits of the current year, if that's the case make sure that value occurs
             // twice, if it doesn't then we know that no year was specified
        } 
    }
}

此外,正如其他人现在在评论中所建议的,检查令牌数量或字符串长度也可能有用;

char[] delims = new char[] { '/', '\', '-', ' '); //are there really any others?
bool yearFound = false;

foreach (char delim in delims)
{
    if (input.Split(delim).Count == 3)
    {
         yearFound = true;
         break;
    }
}

if (yearFound)
    //parse
else
    // error

这些只是一些想法,也不是真正合理的。他们显然都是黑客,只有你知道他们是否足够。至少他们打败了你的同事if (dt.Year == 2014) //discard input“解决方案”。