CultureInfo.InvariantCulture หมายถึงอะไร


178

ฉันมีข้อความเป็นดังนี้:

var foo = "FooBar";

ฉันต้องการประกาศสตริงที่สองที่เรียกว่าbarและทำให้นี่เท่ากับอักขระที่หนึ่งและที่สี่ของแรกของฉันfooดังนั้นฉันจึงทำเช่นนี้:

var bar = foo[0].ToString() + foo[3].ToString();

มันใช้งานได้ตามที่คาดไว้ แต่ReSharperแนะนำให้ฉันใส่Culture.InvariantCultureในวงเล็บดังนั้นบรรทัดนี้จะเป็นดังนี้:

var bar = foo[0].ToString(CultureInfo.InvariantCulture)
        + foo[3].ToString(CultureInfo.InvariantCulture);

สิ่งนี้หมายความว่าอะไรและจะมีผลกับการทำงานของโปรแกรมของฉันหรือไม่


2
ดูคำถาม SO นี้: stackoverflow.com/questions/8492449/…
msigman

39
สำหรับผู้ที่มองหาคำตอบ 5 วินาที: CultureInfo.InvariantCulture หมายถึง "ฉันไม่สนใจฉันไม่ต้องการวัฒนธรรมที่เกี่ยวข้องในสถานที่แรกตอนนี้ให้ฉันใช้สิ่งที่เป็นใบ้"
แอนดรู

5
@Andrew คุณช่วยเขียนเอกสาร MS ทั้งหมดได้ไหม?
Yatrix

3
@Yatrix ใช่แน่นอน ฉันชอบที่จะ! ใครจ่าย
แอนดรู

คำตอบ:


155

ไม่ใช่ทุกวัฒนธรรมใช้รูปแบบเดียวกันสำหรับวันที่และค่าทศนิยม / สกุลเงิน

นี้จะมีความสำคัญสำหรับคุณเมื่อคุณมีการแปลงค่าที่ป้อนเข้า(อ่าน)ที่จะถูกเก็บเป็นสตริง DateTime, float, หรือdouble decimalมันจะสำคัญถ้าคุณพยายามจัดรูปแบบชนิดข้อมูลดังกล่าวเป็นสตริง(เขียน)สำหรับการแสดงผลหรือการจัดเก็บ

หากคุณรู้ว่าวัฒนธรรมเฉพาะที่วันที่และค่าทศนิยม / สกุลเงินของคุณจะอยู่ข้างหน้าคุณสามารถใช้CultureInfoคุณสมบัติเฉพาะนั้น(เช่นCultureInfo("en-GB")) ตัวอย่างเช่นหากคุณคาดหวังอินพุตของผู้ใช้

CultureInfo.InvariantCultureคุณสมบัติถูกใช้ถ้าคุณกำลังจัดรูปแบบหรือแยกสตริงที่ควรจะ parseable โดยชิ้นส่วนของซอฟต์แวร์อิสระของผู้ใช้ที่การตั้งค่าท้องถิ่น

ค่าเริ่มต้นคือCultureInfo.InstalledUICultureCultureInfo เริ่มต้นขึ้นอยู่กับการตั้งค่าของระบบปฏิบัติการ นี่คือเหตุผลที่คุณควรตรวจสอบให้แน่ใจว่าข้อมูลวัฒนธรรมนั้นตรงกับความต้องการของคุณ (ดูคำตอบของ Martinสำหรับแนวทางที่ดี)


3
"en-US" แต่ฉันคิดว่ามันอาจขึ้นอยู่กับการตั้งค่าระบบของคุณ
Tracker1

44
en-USค่าเริ่มต้นคือไม่ได้ มันเป็นวัฒนธรรมท้องถิ่น และInvariantCultureใช้เมื่อคุณต้องการการจัดรูปแบบที่เป็นกลางทางวัฒนธรรมซึ่งเป็นอิสระจากระบบท้องถิ่น ตัวอย่างเช่นเมื่อทำงานกับรูปแบบไฟล์ตามข้อความ
CodesInChaos

23
หากต้องการเพิ่ม @CodesInChaos ความคิดเห็น: การอ้างสิทธิ์ว่าค่าเริ่มต้นคือ CultureInfo ("en-US")นั้นผิด นอกจากนี้คำสั่งคุณสมบัติ CultureInfo.InvariantCulture จะใช้เมื่อคุณไม่แน่ใจล่วงหน้าว่ารูปแบบวัฒนธรรมใดที่จัดรูปแบบวันที่และค่าทศนิยม / สกุลเงินของคุณจะสับสน ด้วยการใช้กระแสในปัจจุบันค่าคงที่หรือวัฒนธรรมที่เฉพาะเจาะจงเป็นสิ่งที่ควรเป็นการตัดสินใจอย่างมีสติและหากคุณเข้าใจผิดคุณสามารถทำให้ผู้ใช้ของคุณ (ไม่ใช่คนอเมริกัน) เป็นคนแปลกแยก คุณไม่ควรใช้วัฒนธรรมที่ไม่เปลี่ยนแปลงหากคุณ "ไม่แน่ใจ" คุณต้องแน่ใจก่อนเวลา
Martin Liversage

3
-1 เนื่องจากปัญหาที่กล่าวถึงในความคิดเห็นอื่น คำตอบของ Martin นั้นมีประโยชน์มากกว่าเพราะจะบอกคุณว่าควรใช้เมื่อใดและไม่ใช้แต่ละวัฒนธรรม
Ed Greaves

"หากคุณทำงานเป็นภาษาอังกฤษแบบอเมริกันโดยเฉพาะคุณไม่ต้องกังวลเกี่ยวกับเรื่องนี้": ไม่ถูกต้องคุณอาจทำงานเป็นภาษาอังกฤษแบบอเมริกันโดยเฉพาะ แต่ซอฟต์แวร์อาจทำงานบน "en-GB" หรือ "de -DE "เซิร์ฟเวอร์จากนั้นจะสร้างความแตกต่างรวมถึงสามารถใช้วัฒนธรรมของลูกค้า (ถ้าคุณพูดอย่างนั้นในไฟล์ web.config) และนั่นอาจไม่ใช่" en-US "อย่างใดอย่างหนึ่ง ...
Stefan Steiger

152

เมื่อตัวเลขวันที่และเวลามีการจัดรูปแบบเป็นสตริงหรือแยกวิเคราะห์จากสตริงวัฒนธรรมจะใช้ในการกำหนดวิธีการทำ เช่นในen-USวัฒนธรรมที่โดดเด่นคุณมีการแทนค่าสตริงเหล่านี้:

  • 1,000,000.00 - หนึ่งล้านด้วยเศษสองหลัก
  • 1/29/2013 - วันที่โพสต์นี้

ในวัฒนธรรมของฉัน ( da-DK) ค่ามีการแสดงสตริงนี้:

  • 1.000.000,00 - หนึ่งล้านด้วยเศษสองหลัก
  • 29-01-2013 - วันที่โพสต์นี้

ในระบบปฏิบัติการ Windows ผู้ใช้ยังสามารถกำหนดวิธีการจัดรูปแบบตัวเลขและวันที่ / เวลาและอาจเลือกวัฒนธรรมอื่นนอกเหนือจากวัฒนธรรมของระบบปฏิบัติการของเขา การจัดรูปแบบที่ใช้เป็นตัวเลือกของผู้ใช้ซึ่งเป็นวิธีการที่ควรจะเป็น

ดังนั้นเมื่อคุณจัดรูปแบบคุ้มค่าที่จะแสดงให้กับผู้ใช้โดยใช้ตัวอย่างToStringหรือString.Formatหรือแยกวิเคราะห์จากสตริงโดยใช้DateTime.Parseหรือเริ่มต้นคือการใช้Decimal.Parse CultureInfo.CurrentCultureสิ่งนี้ทำให้ผู้ใช้สามารถควบคุมการจัดรูปแบบ

อย่างไรก็ตามการจัดรูปแบบสตริงจำนวนมากและการแยกวิเคราะห์จริง ๆ แล้วไม่ใช่การแลกเปลี่ยนสตริงระหว่างแอปพลิเคชันและผู้ใช้ แต่ระหว่างแอปพลิเคชันและรูปแบบข้อมูลบางอย่าง (เช่นไฟล์ XML หรือ CSV) ในกรณีนี้คุณไม่ต้องการใช้CultureInfo.CurrentCultureเพราะถ้าการจัดรูปแบบและการแยกวิเคราะห์เสร็จสิ้นด้วยวัฒนธรรมที่แตกต่างมันสามารถแตกได้ ในกรณีที่คุณต้องการใช้CultureInfo.InvariantCulture(ซึ่งเป็นไปตามen-USวัฒนธรรม) สิ่งนี้ทำให้มั่นใจว่าค่าสามารถไปกลับได้โดยไม่มีปัญหา

ด้วยเหตุผลที่ว่า ReSharper ช่วยให้คุณมีคำเตือนคือการที่บางคนเขียนแอพลิเคชันไม่รู้จักความแตกต่างนี้ซึ่งอาจนำไปสู่ผลลัพธ์ที่ไม่ได้ตั้งใจ แต่พวกเขาไม่เคยค้นพบนี้เพราะพวกเขาCultureInfo.CurrentCultureมีที่ซึ่งมีพฤติกรรมเช่นเดียวกับen-US CultureInfo.InvariantCultureอย่างไรก็ตามทันทีที่มีการใช้แอปพลิเคชันในวัฒนธรรมอื่นซึ่งมีโอกาสที่จะใช้หนึ่งวัฒนธรรมสำหรับการจัดรูปแบบและอื่น ๆ สำหรับการแยกวิเคราะห์แอปพลิเคชันอาจแตก

ดังนั้นเพื่อสรุป:

  • ใช้CultureInfo.CurrentCulture(ค่าเริ่มต้น) หากคุณกำลังจัดรูปแบบหรือแยกสตริงผู้ใช้
  • ใช้CultureInfo.InvariantCultureหากคุณกำลังจัดรูปแบบหรือแยกสตริงที่ควรแยกวิเคราะห์โดยซอฟต์แวร์
  • ใช้วัฒนธรรมของชาติที่เฉพาะเจาะจงเนื่องจากผู้ใช้ไม่สามารถควบคุมวิธีการจัดรูปแบบและการแยกวิเคราะห์

1
ในเรื่องที่เกี่ยวกับจุดสุดท้าย "ไม่ค่อยใช้วัฒนธรรมของชาติที่เฉพาะเจาะจง ... " การจัดรูปแบบสกุลเงินจะเป็นข้อยกเว้นหรือไม่? ตัวอย่างเช่นหากฉันมีDecimalตัวแปรที่มีค่าหนึ่งเป็นดอลลาร์สหรัฐฉันจะต้องการยกเว้นและใช้en-USเป็นวัฒนธรรมเมื่อแสดงเพื่อให้แน่ใจว่าฉันจะไม่ได้รับผลลัพธ์ที่ดูเหมือนจำนวนในยูโรหรือไม่ ฉันพยายาม CultureInfo.InvariantCultureแต่ได้สิ่งนี้เพื่อทำเครื่องหมายสกุลเงิน¤ดังนั้นฉันไม่แน่ใจว่าเป็นวิธีที่ถูกต้อง
Jeff B

1
@JeffBridgman: คำแนะนำของฉันเป็นเพียงคำแนะนำทั่วไปและอาจไม่ใช้กับกรณีเฉพาะของคุณ อย่างไรก็ตามฉันคิดว่าวิธีที่คุณแสดงจุดทศนิยม (เครื่องหมายจุลภาคหรือจุด) ควรเป็นสิ่งที่ผู้ใช้ควบคุม (เช่นใช้CultureInfo.CurrentCulture) หากคุณนอกเหนือไปจากการแสดงความจำเป็นจำนวนสกุลเงินแล้วบางทีคุณควรทำในลักษณะที่สอดคล้องกันคือไม่ได้ใช้และแทนที่จะใช้รหัสสกุลเงินสามตัวอักษรเช่นCultureInfo USD 1,234.56ถ้าอย่างนั้นคุณก็ไม่ต้องเจอปัญหาเรื่องการจับคู่สกุลเงินกับวัฒนธรรม
Martin Liversage

26

ตามที่ Microsoft:

คุณสมบัติ CultureInfo.InvariantCulture ไม่ใช่แบบเป็นกลางหรือแบบเจาะจง มันเป็นวัฒนธรรมประเภทที่สามที่ไม่ไวต่อวัฒนธรรม มันเกี่ยวข้องกับภาษาอังกฤษ แต่ไม่ใช่ในประเทศหรือภูมิภาค

(จากhttp://msdn.microsoft.com/en-us/library/4c5zdc6a(vs.71).aspx )

ดังนั้น InvariantCulture นั้นคล้ายคลึงกับวัฒนธรรม "en-US" แต่ไม่เหมือนกัน ถ้าคุณเขียน:

var d = DateTime.Now;
var s1 = d.ToString(CultureInfo.InvariantCulture);   // "05/21/2014 22:09:28"
var s2 = d.ToString(new CultureInfo("en-US"));       // "5/21/2014 10:09:28 PM"

ดังนั้น s1 และ s2 จะมีรูปแบบ similair แต่ InvariantCulture เพิ่มศูนย์นำหน้าและ "en-US" ใช้ AM หรือ PM

ดังนั้น InvariantCulture จะดีกว่าสำหรับการใช้งานภายในเมื่อคุณเช่นบันทึกวันที่ลงในไฟล์ข้อความหรือข้อมูลแยกวิเคราะห์ และ CultureInfo ที่ระบุจะดีกว่าเมื่อคุณแสดงข้อมูล (วันที่, สกุลเงิน ... ) ให้กับผู้ใช้ปลายทาง


3
ฉันรันโค้ดตัวอย่างของคุณเพื่อยืนยัน: InvariantCulture ใช้ American MM / dd / yyyy มากกว่าทำตามรูปแบบ ISO 8601 ปีไปครั้งแรก แม้จะมีไว้สำหรับการจัดเก็บแบบพกพาและการประมวลผลเชิงกลมากกว่าการบริโภคของมนุษย์ สับสนแค่ไหน
Max Barraclough

4

สำหรับสิ่งต่าง ๆ เช่นตัวเลข (จุดทศนิยม, เครื่องหมายจุลภาคในจำนวน), พวกเขามักจะชอบในวัฒนธรรมเฉพาะ

วิธีที่เหมาะสมในการทำเช่นนี้จะถูกตั้งไว้ที่ระดับวัฒนธรรม (สำหรับภาษาเยอรมัน) เช่นนี้:

Thread.CurrentThread.CurrentCulture.NumberFormat = new CultureInfo("de").NumberFormat;

4

JetBrains เสนอที่เหมาะสมคำอธิบาย ,

"การแปลง Ad-hoc ของโครงสร้างข้อมูลเป็นข้อความนั้นขึ้นอยู่กับวัฒนธรรมปัจจุบันเป็นส่วนใหญ่และอาจนำไปสู่ผลลัพธ์ที่ไม่ได้ตั้งใจเมื่อโค้ดถูกเรียกใช้บนเครื่องที่มีโลแคลแตกต่างจากของผู้พัฒนาดั้งเดิมเพื่อป้องกันความกำกวม อินสแตนซ์ใด ๆ ในรหัสที่อาจเกิดปัญหาดังกล่าว "

แต่ถ้าฉันทำงานในเว็บไซต์ที่ฉันรู้ว่าจะเป็นภาษาอังกฤษเท่านั้นฉันก็ไม่สนใจคำแนะนำ

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