IFormatProvider làm gì?


93

Tôi đã thử với phương thức Datetime.ParseExact và nó muốn một IFormatProvider ...

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


3
bản sao có thể xảy ra của Tại sao DateTime.ParseExact (String, String, IFormatProvider) cần IFormatProvider? . Tôi đang bỏ phiếu để kết thúc bằng một cái mới hơn vì nó được truyền tải tốt hơn và có câu trả lời tốt hơn.
nawfal

Câu trả lời:


61

Để bổ sung cho câu trả lời của Ian Boyd:

Cũng CultureInfothực hiện 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 một chuỗi ngày tiếng Pháp chẳng hạn; bạn đã có thể sử dụng

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

2
Dường như không còn tình trạng quá tải khớp với ví dụ của bạn nữa trong .NET Framework 4.6. Bạn phải sử dụng DateTime.ParseExact(string, string, IFormatProvider)thay vào đó, tôi tin rằng - như vậy: DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
James King

1
Trong .NET Framework 4.6.2 không có tham số đầu vào như bạn trỏ. Tôi chỉ sử dụng hai và nó hoạt động tốt. DateTime dt = DateTime.Parse(yourDateInputString, ci);Vui lòng sửa lại câu trả lời của bạn.
Nhà phát triển

1
Xin lỗi các bạn, một bản cập nhật quá hạn lâu đã được thực hiện cho câu trả lời của tôi.
Andrei Rînea

49

Các IFormatProvidergiao diện thường được thực hiện cho bạn bằng một CultureInfolớp, ví dụ như:

  • 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 để lấy một bộ dữ liệu dành riêng cho từng nền văn hóa từ một nền văn hóa. Hai đối tượng nuôi cấy phổ biến có sẵn mà một IFormatProvidercó thể được truy vấn là:

Cách nó hoạt động bình thường là bạn yêu cầu IFormatProvidercung cấp cho bạn một DateTimeFormatInfođối tượng:

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

Ngoài ra còn có kiến ​​thức bên trong rằng bất kỳ IFormatProvidergiao diện nào cũng có khả năng được thực hiện bởi một lớp giảm dần CultureInfohoặc giảm dần DateTimeFormatInfo, vì vậy bạn có thể truyền trực tiếp giao diện:

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 vậy

Tất cả công việc khó khăn đó đã được viết cho bạn:

Để nhận được DateTimeFormatInfotừ mộtIFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

Để nhận được NumberFormatInfotừ mộtIFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

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

Bạn cũng có thể sử dụng IFormatProvidercho mộ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 thần trong các nền văn hóa khác nhau

  • Chúa Trời
  • Chúa Trời
  • Jehova
  • Yahwe
  • יהוה
  • אהיה אשר אהיה

Điều này cho phép LordsNameFormatInfolớp học tùy chỉnh của bạn đi cùng bên trongIFormatProvider và bạn có thể bảo tồn thành ngữ.

Trong thực tế, bạn sẽ không bao giờ cần gọi GetFormatphương thức củaIFormatProvider chính mình.

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

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

Lưu ý : Bất kỳ mã nào được phát hành vào miền công cộng. Không cần ghi công.


18

Truyền null IFormatProviderkhông phải là cách chính xác để 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 vấn đề 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 trong đó ai đó đã chuyển null làm IFormatProvider khi chuyển đổi thành chuỗi.

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

Sai lầm:

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

Chính xác:

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

2
Có lý do gì chúng ta nên sử dụng CultureInfo.InvariantCulturethay vì CultureInfo.CurrentCulture?
Stephen Booher

5
InvariantCulture là một 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 trở lại cùng các giá trị. CurrentCulture là văn hóa của luồng hiện tại. Điều này có thể khác nhau và nếu bạn không sử dụng các nền văn hóa tương tự để chuyển sang chuỗi và phân tích cú pháp, bạn sẽ nhận được lỗi định dạng ...
Tim

5
@StephenBooher chuyển vào nullsẽ mặc định thành CultureInfo.CurrentCulture. Xem lệnh gọi trong nguồn tham chiếu , nếu bạn tuân theo chuỗi lệnh gọi, giá trị rỗng cuối cùng sẽ được thay thế bằng giá trị DateTimeFormatInfo.CurrentInfotương đương với CultureInfo.CurrentCulturekết quả đầu ra.
Scott Chamberlain

InvariantCulture là những gì tôi đang tìm kiếm. Cảm ơn
Chicowitz

5

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




2

Bởi MSDN

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

  1. Các NumberFormatInfolớp, cung cấp thông tin được sử dụng để định dạng số, chẳng hạn như tiền tệ, hàng ngàn phân cách, và các ký hiệu thập phân tách cho một nền văn hóa cụ thể. Để biết thông tin về các chuỗi định dạng xác định trước được một NumberFormatInfođối tượng nhận dạng và sử dụng trong các thao tác định dạng số, hãy xem Chuỗi định dạng số chuẩn và Chuỗi định dạng số tùy chỉnh.
  2. Các DateTimeFormatInfolớp, cung cấp thông tin được sử dụng để định dạng ngày tháng và thời gian, ví dụ như ngày tháng và thời gian ký tự phân cách cho một nền văn hóa cụ thể hoặc trình tự, định dạng của các thành phần năm, tháng và ngày một ngày. Để biết thông tin về các chuỗi định dạng được xác định trước được công nhận bởiDateTimeFormatInfo đối tượng và sử dụng trong các thao tác đị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ờ tùy chỉnh.
  3. Các CultureInfolớp, đại diện cho một nền văn hóa cụ thể. GetFormatPhương thức của nó trả về một đối tượng NumberFormatInfohoặc một nền văn hóa cụ thể DateTimeFormatInfo, tùy thuộc vào việc CultureInfođối tượng đó được sử dụng trong thao tác định dạng hoặc phân tích cú pháp liên quan đến số hoặc ngày và giờ.

.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 triển khai cả IFormatProvider và ICustomFormatter. Một thể hiện của lớp này sau đó được chuyển dưới dạng tham số cho một phương thức thực hiện thao tác định dạng tùy chỉnh, chẳng hạn như String.Format(IFormatProvider, String, Object[]).


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.