เหตุใดตัวคั่นกลุ่มหมายเลขวัฒนธรรม. NET“ de-CH” จึงแตกต่างกันทั้งในเครื่องและบน Azure

Aug 19 2020

ฉันเห็นอักขระ 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

ทำไมถึงแตกต่าง?

คำตอบ

NineBerry Sep 04 2020 at 10:55

บล็อกของ 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 การจัดรูปแบบที่เหมาะสมสำหรับการแสดง ใบสมัครของคุณจะมีข้อกำหนดของตัวเองดังนั้นควรพิจารณาอย่างรอบคอบ

โปรดทราบว่าสำหรับการเรียงลำดับ (ลำดับการจัดเรียง / การเปรียบเทียบ) แม้แต่พฤติกรรมที่ไม่เปลี่ยนแปลงก็สามารถเปลี่ยนแปลงได้ คุณจะต้องใช้การจัดเรียงเวอร์ชันเพื่อหลีกเลี่ยงสิ่งนั้นหากคุณต้องการลำดับการจัดเรียงที่คงที่อย่างสม่ำเสมอ

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

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

หากเป็นไปได้พยายามหลีกเลี่ยงการแยกวิเคราะห์ตัวเลขที่จัดรูปแบบให้ใช้งานง่าย เมื่อใดก็ตามที่เป็นไปได้ให้พยายามขอหมายเลขในรูปแบบที่กำหนดไว้อย่างเคร่งครัด (คงที่)