Datetime.Parse()可交换格式?

时间:2013-03-07 12:18:39

标签: c# .net datetime

查看格式:"MMM d yyyy"

这是有效的

var t="Mar 2013 7";
DateTime dt=DateTime.Parse(t);

但是

also this :"Mar 7 2013"
and  this :"7  Mar 2013"

正在运作

看着:

new DateTimeFormatInfo()
               .GetAllDateTimePatterns()
               .Select((i,n)=>n+"    "+i)
               .ToList()
               .ForEach(f=>Console.WriteLine(f));
  

哪个是日期和时间值可以使用的所有标准模式   格式化。

结果是:

0    MM/dd/yyyy
1    yyyy-MM-dd
2    dddd, dd MMMM yyyy
3    dddd, dd MMMM yyyy HH:mm
4    dddd, dd MMMM yyyy hh:mm tt
5    dddd, dd MMMM yyyy H:mm
6    dddd, dd MMMM yyyy h:mm tt
7    dddd, dd MMMM yyyy HH:mm:ss
8    MM/dd/yyyy HH:mm
9    MM/dd/yyyy hh:mm tt
10    MM/dd/yyyy H:mm
11    MM/dd/yyyy h:mm tt
12    yyyy-MM-dd HH:mm
13    yyyy-MM-dd hh:mm tt
14    yyyy-MM-dd H:mm
15    yyyy-MM-dd h:mm tt
16    MM/dd/yyyy HH:mm:ss
17    yyyy-MM-dd HH:mm:ss
18    MMMM dd
19    MMMM dd
20    yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK
21    yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK
22    ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
23    ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
24    yyyy'-'MM'-'dd'T'HH':'mm':'ss
25    HH:mm
26    hh:mm tt
27    H:mm
28    h:mm tt
29    HH:mm:ss
30    yyyy'-'MM'-'dd HH':'mm':'ss'Z'
31    dddd, dd MMMM yyyy HH:mm:ss
32    yyyy MMMM
33    yyyy MMMM

问题:

  • 我在列表中看不到MMM d yyyy格式。那怎么做呢?它会尝试所有组合吗?

  • 如何为格式MMM d yyyy添加时间? [Mar 3 2007 13:13:13]它也可以,但没有具体的格式。那怎么做呢?

3 个答案:

答案 0 :(得分:2)

我用Reflector来看这个。有数百行解析代码真的很复杂!

然而,最终它最终会对输入字符串进行标记,并尝试将标记分类为日期名称,月份名称,年份,日期等。

特别是一个名为internal TokenHashValue[] CreateTokenHashTable()的函数有这样的东西:

for (int i = 1; i <= 12; i++)
{
    this.InsertHash(dtfiTokenHash, this.GetAbbreviatedMonthName(i), TokenType.MonthToken, i);
}

它使用它(如您所见,具有所有缩写的月份名称)来确定令牌是否是月份名称。日名的代码类似。

解析代码还会检查其中一个数字是否大于2位数。如果是,它假定它是一年。这意味着(并且您可以验证它)您可以拥有3位数的年份,它仍然可以解析它。但它变得更加复杂!它还检查数字是否大于12,如果是这样,则假定它是一年。

如果你把两个数字分别小于或等于12,它仍然有效,但它假设第一个是一天,第二个是一个月(对于英国文化 - 我打赌它是与其他文化不同)。

这当然允许它在没有警告的情况下解析模棱两可的日期。

Upshot是:永远不会像这样日期

始终ParseExact()

答案 1 :(得分:1)

我猜它是使用格式说明符而不是它们的排列。

从文字“Mar 2013 7”的编写方式来看,我怀疑它们在解析时可能有任何含糊之处。

  • Mar完全匹配MMM
  • 2003完全匹配yyyy
  • 7匹配d

答案 2 :(得分:1)

我在这里找到了DateTime.Parse源代码的链接: http://typedescriptor.net/name/members/5B57671F27DBC0AEA0EB9825243834CF-System.DateTime.Parse(String,IFormatProvider,DateTimeStyles)

您可以点击链接深入了解私有方法,但它变得复杂。但它看起来像lexing和解析很像编译器。字符串被分解为部分(标记),它会尝试识别每个字符串是一年,一个月,等等。

当然可能存在一些歧义,例如:也许你的意思是dd-MM-yyyy,但它解析为MM-dd-yyyy。但这就是为什么你可以指定一个特定于文化的IFormatProvider。