2017-04-11 19 views
31
DateTime.Parse("AD3AD08") 

[2017-08-03 12:00:00 AM] 

Tại sao chuỗi đó (trông giống như một chuỗi hex bình thường đối với tôi) được phân tích cú pháp thành công dưới dạng một ngày? Tôi có thể thấy số 3 và số 8 được phân tích theo tháng và ngày. Nhưng nếu không nó không hợp lý với tôi.Tại sao AD3AD08 đại diện cho một ngày hợp lệ trong khuôn khổ .NET?

+0

trình nếu tôi thay đổi văn hóa hiện tại của tôi cho 'en-US' hoặc' en-GB', không biết tại sao hoặc –

+0

Ngay cả đối với 'DateTime.Parse ("AD3AD08", CultureInfo.InvariantCulture); ' – xanatos

+0

Đây là tên thời đại (AD = anno domini) – xanatos

Trả lời

19

tl; dr: Bạn có thể sử dụng số DateTimeFormatInfo.GetEraName/GetAbbreviatedEraName trở lại làm dấu phân tách, bỏ qua trường hợp. Thứ tự là: ngày, tháng, năm (tùy chọn).


Dường như bạn luôn có thể sử dụng của lịch hiện era's abbreviated name hoặc full era-name như delimiter cho các thẻ DateTime. Đối với nền văn hóa tiếng Anh, nó là AD hoặc A.D., ví dụ: đối với nền văn hóa Đức là n. Chr..

var enCulture = new CultureInfo("en-GB"); 
System.Threading.Thread.CurrentThread.CurrentCulture = enCulture; 
var fi = enCulture.DateTimeFormat; 
int currentEra = enCulture.Calendar.GetEra(DateTime.Now); 
var eraName = fi.GetEraName(currentEra); 
var shortEra = fi.GetAbbreviatedEraName(currentEra); 
var date = DateTime.Parse($"{shortEra}3{shortEra}08"); // AD or A.D. works 

var deCulture = new CultureInfo("de-DE"); 
System.Threading.Thread.CurrentThread.CurrentCulture = deCulture; 
fi = deCulture.DateTimeFormat; 
currentEra = deCulture.Calendar.GetEra(DateTime.Now); 
eraName = fi.GetEraName(currentEra); 
shortEra = fi.GetAbbreviatedEraName(currentEra); 
date = DateTime.Parse($"{shortEra}3{shortEra}08"); // n. Chr. works 

Điều thú vị là phân biệt chữ hoa chữ thường, do đó, ad cũng hoạt động. Đó là tài liệu trong DateTimeFormatInfo.GetEra:

Tên kỷ nguyên là tên một cuốn lịch sử dụng để chỉ một khoảng thời gian xem thuộc từ một điểm cố định hoặc sự kiện. Ví dụ: "A.D." hoặc "C.E." là thời đại hiện tại trong lịch Gregorian. So sánh với ageName là không phân biệt chữ hoa chữ thường, ví dụ: "A.D" tương đương với "a.d.".

Lịch gregorian chỉ có một kỷ nguyên, vì vậy Calendar.GetEra(DateTime.Now) không thực sự cần thiết. Tôi chưa tìm thấy bất kỳ tài liệu nào khác.

Dưới đây là một số mẫu mà tất cả công việc và sẽ được phân tích để Giáng sinh 2017:

DateTime christmas = DateTime.Parse("ad25ad12ad2017ad"); 
christmas = DateTime.Parse("AD25ad12ad2017"); 
christmas = DateTime.Parse("25ad12ad2017AD"); 
christmas = DateTime.Parse("25ad12ad2017"); 
christmas = DateTime.Parse("A.D.25ad12ad2017"); 
christmas = DateTime.Parse("A.D.25ad12ad"); // current year is used 
christmas = DateTime.Parse("A.D.25ad12"); // current year is used 
+0

Khi liên kết đó chỉ ra, thời đại hiện tại được gọi là 'AD' * hoặc *' CE' nhưng chúng ta không thể sử dụng 'CE' làm" dấu tách ". –

+0

Theo nguồn tham khảo, câu trả lời của bạn là chính xác. Tôi chỉ tự hỏi tại sao một sự lựa chọn lộn xộn như vậy. Ý tôi là, chấp nhận thời đại * sau * ngày sẽ có ý nghĩa, nhưng chấp nhận nó ở bất cứ nơi nào ... sẽ không gây nhầm lẫn? –

+2

@Damien_The_Unbeliever: chỉ những gì 'GetEraName' hoặc' GetAbbreviatedEraName' trả lại có thể được sử dụng là 'A.D.' /' AD'. –

9

Bạn có thể xác nhận rằng đây là thời kỳ và không phải một số UTF mã hóa kí tự bằng cách thay đổi văn hóa viết tắt tên kỷ nguyên (tên kỷ nguyên được lưu trữ trong DateTimeFormatInfo.m_abbrevEraNamesDateTimeFormatInfo.m_abbrevEnglishEraNames lĩnh vực tư nhân, và cho văn hóa bất biến tên kỷ nguyên được viết tắt là mảng chuỗi chỉ với một giá trị - "AD"). Trường có thể được sử dụng thay vì "AD".

var cul = (CultureInfo) CultureInfo.InvariantCulture.Clone();       
// set DateTimeFormatInfo.AbbreviatedEraNames to "BLA" 
typeof(DateTimeFormatInfo).GetField("m_abbrevEraNames", BindingFlags.Instance | BindingFlags.NonPublic) 
    .SetValue(cul.DateTimeFormat, new string[] {"BLA"}); 
// set DateTimeFormatInfo.AbbreviatedEnglishEraNames to "BLA" 
typeof(DateTimeFormatInfo).GetField("m_abbrevEnglishEraNames", BindingFlags.Instance | BindingFlags.NonPublic) 
    .SetValue(cul.DateTimeFormat, new string[] { "BLA" }); 

var date = DateTime.Parse("AD03AD08", cul); // now it fails 
var date = DateTime.Parse("A.D.03A.D.08", cul); // still works because we 
// did not modify non-abbreviated era name 
var date = DateTime.Parse("BLA03BLA08", cul); // this one works 

Bây giờ tại sao nó đối xử với tên kỷ nguyên như thế không phải là khá rõ ràng ... Có lẽ sau khi gặp gỡ đặt trước đó nó đặt kỷ nguyên ngày và tiếp tục phân tích, vì vậy nó đóng vai trò như tách trong một cảm giác nó chỉ chuyển sang phân tích dấu hiệu tiếp theo sau cái này Tài liệu cho DateTime.Parse tuyên bố rằng:

Phương pháp này cố phân tích chuỗi hoàn toàn và tránh ném Định dạng ngoại lệ. Nó bỏ qua dữ liệu không được công nhận nếu có thể và điền vào thiếu tháng, ngày, và thông tin năm với ngày hiện tại

Trong khi điều này không đề cập đến bất cứ điều gì về thời đại - hành vi như vậy gắn với "tránh ném FormatException bất cứ khi nào có thể" thiết kế.

Các vấn đề liên quan