2009-02-03 17 views
65

Tôi đang chơi với phương thức Datetime.ParseExact và muốn một IFormatProvider ...IFormatProvider làm gì?

Nó hoạt động nhập null, nhưng chính xác thì nó làm gì?

+3

bản sao có thể có của [Tại sao DateTime.ParseExact (String, String, IFormatProvider) cần IFormatProvider?] (Http://stackoverflow.com/questions/18961520/why-datetime-parseexactstring-string-iformatprovider-need-the- iformatprovide). Tôi đang bỏ phiếu để đóng với một cái mới hơn bởi vì nó được diễn đạt tốt hơn, và có câu trả lời tốt hơn. – nawfal

Trả lời

41

Ngoài ra CultureInfo triển khai giao diện này và có thể được sử dụng trong trường hợp của bạn. Vì vậy, bạn có thể phân tích cú pháp chuỗi ngày của Pháp chẳng hạn; bạn có thể sử dụng

var ci = new CultureInfo("fr-FR"); 
DateTime dt = DateTime.Parse(yourDateInputString, yourFormatString, ci); 
+2

Có vẻ như không quá tải phù hợp với ví dụ của bạn nữa trong Khuôn khổ .NET 4.6. Bạn phải sử dụng 'DateTime.ParseExact (chuỗi, chuỗi, IFormatProvider)' thay vào đó, tôi tin - như vậy: 'DateTime.ParseExact (" 20160409 111559 "," yyyyMMdd HHmmss ", CultureInfo.CurrentCulture)' –

+0

Tôi sẽ cập nhật câu trả lời :) –

1

Lớp DateTimeFormatInfo triển khai giao diện này, vì vậy nó cho phép bạn kiểm soát định dạng chuỗi DateTime của mình.

5

IFormatProvider cung cấp thông tin văn hóa cho phương thức được đề cập. DateTimeFormatInfo triển khai IFormatProvider và cho phép bạn chỉ định định dạng bạn muốn ngày/giờ được hiển thị. Ví dụ có thể tìm thấy trên các trang MSDN có liên quan.

14

Truyền null là IFormatProvider không đúng cách để thực hiện việc này. Nếu người dùng có định dạng ngày/giờ tùy chỉnh trên PC của họ, bạn sẽ gặp sự cố khi phân tích cú pháp và chuyển đổi thành chuỗi. Tôi vừa sửa một lỗi mà ai đó đã vượt qua null như IFormatProvider khi chuyển đổi thành chuỗi.

Thay vào đó bạn nên sử dụng CultureInfo.InvariantCulture

sai:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", null); 

Đúng:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", CultureInfo.InvariantCulture); 
+2

Có lý do nào chúng ta nên sử dụng 'CultureInfo.InvariantCulture' thay vì' CultureInfo.CurrentCulture'? –

+4

InvariantCulture là một nền văn hóa đặc biệt được đảm bảo luôn tồn tại trên bất kỳ máy nào và sẽ luôn chuyển đổi và phân tích cú pháp ngược lại thành các giá trị giống nhau. CurrentCulture là văn hóa của chuỗi hiện tại. Điều này có thể khác nhau và nếu bạn không sử dụng cùng một nền văn hóa để chuyển đổi thành chuỗi và phân tích cú pháp, bạn sẽ nhận được lỗi định dạng ... – Tim

+5

@StephenBooher truyền vào 'null' sẽ mặc định thành' CultureInfo.CurrentCulture'. Xem cuộc gọi trong [nguồn tham khảo] (http://referencesource.microsoft.com/mscorlib/a.html#bfc8add12515d311), nếu bạn làm theo chuỗi các cuộc gọi cùng, null cuối cùng được thay thế bằng ['DateTimeFormatInfo.CurrentInfo' ] (http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.currentinfo (v = vs.110) .aspx) tương đương với kết quả đầu ra 'CultureInfo.CurrentCulture'. –

29

Giao diện IFormatProvider thường được thực hiện cho bạn bằng một lớp CultureInfo, ví dụ:

  • CultureInfo.CurrentCulture
  • CultureInfo.CurrentUICulture
  • CultureInfo.InvariantCulture
  • CultureInfo.CreateSpecificCulture("de-CA") //German (Canada)

Giao diện là một cửa ngõ cho một chức năng để có được một tập hợp các dữ liệu văn hóa cụ thể từ một nền văn hóa.Hai nền văn hóa thường có sẵn các đối tượng rằng một IFormatProvider có thể được truy vấn cho là:

  • DateTimeFormatInfo
  • NumberFormatInfo

Cách nó sẽ làm việc bình thường được bạn hỏi IFormatProvider để cung cấp cho bạn một đối tượng DateTimeFormatInfo:

DateTimeFormatInfo format; 
format = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo)); 
if (format != null) 
    DoStuffWithDatesOrTimes(format); 

Cũng có kiến ​​thức bên trong rằng bất kỳ 012 giao diệncó khả năng được thực hiện bởi một lớp xuống từ CultureInfo, hoặc xuống từ DateTimeFormatInfo, vì vậy bạn có thể cast giao diện trực tiếp:

CultureInfo info = provider as CultureInfo; 
if (info != null) 
    format = info.DateTimeInfo; 
else 
{ 
    DateTimeFormatInfo dtfi = provider as DateTimeFormatInfo; 
    if (dtfi != null) 
     format = dtfi; 
    else 
     format = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo)); 
} 

if (format != null) 
    DoStuffWithDatesOrTimes(format); 

Nhưng đừng làm điều đó

Tất cả những gì công việc khó khăn có đã được viết dành cho bạn:

để có được một DateTimeFormatInfo từ một IFormatProvider:

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider); 

Để có được một NumberFormatInfo từ một IFormatProvider:

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider); 

Giá trị của IFormatProvider là bạn tạo các đối tượng văn hóa của riêng bạn. Miễn là chúng triển khai IFormatProvider và trả về các đối tượng mà chúng được yêu cầu, bạn có thể bỏ qua các nền văn hóa được tích hợp sẵn.

Bạn cũng có thể sử dụng IFormatProvider để biết cách truyền các đối tượng văn hóa tùy ý - thông qua IFormatProvider. Ví dụ. tên của vị thần trong các nền văn hóa khác nhau

  • thần
  • Thiên Chúa
  • Jehova
  • Yahwe
  • יהוה
  • אהיה אשר אהיה

này cho phép tùy chỉnh LordsNameFormatInfo lớp đi xe của bạn cùng bên trong một số IFormatProvider và bạn có thể giữ lại anh thành ngữ.

Trong thực tế, bạn sẽ không bao giờ phải gọi phương thức GetFormat của chính mình là IFormatProvider.

Bất cứ khi nào bạn cần một IFormatProvider bạn có thể vượt qua một đối tượng CultureInfo:

DateTime.Now.ToString(CultureInfo.CurrentCulture); 

endTime.ToString(CultureInfo.InvariantCulture); 

transactionID.toString(CultureInfo.CreateSpecificCulture("qps-ploc")); 

Note: Bất kỳ mã được phát hành vào phạm vi công cộng. Không yêu cầu ghi nhận tác giả.

2

By MSDN

.NET Framework bao gồm các ba triển khai IFormatProvider được xác định trước sau để cung cấp thông tin văn hóa cụ thể được sử dụng trong định dạng hoặc phân tích số và ngày tháng và thời gian giá trị:

  1. Lớp NumberFormatInfo, cung cấp thông tin được sử dụng để định dạng các số, chẳng hạn như đơn vị tiền tệ, dấu tách hàng nghìn và ký hiệu dấu tách thập phân cho một nền văn hóa cụ thể. Để biết thông tin về các chuỗi định dạng được xác định trước được một đối tượng NumberFormatInfo nhận dạng và được sử dụng trong các hoạt động định dạng số, hãy xem Chuỗi Định dạng Số Tiêu chuẩn và Chuỗi Định dạng Số Tùy chỉnh.
  2. Lớp DateTimeFormatInfo, cung cấp thông tin được sử dụng để định dạng ngày và giờ, chẳng hạn như biểu tượng dấu ngày và giờ cho văn hóa cụ thể hoặc thứ tự và định dạng của các thành phần của năm, tháng và ngày của ngày. Để biết thông tin về chuỗi định dạng được xác định trước được nhận dạng bởi đối tượng DateTimeFormatInfo và được sử dụng trong hoạt động định dạng số, hãy xem Chuỗi định dạng ngày và giờ chuẩn và Chuỗi định dạng ngày và giờ.
  3. Lớp CultureInfo, đại diện cho một nền văn hóa cụ thể. Phương thức GetFormat trả về đối tượng NumberFormatInfo hoặc DateTimeFormatInfo cụ thể theo văn hóa, tùy thuộc vào đối tượng CultureInfo được sử dụng trong hoạt động định dạng hoặc phân tích cú pháp có liên quan đến số hoặc ngày và giờ hay không.

.NET Framework cũng hỗ trợ định dạng tùy chỉnh. Điều này thường liên quan đến việc tạo ra một lớp định dạng thực hiện cả IFormatProvider và ICustomFormatter. Một thể hiện của lớp này sau đó được chuyển thành một tham số cho một phương thức thực hiện một hoạt động định dạng tùy chỉnh, chẳng hạn như String.Format(IFormatProvider, String, Object[]).