IFormatProvider ทำอะไร?


95

ฉันกำลังเล่นกับเมธอด Datetime.ParseExact และมันต้องการ IFormatProvider ...

มันใช้งานได้ในการป้อนค่า null แต่มันทำอะไรกันแน่?


3
อาจซ้ำกันได้ของทำไม DateTime.ParseExact (String, String, IFormatProvider) ต้องใช้ IFormatProvider . ฉันกำลังโหวตให้ปิดด้วยอันใหม่กว่าเพราะมันถูกกว่าและมีคำตอบที่ดีกว่า
nawfal

คำตอบ:


62

ในการยอมรับคำตอบของ Ian Boyd:

นอกจากนี้ยังCultureInfoดำเนินการติดต่อนี้และสามารถนำมาใช้ในกรณีของคุณ คุณจึงสามารถแยกวิเคราะห์สตริงวันที่ภาษาฝรั่งเศสได้เช่น คุณสามารถใช้

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

2
ดูเหมือนจะไม่มีโอเวอร์โหลดที่ตรงกับตัวอย่างของคุณอีกต่อไปใน. NET Framework 4.6 คุณต้องใช้DateTime.ParseExact(string, string, IFormatProvider)แทนฉันเชื่อว่า - เช่น: DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
เจมส์คิง

1
ใน. NET Framework 4.6.2 ไม่มีพารามิเตอร์อินพุตตามที่คุณชี้ ฉันใช้เพียงสองข้อและใช้ได้ดีDateTime dt = DateTime.Parse(yourDateInputString, ci);โปรดแก้ไขคำตอบของคุณ
DmitryBoyko

1
ขออภัยมีการอัปเดตคำตอบที่ค้างชำระเป็นเวลานาน
Andrei Rînea

49

โดยIFormatProviderปกติอินเทอร์เฟซจะถูกใช้งานสำหรับคุณโดยCultureInfoคลาสเช่น:

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

อินเทอร์เฟซเป็นเกตเวย์สำหรับฟังก์ชันเพื่อรับชุดข้อมูลเฉพาะวัฒนธรรมจากวัฒนธรรม วัตถุทางวัฒนธรรมที่มีอยู่ทั่วไปสองรายการที่IFormatProviderสามารถสอบถามได้คือ:

วิธีการทำงานตามปกติคือคุณขอIFormatProviderให้คุณมอบDateTimeFormatInfoวัตถุ:

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

นอกจากนี้ยังมีความรู้ภายในว่าIFormatProviderอินเทอร์เฟซใด ๆน่าจะถูกนำไปใช้โดยคลาสที่สืบเชื้อสายมาจากCultureInfoหรือสืบเชื้อสายมาDateTimeFormatInfoดังนั้นคุณสามารถส่งอินเทอร์เฟซได้โดยตรง:

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

แต่อย่าทำอย่างนั้น

งานหนักทั้งหมดนั้นได้เขียนไว้สำหรับคุณแล้ว:

ในการรับDateTimeFormatInfoจากIFormatProvider :

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

ในการรับNumberFormatInfoจากIFormatProvider :

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

คุณค่าIFormatProviderคือคุณสร้างวัตถุทางวัฒนธรรมของคุณเอง ตราบเท่าที่พวกเขานำไปใช้IFormatProviderและส่งคืนวัตถุที่พวกเขาขอคุณสามารถข้ามวัฒนธรรมที่มีอยู่แล้วได้

คุณยังสามารถใช้IFormatProviderเพื่อส่งผ่านวัตถุทางวัฒนธรรมโดยพลการ - ผ่านไฟล์IFormatProvider. เช่นชื่อของเทพเจ้าในวัฒนธรรมที่แตกต่างกัน

  • พระเจ้า
  • พระเจ้า
  • เยโฮวา
  • ยาห์เว
  • יהוה
  • אהיהאשראהיה

สิ่งนี้ช่วยให้LordsNameFormatInfoชั้นเรียนที่กำหนดเองของคุณขับไปใน an IFormatProviderและคุณสามารถรักษาสำนวน

ในความเป็นจริงคุณไม่จำเป็นต้องเรียกGetFormatวิธีการของIFormatProviderตัวเอง

เมื่อใดก็ตามที่คุณต้องการIFormatProviderคุณสามารถส่งผ่านCultureInfoวัตถุ:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

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

หมายเหตุ : รหัสใด ๆ ถูกเผยแพร่สู่สาธารณสมบัติ ไม่จำเป็นต้องแสดงที่มา


18

การส่งค่า null เนื่องจากIFormatProviderไม่ใช่วิธีที่ถูกต้องในการทำเช่นนี้ หากผู้ใช้มีรูปแบบวันที่ / เวลาที่กำหนดเองบนพีซีคุณจะมีปัญหาในการแยกวิเคราะห์และแปลงเป็นสตริง ฉันเพิ่งแก้ไขข้อผิดพลาดที่มีคนส่งค่า null เป็น IFormatProvider เมื่อแปลงเป็นสตริง

แต่คุณควรใช้ CultureInfo.InvariantCulture

ไม่ถูกต้อง:

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

แก้ไข:

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

2
มีเหตุผลอะไรที่เราควรใช้CultureInfo.InvariantCultureแทนCultureInfo.CurrentCulture?
Stephen Booher

5
InvariantCulture เป็นวัฒนธรรมพิเศษที่รับประกันว่าจะมีอยู่ในเครื่องใด ๆ เสมอและจะแปลงและแยกวิเคราะห์กลับเป็นค่าเดิมเสมอ CurrentCulture คือวัฒนธรรมของเธรดปัจจุบัน สิ่งนี้อาจแตกต่างกันไปและหากคุณไม่ใช้วัฒนธรรมเดียวกันในการแปลงเป็นสตริงและแยกวิเคราะห์คุณจะได้รับข้อผิดพลาดของรูปแบบ ...
Tim

5
@StephenBooher ที่ส่งผ่านnullจะเริ่มต้นเป็นCultureInfo.CurrentCulture. ดูการโทรในแหล่งอ้างอิงหากคุณติดตามสายการโทรไปพร้อมกันในที่สุด null จะถูกแทนที่ด้วยDateTimeFormatInfo.CurrentInfoซึ่งเทียบเท่ากับCultureInfo.CurrentCultureเอาต์พุตใด
Scott Chamberlain

InvariantCulture คือสิ่งที่ฉันกำลังมองหา ขอบคุณ
Chicowitz

5

IFormatProviderให้ข้อมูลวัฒนธรรมแก่วิธีการที่เป็นปัญหา DateTimeFormatInfoใช้ IFormatProvider และอนุญาตให้คุณระบุรูปแบบที่คุณต้องการให้แสดงวันที่ / เวลาตัวอย่างสามารถพบได้ในเพจ MSDN ที่เกี่ยวข้อง




2

โดยMSDN

.NET Framework รวมการใช้งาน IFormatProvider ที่กำหนดไว้ล่วงหน้าสามแบบต่อไปนี้เพื่อให้ข้อมูลเฉพาะวัฒนธรรมที่ใช้ในการจัดรูปแบบหรือแยกวิเคราะห์ค่าตัวเลขและวันที่และเวลา:

  1. NumberFormatInfoระดับซึ่งให้ข้อมูลที่ใช้ในการตัวเลขรูปแบบต่างๆเช่นสกุลเงินที่คั่นหลักพันและสัญลักษณ์คั่นทศนิยมวัฒนธรรมโดยเฉพาะอย่างยิ่ง สำหรับข้อมูลเกี่ยวกับสตริงรูปแบบที่กำหนดไว้ล่วงหน้าที่NumberFormatInfoอ็อบเจ็กต์รู้จักและใช้ในการดำเนินการจัดรูปแบบตัวเลขโปรดดูสตริงรูปแบบตัวเลขมาตรฐานและสตริงรูปแบบตัวเลขที่กำหนดเอง
  2. DateTimeFormatInfoระดับซึ่งให้ข้อมูลที่ใช้ในการจัดรูปแบบวันที่และเวลาเช่นวันและเวลาที่คั่นสัญลักษณ์สำหรับวัฒนธรรมโดยเฉพาะหรือการสั่งซื้อและรูปแบบของวันปีเดือนวันและส่วนประกอบ สำหรับข้อมูลเกี่ยวกับสตริงรูปแบบที่กำหนดไว้ล่วงหน้าที่DateTimeFormatInfoอ็อบเจ็กต์รู้จักและใช้ในการดำเนินการจัดรูปแบบตัวเลขโปรดดูสตริงรูปแบบวันที่และเวลามาตรฐานและสตริงรูปแบบวันที่และเวลาที่กำหนดเอง
  3. CultureInfoระดับซึ่งหมายถึงวัฒนธรรมโดยเฉพาะอย่างยิ่ง ใช้GetFormatวิธีการส่งกลับวัฒนธรรมที่เฉพาะเจาะจงNumberFormatInfoหรือDateTimeFormatInfoวัตถุขึ้นอยู่กับว่าCultureInfoวัตถุที่ถูกนำมาใช้ในการดำเนินการจัดรูปแบบหรือการแยกวิเคราะห์ที่เกี่ยวข้องกับตัวเลขหรือวันที่และเวลา

.NET Framework ยังสนับสนุนการจัดรูปแบบแบบกำหนดเอง โดยทั่วไปจะเกี่ยวข้องกับการสร้างคลาสการจัดรูปแบบที่ใช้ทั้ง IFormatProvider และ ICustomFormatter String.Format(IFormatProvider, String, Object[])อินสแตนซ์ของคลาสนี้ถูกส่งผ่านไปแล้วเป็นพารามิเตอร์กับวิธีการที่มีประสิทธิภาพการดำเนินงานการจัดรูปแบบที่กำหนดเองเช่น


1

DateTimeFormatInfoการดำเนินการระดับอินเตอร์เฟซนี้เพื่อที่จะช่วยให้คุณควบคุมการจัดรูปแบบของสตริง DateTime ของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.