2

看格式: "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]它也有效,但没有特定的格式。那么它是如何做到的呢?

4

3 回答 3

2

我用反射器来看看这个。几百行解析代码真的很复杂!

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

特别是一个被调用的函数internal TokenHashValue[] CreateTokenHashTable()有这样的事情:

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

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

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

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

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

结果是:永远不要解析这样的日期

总是ParseExact()

于 2013-03-07T12:42:59.637 回答
1

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

从文字“2013 年 3 月 7 日”的书写方式来看,我怀疑它们的解析可能有任何歧义。

  • Mar 完全匹配 MMM
  • 2003 完全匹配 yyyy
  • 7 完全匹配 d
于 2013-03-07T12:24:34.860 回答
1

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

您可以单击链接以深入了解私有方法,但这会变得复杂。但它看起来就像编译器一样进行词法分析和解析。该字符串被分解为多个部分(令牌),并尝试识别每个部分是一年、一个月还是什么。

当然可能会有一些歧义,例如,也许您的意思是 dd-MM-yyyy 但它被解析为 MM-dd-yyyy。但这就是您可以指定特定于文化的 IFormatProvider 的原因。

于 2013-03-07T12:38:11.047 回答