具有“ddd”格式的DateTime.TryParseExact在除当前之外的所有日期都失败

时间:2015-07-01 10:05:42

标签: c# date datetime

我遇到了一个奇怪的问题。现在是星期三,并且:

DateTime date;
DateTime.TryParseExact(
   "Wed", "ddd", null, System.Globalization.DateTimeStyles.None, out date); // true

DateTime.TryParseExact(
   "Mon", "ddd", null, System.Globalization.DateTimeStyles.None, out date); // false

当我将计算机上的本地日期更改为星期一输出交换为'false-true'时。

为什么解析器依赖于当前日期?

2 个答案:

答案 0 :(得分:4)

怀疑问题是你的日期格式非常不完整。通常,DateTime.TryParseExact将使用未指定的任何字段的当前时间和日期。在这里,您指定的是星期几,这实际上并不足以获得实际日期...所以我怀疑文本值仅用于验证它是在将DateTime默认为“现在”之后的合理日期。 (如果它确实设法根据日期名称进行解析,则最终得到今天的日期。)

我刚刚完成了另一项测试,我们也指定了日期值,最终得到了有趣的结果 - 它似乎使用了当年的第一个月:

using System;
using System.Globalization;

class Test
{    
    public static void Main (string[] args)
    {
        // Note: All tests designed for 2015.
        // January 1st 2015 was a Thursday.
        TryParse("01 Wed"); // False
        TryParse("01 Thu"); // True - 2015-01-01
        TryParse("02 Thu"); // False
        TryParse("02 Fri"); // True - 2015-01-02
    }

    private static void TryParse(string text)
    {
        DateTime date;
        bool result = DateTime.TryParseExact(
            text, "dd ddd", CultureInfo.InvariantCulture, 0, out date);
        Console.WriteLine("{0}: {1} {2:yyyy-MM-dd}", text, result, date);
    }
}

将系统日期更改为2016年的结果与2016年1月的查找日期一致。

从根本上说,试图解析这样的不完整,因为这本质上是奇怪的。仔细考虑你真正想要实现的目标。

答案 1 :(得分:1)

如果您想要验证部分日期,为什么不使用正则表达式?

https://dotnetfiddle.net/ieokVz

using System;
using System.Text.RegularExpressions;

public class Program
{
public static void Main()
{

    string pattern = "(Mon|Tue|Wed|Thu|Fri|Sat|Sun)";

    string[] values = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun","Bun","Boo","Moo"};

    Console.WriteLine("");


    foreach(var val in values){

        Console.WriteLine("{0} ? {1}",val,Regex.IsMatch(val,pattern));

    }
    }
}

根据@ Jon的评论 https://dotnetfiddle.net/I4R2ZT

    using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {

        var matches = new HashSet<String>(System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.AbbreviatedDayNames,StringComparer.OrdinalIgnoreCase);

        string[] values = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun","Bun","Boo","Moo","Foo","Bar"};


        foreach(var val in values){

            Console.WriteLine("{0} ? {1}", val, matches.Contains(val));

        }
    }
}