Mengapa pemisah kelompok nomor budaya "de-CH" .NET berbeda secara lokal dan di Azure?

Aug 19 2020

Saya melihat karakter Unicode yang berbeda sebagai pemisah grup angka untuk budaya "de-CH" saat berjalan di desktop lokal dan di Azure.

Ketika kode berikut dijalankan di desktop saya di .NET Core 3.1 atau .NETFramework 4.7.2 outputnya 2019terlihat seperti apostrof tetapi tidak sama.

Saat dijalankan di Azure, misalnya di https://try.dot.netatau (sedikit diubah) dalam fungsi Azure yang berjalan di .NET Core 3.1 (pada Layanan Aplikasi berbasis Windows) yang dihasilkannya 0027, apostrof ASCII standar.

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

Hasil dari ini adalah mencoba mengurai string 4'200.000(di mana apostrof ada Unicode 0027) di desktop lokal menggunakan budaya "de-CH" gagal, tetapi berfungsi di Azure.

Kenapa beda?

Jawaban

NineBerry Sep 04 2020 at 10:55

Blog Microsoft oleh Shawn Steele ini menjelaskan mengapa Anda tidak boleh mengandalkan pengaturan budaya tertentu yang stabil (Dikutip penuh karena tidak lagi online di 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/

Data CultureInfo dan RegionInfo mewakili preferensi budaya, regional, admin atau pengguna untuk pengaturan budaya. Aplikasi TIDAK boleh membuat asumsi apa pun yang mengandalkan stabilnya data ini. Satu-satunya pengecualian (ini adalah aturan, jadi tentu saja ada pengecualian) adalah untuk CultureInfo.InvariantCulture. CultureInfo.InvariantCulture seharusnya tetap stabil, bahkan di antara versi.

Ada banyak alasan mengapa data budaya bisa berubah. Dengan Whidbey dan Custom Cultures, daftarnya menjadi sedikit lebih lama.

  • Alasan paling jelas adalah adanya bug pada data dan kami harus melakukan perubahan. (Percaya atau tidak kami membuat kesalahan ;-)) Dalam hal ini pengguna kami (dan Anda juga) menginginkan data yang benar secara budaya, jadi kami harus memperbaiki bug meskipun itu merusak aplikasi yang ada.
  • Alasan lainnya adalah preferensi budaya dapat berubah. Ada banyak cara ini dapat terjadi, tetapi itu terjadi:
    • Kesadaran global, pertukaran lintas budaya, perubahan peran komputer, dan sebagainya, semuanya dapat mempengaruhi preferensi budaya.
    • Perjanjian internasional, perdagangan, dll. Dapat mengubah nilai. Adopsi Euro mengubah simbol mata uang banyak negara menjadi €.
    • Peraturan nasional atau regional dapat mempengaruhi nilai-nilai ini juga.
    • Ejaan kata yang disukai dapat berubah seiring waktu.
    • Format tanggal yang diinginkan, dll. Dapat berubah.
  • Beberapa preferensi bisa ada untuk suatu budaya. Pilihan terbaik yang disukai kemudian dapat berubah seiring waktu.
  • Pengguna mungkin telah mengganti beberapa nilai, seperti format tanggal atau waktu. Ini dapat diminta tanpa penggantian pengguna, namun kami menyarankan agar aplikasi mempertimbangkan untuk menggunakan penggantian pengguna.
  • Pengguna atau administrator dapat membuat budaya pengganti, mengganti nilai default umum untuk budaya dengan data standar khusus perusahaan, regional tertentu, atau variasi lainnya.
    • Beberapa budaya mungkin memiliki preferensi yang berbeda-beda tergantung pada pengaturannya. Bisnis mungkin memiliki bentuk yang lebih formal daripada Warnet.
    • Suatu perusahaan mungkin memerlukan format tanggal atau format waktu tertentu untuk seluruh organisasi.
  • Versi yang berbeda dari budaya kustom yang sama, atau versi kustom di satu mesin dan budaya khusus jendela di komputer lain.

Jadi jika Anda memformat string dengan format tanggal / waktu tertentu, dan kemudian mencoba mengurai nanti, parse mungkin gagal jika versinya berubah, jika mesin berubah, jika versi kerangka berubah (data yang lebih baru), atau jika budaya kustom sudah berubah. Jika Anda perlu menyimpan data dalam format yang dapat diandalkan, pilih metode biner, berikan format Anda sendiri atau gunakan InvariantCulture.

Meskipun tanpa mengubah data, mengingat untuk menggunakan Invarian tetap merupakan ide yang bagus. Jika Anda memiliki yang berbeda. dan, sintaks untuk sesuatu seperti 1.000.29, maka Parsing bisa menjadi bingung jika klien mengharapkan 1.000,29. Saya telah melihat masalah ini dengan aplikasi yang tidak menyadari bahwa budaya pengguna akan berbeda dari budaya pengembang. Menggunakan Invarian atau teknik lain memecahkan masalah semacam ini.

Tentu saja Anda tidak dapat memiliki tampilan yang "benar" untuk pengguna saat ini dan tampilan yang sempurna jika data budaya berubah. Jadi umumnya saya akan merekomendasikan menyimpan data menggunakan InvariantCulture atau format tetap lainnya, dan selalu menggunakan API pemformatan yang sesuai untuk tampilan. Aplikasi Anda akan memiliki persyaratannya sendiri, jadi pertimbangkan baik-baik.

Perhatikan bahwa untuk pemeriksaan (urutan sortir / perbandingan), bahkan perilaku Invarian dapat berubah. Anda harus menggunakan Sort Versioning untuk menyiasatinya jika Anda memerlukan urutan sortir yang stabil secara konsisten.

Jika Anda perlu mengurai data secara otomatis yang diformat agar ramah pengguna, ada dua pendekatan:

  • Izinkan pengguna untuk secara eksplisit menentukan format yang digunakan.
  • Hapus terlebih dahulu setiap karakter kecuali angka, tanda minus dan pemisah desimal dari string sebelum mencoba mengurai ini. Perhatikan bahwa Anda perlu mengetahui pemisah desimal yang benar terlebih dahulu. Tidak ada cara untuk menebak ini dengan benar dan salah menebak dapat mengakibatkan masalah besar.

Jika memungkinkan, cobalah untuk menghindari penguraian angka yang diformat agar mudah digunakan. Sebaliknya, jika memungkinkan, cobalah untuk meminta nomor dalam format yang ditentukan secara ketat (invarian).