Apa yang dilakukan IFormatProvider?


93

Saya bermain-main dengan metode Datetime.ParseExact, dan ia menginginkan IFormatProvider ...

Ia bekerja memasukkan null, tetapi apa sebenarnya fungsinya?


3
kemungkinan duplikat dari Why DateTime.ParseExact (String, String, IFormatProvider) membutuhkan IFormatProvider? . Saya memilih untuk menutup dengan yang lebih baru karena kata-katanya lebih baik, dan memiliki jawaban yang lebih baik.
nawfal

Jawaban:


61

Selain jawaban Ian Boyd:

Juga CultureInfomengimplementasikan antarmuka ini dan dapat digunakan dalam kasus Anda. Jadi Anda bisa mengurai string tanggal Prancis misalnya; Anda bisa menggunakan

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

2
Sepertinya tidak ada kelebihan beban yang cocok dengan contoh Anda lagi di .NET Framework 4.6. Anda harus menggunakan DateTime.ParseExact(string, string, IFormatProvider)sebagai gantinya, saya percaya - seperti itu: DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
James King

1
Di .NETFramework 4.6.2 tidak ada parameter masukan seperti yang Anda tunjuk. Saya hanya menggunakan dua dan berfungsi dengan baik. DateTime dt = DateTime.Parse(yourDateInputString, ci);Harap perbaiki jawaban Anda.
Pengembang

1
Maaf teman-teman, pembaruan lama tertunda telah dibuat untuk jawaban saya.
Andrei Rînea

49

The IFormatProviderantarmuka biasanya dilaksanakan untuk Anda oleh CultureInfokelas, misalnya:

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

Antarmuka adalah gerbang bagi suatu fungsi untuk mendapatkan sekumpulan data khusus budaya dari suatu budaya. Dua objek budaya yang umum tersedia yang IFormatProviderdapat ditanyakan adalah:

Cara biasanya bekerja adalah Anda meminta IFormatProvideruntuk memberi Anda sebuah DateTimeFormatInfoobjek:

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

Ada juga pengetahuan orang dalam bahwa setiap IFormatProviderantarmuka kemungkinan diimplementasikan oleh kelas yang diturunkan dari CultureInfo, atau diturunkan dari DateTimeFormatInfo, sehingga Anda dapat mentransmisikan antarmuka secara langsung:

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);

Tapi jangan lakukan itu

Semua kerja keras itu telah dituliskan untuk Anda:

Untuk mendapatkan DateTimeFormatInfodariIFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

Untuk mendapatkan NumberFormatInfodariIFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

Nilai dari itu IFormatProvideradalah Anda menciptakan objek budaya Anda sendiri. Selama mereka menerapkan IFormatProvider, dan mengembalikan objek yang diminta, Anda dapat melewati budaya bawaan.

Anda juga dapat menggunakan IFormatProvideruntuk cara melewati objek budaya sewenang-wenang - melalui IFormatProvider. Misalnya nama dewa dalam budaya yang berbeda

  • Tuhan
  • Tuhan
  • Jehova
  • Yahwe
  • יהוה
  • אהיה אשר אהיה

Ini memungkinkan LordsNameFormatInfokelas kustom Anda ikut serta di dalam IFormatProvider, dan Anda dapat mempertahankan idiom tersebut.

Pada kenyataannya Anda tidak perlu menyebut GetFormatmetode IFormatProviderdiri Anda sendiri.

Kapan pun Anda membutuhkannya, IFormatProviderAnda dapat memberikan CultureInfoobjek:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

Catatan : Kode apa pun dilepaskan ke domain publik. Tidak diperlukan atribusi.


18

Meneruskan nol sebagai IFormatProviderbukan cara yang benar untuk melakukan ini. Jika pengguna memiliki format tanggal / waktu khusus di PC mereka, Anda akan mengalami masalah dalam penguraian dan konversi ke string. Saya baru saja memperbaiki bug di mana seseorang telah mengirimkan null sebagai IFormatProvider saat mengonversi ke string.

Sebaliknya Anda harus menggunakan CultureInfo.InvariantCulture

Salah:

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

Benar:

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

2
Apakah ada alasan kita harus menggunakan CultureInfo.InvariantCulturebukan CultureInfo.CurrentCulture?
Stephen Booher

5
InvariantCulture adalah budaya khusus yang dijamin akan selalu ada di setiap mesin dan akan selalu mengubah dan mengurai kembali ke nilai yang sama. CurrentCulture adalah budaya thread saat ini. Ini dapat bervariasi dan jika Anda tidak menggunakan budaya yang sama untuk mengonversi ke string dan parse, Anda akan mendapatkan kesalahan format ...
Tim

5
@StephenBooher yang meneruskan nullakan default ke CultureInfo.CurrentCulture. Lihat panggilan di sumber referensi , jika Anda mengikuti rangkaian panggilan, null akhirnya diganti dengan DateTimeFormatInfo.CurrentInfoyang setara dengan CultureInfo.CurrentCulturekeluaran apa .
Scott Chamberlain

InvariantCulture adalah apa yang saya cari. Terima kasih
Chicowitz

5

IFormatProvider memberikan info budaya ke metode yang dimaksud. DateTimeFormatInfo mengimplementasikan IFormatProvider, dan memungkinkan Anda untuk menentukan format yang Anda inginkan untuk menampilkan tanggal / waktu Anda. Contohnya dapat ditemukan pada halaman MSDN yang relevan.




2

Oleh MSDN

.NET Framework mencakup tiga implementasi IFormatProvider yang telah ditentukan sebelumnya untuk menyediakan informasi khusus budaya yang digunakan dalam pemformatan atau penguraian nilai numerik dan tanggal dan waktu:

  1. The NumberFormatInfokelas, yang menyediakan informasi yang digunakan untuk nomor Format, seperti mata uang, pemisah ribuan, dan simbol pemisah desimal untuk budaya tertentu. Untuk informasi tentang string format standar yang dikenali oleh NumberFormatInfoobjek dan digunakan dalam operasi pemformatan numerik, lihat String Format Numerik Standar dan String Format Numerik Kustom.
  2. The DateTimeFormatInfokelas, yang menyediakan informasi yang digunakan untuk tanggal Format dan waktu, seperti tanggal dan waktu simbol pemisah untuk budaya tertentu atau urutan dan format komponen tahun, bulan, hari tanggal ini. Untuk informasi tentang string format yang sudah ditentukan sebelumnya yang dikenali oleh DateTimeFormatInfoobjek dan digunakan dalam operasi pemformatan numerik, lihat String Format Tanggal dan Waktu Standar dan String Format Tanggal dan Waktu Kustom.
  3. The CultureInfokelas, yang mewakili budaya tertentu. Its GetFormatmetode mengembalikan budaya khusus NumberFormatInfoatau DateTimeFormatInfoobjek, tergantung pada apakah CultureInfoobjek yang digunakan dalam operasi format atau parsing yang melibatkan angka atau tanggal dan waktu.

.NET Framework juga mendukung pemformatan kustom. Ini biasanya melibatkan pembuatan kelas pemformatan yang mengimplementasikan IFormatProvider dan ICustomFormatter. Sebuah instance dari kelas ini kemudian diteruskan sebagai parameter ke metode yang melakukan operasi pemformatan khusus, seperti String.Format(IFormatProvider, String, Object[]).


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.