2013-03-07 39 views
2

看格式:​​3210Datetime.Parse()可交換格式?

這是工作

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]它也可以工作,但沒有特定的格式。那它怎麼做呢?

+0

您認爲DateTime.Parse()使用由GetAllDateTimePatterns()返回的模式是不正確的。我已經將你鏈接到參考源,看看System.DateTimeParse.Lex() – 2013-03-07 12:53:26

+0

@HansPassant你是對的。它似乎是所有與標準格式字符串對應的自定義格式字符串。和**不是**,因爲我假設解析)。謝謝:-) – 2013-03-07 13:06:46

回答

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,它仍然的作品,但它假定第一個是天,第二個月(爲英國文化 - 我敢打賭,這是對其他文化的不同)。

這當然可以讓它在沒有警告的情況下解析模糊的日期。

結果是:NEVER解析的日期像這樣

始終ParseExact()

1

我想它是使用格式說明符,而不是他們的安排。

從字面意思是「2013年3月7日」的寫法,我懷疑它們在解析中可能會有歧義。

  • 匹配月確切MMM
  • 2003場比賽正好YYYY
  • 7場比賽正好Ð
+0

(另一個例子):DDD可以'Mon'(星期一),但MMM可以'Mar'(比賽),他們都長3.所以它是如何知道這是誰? – 2013-03-07 12:25:46

+0

@RoyiNamir我是指的你在上面「MMM d YYYY」指定的確切格式 – scartag 2013-03-07 12:27:58

+1

@RoyiNamir這可能是爲什麼ParseExact存在..在不確定性可能存在:) – scartag 2013-03-07 12:30:10

1

我找到了一個鏈接到DateTime.Parse源代碼在這裏: http://typedescriptor.net/name/members/5B57671F27DBC0AEA0EB9825243834CF-System.DateTime.Parse(String,IFormatProvider,DateTimeStyles)

你可以點擊鏈接深入挖掘私有方法,但它變得複雜。但它看起來像一個編譯器一樣輕鬆和解析。該字符串被分解成部分(令牌),並試圖識別每個是一年還是一個月。

當然可能有一些不明確的地方,例如,也許你的意思是dd-MM-yyyy,但它解析爲MM-dd-yyyy。但這就是爲什麼你可以指定一個文化特定的IFormatProvider。