เหตุใดตัวคั่นกลุ่มหมายเลขวัฒนธรรม. NET“ de-CH” จึงแตกต่างกันทั้งในเครื่องและบน Azure
ฉันเห็นอักขระ Unicode ที่แตกต่างกันเป็นตัวคั่นกลุ่มตัวเลขสำหรับวัฒนธรรม "de-CH" เมื่อทำงานบนเดสก์ท็อปภายในและใน Azure
เมื่อรันโค้ดต่อไปนี้บนเดสก์ท็อปของฉันใน. NET Core 3.1 หรือ. NET Framework 4.7.2 ผลลัพธ์จะออกมา2019
ซึ่งดูเหมือนเครื่องหมายวรรคตอน แต่ไม่เหมือนกัน
เมื่อทำงานใน Azure เช่นใน https://try.dot.netหรือ (แก้ไขเล็กน้อย) ในฟังก์ชัน Azure ที่ทำงานบน. NET Core 3.1 (บนบริการแอพที่ใช้ Windows) ผลลัพธ์จะ0027
เป็นเครื่องหมายวรรคตอน ASCII มาตรฐาน
using System;
using System.Linq;
using System.Globalization;
Console.WriteLine(((int)(CultureInfo
.GetCultureInfo("de-CH")
.NumberFormat
.NumberGroupSeparator
.Single())) // Just getting the single character as an int
.ToString("X4") // unicode value of that character
);
ผลลัพธ์ที่ได้คือการพยายามแยกวิเคราะห์สตริง4'200.000
(โดยที่เครื่องหมายวรรคตอนมี Unicode 0027
) บนเดสก์ท็อปเฉพาะที่โดยใช้วัฒนธรรม "de-CH" ล้มเหลว แต่ทำงานใน Azure
ทำไมถึงแตกต่าง?
คำตอบ
บล็อกของ Microsoft นี้โดย Shawn Steele อธิบายว่าเหตุใดคุณจึงไม่ควรพึ่งพาการตั้งค่าวัฒนธรรมเฉพาะที่มีความเสถียร (อ้างถึงอย่างสมบูรณ์เนื่องจากไม่ได้ออนไลน์ที่ MSDN อีกต่อไป):
https://web.archive.org/web/20190110065542/https://blogs.msdn.microsoft.com/shawnste/2005/04/05/culture-data-shouldnt-be-considered-stable-except-for-invariant/
ข้อมูล CultureInfo และ RegionInfo แสดงถึงความชอบทางวัฒนธรรมภูมิภาคผู้ดูแลระบบหรือผู้ใช้สำหรับการตั้งค่าทางวัฒนธรรม แอปพลิเคชันไม่ควรตั้งสมมติฐานใด ๆ ว่าข้อมูลนี้มีความเสถียร ข้อยกเว้นเพียงอย่างเดียว (นี่เป็นกฎดังนั้นแน่นอนว่ามีข้อยกเว้น) สำหรับ CultureInfo.InvariantCulture CultureInfo.InvariantCulture ควรจะยังคงมีเสถียรภาพแม้จะอยู่ระหว่างเวอร์ชัน
มีหลายเหตุผลที่ข้อมูลทางวัฒนธรรมสามารถเปลี่ยนแปลงได้ ด้วย Whidbey และ Custom Cultures รายการจะยาวขึ้นเล็กน้อย
- สาเหตุที่ชัดเจนที่สุดคือมีข้อบกพร่องในข้อมูลและเราต้องทำการเปลี่ยนแปลง (เชื่อหรือไม่ว่าเราทำผิดพลาด ;-)) ในกรณีนี้ผู้ใช้ของเรา (และของคุณด้วย) ต้องการข้อมูลที่ถูกต้องตามวัฒนธรรมดังนั้นเราจึงต้องแก้ไขข้อบกพร่องแม้ว่าจะทำให้แอปพลิเคชันที่มีอยู่เสียหายก็ตาม
- อีกเหตุผลหนึ่งคือความชอบทางวัฒนธรรมสามารถเปลี่ยนแปลงได้ มีหลายวิธีที่สามารถเกิดขึ้นได้ แต่มันจะเกิดขึ้น:
- การรับรู้ทั่วโลกการแลกเปลี่ยนข้ามวัฒนธรรมบทบาทที่เปลี่ยนไปของคอมพิวเตอร์และอื่น ๆ ล้วนส่งผลต่อความชอบทางวัฒนธรรม
- สนธิสัญญาระหว่างประเทศการค้า ฯลฯ สามารถเปลี่ยนแปลงค่านิยม การยอมรับสกุลเงินยูโรเปลี่ยนสัญลักษณ์สกุลเงินของหลายประเทศเป็น€
- กฎระเบียบระดับชาติหรือระดับภูมิภาคอาจส่งผลต่อค่านิยมเหล่านี้ด้วย
- การสะกดคำที่ต้องการสามารถเปลี่ยนแปลงได้ตลอดเวลา
- รูปแบบวันที่ที่ต้องการ ฯลฯ สามารถเปลี่ยนแปลงได้
- การตั้งค่าหลายอย่างอาจมีอยู่สำหรับวัฒนธรรม ทางเลือกที่ดีที่สุดที่ต้องการสามารถเปลี่ยนแปลงได้ตลอดเวลา
- ผู้ใช้สามารถลบล้างค่าบางค่าได้เช่นรูปแบบวันที่หรือเวลา สิ่งเหล่านี้สามารถร้องขอได้โดยไม่ต้องลบล้างผู้ใช้อย่างไรก็ตามเราขอแนะนำให้แอปพลิเคชันพิจารณาใช้การลบล้างผู้ใช้
- ผู้ใช้หรือผู้ดูแลระบบสามารถสร้างวัฒนธรรมทดแทนแทนที่ค่าเริ่มต้นทั่วไปสำหรับวัฒนธรรมด้วยข้อมูลมาตรฐานเฉพาะของ บริษัท เฉพาะภูมิภาคหรือรูปแบบอื่น ๆ
- บางวัฒนธรรมอาจมีความชอบที่แตกต่างกันไปขึ้นอยู่กับการตั้งค่า ธุรกิจอาจมีรูปแบบที่เป็นทางการมากกว่าร้านอินเทอร์เน็ต
- องค์กรอาจต้องการรูปแบบวันที่หรือรูปแบบเวลาที่เฉพาะเจาะจงสำหรับทั้งองค์กร
- เวอร์ชันที่แตกต่างกันของวัฒนธรรมที่กำหนดเองเดียวกันหรือที่กำหนดเองในเครื่องหนึ่งและวัฒนธรรมเฉพาะ Windows ในเครื่องอื่น
ดังนั้นหากคุณจัดรูปแบบสตริงด้วยรูปแบบวันที่ / เวลาเฉพาะแล้วลองแยกวิเคราะห์ในภายหลังการแยกวิเคราะห์อาจล้มเหลวหากเวอร์ชันมีการเปลี่ยนแปลงหากเครื่องเปลี่ยนไปหากเวอร์ชันของเฟรมเวิร์กเปลี่ยนไป (ข้อมูลที่ใหม่กว่า) หรือหากวัฒนธรรมที่กำหนดเอง เปลี่ยนไปแล้ว. หากคุณต้องการคงข้อมูลไว้ในรูปแบบที่เชื่อถือได้ให้เลือกวิธีไบนารีระบุรูปแบบของคุณเองหรือใช้ InvariantCulture
แม้ว่าจะไม่มีการเปลี่ยนแปลงข้อมูล แต่อย่าลืมใช้ Invariant ก็ยังคงเป็นความคิดที่ดี หากคุณมีความแตกต่างกัน และไวยากรณ์สำหรับบางสิ่งเช่น 1,000.29 การแยกวิเคราะห์อาจทำให้สับสนได้หากลูกค้าคาดหวังว่าจะได้ 1.000,29 ฉันพบปัญหานี้กับแอปพลิเคชันที่ไม่ทราบว่าวัฒนธรรมของผู้ใช้จะแตกต่างจากวัฒนธรรมของผู้พัฒนา การใช้ Invariant หรือเทคนิคอื่นช่วยแก้ปัญหาประเภทนี้ได้
แน่นอนว่าคุณไม่สามารถมีทั้งการแสดงผลที่ "ถูกต้อง" สำหรับผู้ใช้ปัจจุบันและการสะดุดรอบที่สมบูรณ์แบบหากข้อมูลวัฒนธรรมเปลี่ยนแปลงไป ดังนั้นโดยทั่วไปฉันขอแนะนำให้ใช้ข้อมูลที่คงอยู่โดยใช้ InvariantCulture หรือรูปแบบอื่นที่ไม่เปลี่ยนรูปและใช้ API การจัดรูปแบบที่เหมาะสมสำหรับการแสดง ใบสมัครของคุณจะมีข้อกำหนดของตัวเองดังนั้นควรพิจารณาอย่างรอบคอบ
โปรดทราบว่าสำหรับการเรียงลำดับ (ลำดับการจัดเรียง / การเปรียบเทียบ) แม้แต่พฤติกรรมที่ไม่เปลี่ยนแปลงก็สามารถเปลี่ยนแปลงได้ คุณจะต้องใช้การจัดเรียงเวอร์ชันเพื่อหลีกเลี่ยงสิ่งนั้นหากคุณต้องการลำดับการจัดเรียงที่คงที่อย่างสม่ำเสมอ
หากคุณต้องการแยกวิเคราะห์ข้อมูลโดยอัตโนมัติที่จัดรูปแบบให้ใช้งานง่ายมีสองวิธีดังนี้
- อนุญาตให้ผู้ใช้ระบุรูปแบบที่ใช้อย่างชัดเจน
- ขั้นแรกให้ลบอักขระทุกตัวยกเว้นตัวเลขเครื่องหมายลบและตัวคั่นทศนิยมออกจากสตริงก่อนที่จะพยายามแยกวิเคราะห์สิ่งนี้ โปรดทราบว่าคุณต้องทราบตัวคั่นทศนิยมที่ถูกต้องก่อน ไม่มีวิธีใดที่จะเดาได้อย่างถูกต้องและการเดาผิดอาจทำให้เกิดปัญหาใหญ่ได้
หากเป็นไปได้พยายามหลีกเลี่ยงการแยกวิเคราะห์ตัวเลขที่จัดรูปแบบให้ใช้งานง่าย เมื่อใดก็ตามที่เป็นไปได้ให้พยายามขอหมายเลขในรูปแบบที่กำหนดไว้อย่างเคร่งครัด (คงที่)