Bagaimana cara melokalkan angka dengan benar?

38

Peringatan apa yang harus saya perhatikan saat mencari nomor di aplikasi front-end saya?

Contoh: Dalam bahasa Portugis Brasil (pt-BR) kami membagi ribuan dengan titik dan desimal dengan koma. Dalam US English (en-US) itu yang sebaliknya. Di pt-BR kami menyajikan angka yang dipisahkan oleh ribuan, sama dengan en-AS. Tetapi membaca tentang Bahasa Inggris India (id-IN) hari ini saya menemukan permata ini:

Sistem penomoran India lebih disukai untuk pengelompokan digit. Ketika ditulis dalam kata-kata, atau ketika diucapkan, angka kurang dari 100.000 / 100.000 diekspresikan sama seperti mereka dalam Bahasa Inggris Standar. Angka-angka termasuk dan melampaui 100.000 / 100.000 diekspresikan dalam subset dari sistem penomoran India.

https://en.wikipedia.org/wiki/Indian_English#Numbering_system

Yang berarti:

1000000 units in pt-BR are formatted 1.000.000
1000000 units in en-US are formatted 1,000,000
1000000 units in en-IN are formatted 10,00,000

Selain koma dan titik dan pemisah khusus lainnya, tampaknya masking juga menjadi perhatian yang valid.

Peringatan apa lagi yang harus saya perhatikan saat mencari nomor di aplikasi front-end saya? Khususnya jika saya menunjukkan angka ke rangkaian karakter non-latin?

Machado
sumber
3
Semakin menarik saat berhadapan dengan uang! :-)
Stephan Bijzitter
4
Tidak berbicara tentang sistem penomoran Mars yang memiliki basis 6 (dua kali 3 jari) ;-) Tetapi bahasa Jepang juga memiliki keanehan: man = 10.000 ditulis sebagai 1.0000, oku = 100.000.000 ditulis di Jepang sebagai 1.0000.0000 dan chō. .. guess
qwerty_so
6
Mengapa Anda harus khawatir tentang ini? Tidak bisakah Anda mengikuti pengaturan OS?
Jan Doggen
3
@JanDoggen karena itulah salah satu masalah menarik dari domain Rekayasa Perangkat Lunak, "cara menyajikan data dengan benar kepada orang-orang". Yang harus saya khawatirkan ketika mendesain sistem adalah domain dari pertanyaan ini. Dan saya bahkan tidak berbicara tentang uang, seperti yang dikatakan teman kita Stephan, tidak juga tanggal dan waktu. Hanya angka mentah.
Machado
5
@ JanDoggen, ini menjadi jauh lebih kompleks ketika berhadapan dengan perangkat lunak online. Pengguna mungkin berada di India, di komputer Inggris AS, tetapi membaca halaman web dalam bahasa Portugis Brasil. Server Anda mungkin berbahasa Mandarin. Aplikasi Anda harus memahami apa yang diinginkan pengguna, terlepas dari OS apa yang ia gunakan, atau di mana server Anda. Jadi 1.000,00 dolar Anda menjadi 67,545,00 rupee: mata uang AS, dikonversi dengan nilai tukar lokal, tetapi ditampilkan dalam format Portugis.
noderman

Jawaban:

87

Sebagian besar bahasa dan kerangka kerja pemrograman sudah memiliki mekanisme kerja yang masuk akal yang dapat Anda gunakan untuk ini.

Sebagai contoh, ekosistem C # memiliki namespace System.Globalization , yang memungkinkan Anda menentukan yang CultureAnda inginkan:

Console.WriteLine(myMoneyValue.ToString("C", "en-US"));

Ini bukan sesuatu yang ingin Anda ciptakan kembali. Gunakan fitur internasionalisasi yang disediakan oleh bahasa atau kerangka kerja favorit Anda.

Robert Harvey
sumber
2
Saya menyadari System.Globalisasi dan kerangka kerja lain yang menangani kompleksitas semacam ini bagi saya. Yang saya tidak tahu adalah masalah apa yang mereka selesaikan. Misalnya, beberapa aplikasi yang saya lihat menggunakan masking spesifik pada ToString, seperti .ToString ("#, ## 0,00", lokal), tetapi mask itu sendiri tidak valid jika saya menunjukkan nomor ini kepada orang India. Jadi, selain "tidak menggunakan topeng khusus", apa lagi yang harus saya ketahui?
Machado
7
Tidak ada yang saya ketahui. Jika Anda menggunakan kerangka kerja dengan benar, itu hanya akan berfungsi. Ada beberapa kasus khusus tentang masalah internasionalisasi, tetapi membangun daftar komprehensif mereka bukanlah sesuatu yang kita lakukan di sini. Lihat contoh ini .
Robert Harvey
5
Ini adalah satu-satunya jawaban yang benar: atur lokal Anda, lalu dorong nilai-nilai Anda melalui lapisan i18n sebelum ditampilkan kepada pengguna dan biarkan pembuat kerangka mengatasinya. Ini berlaku untuk angka, nilai mata uang, string yang diterjemahkan, tanggal, semuanya.
2
Jawaban sempurna. "Jangan menemukan kembali roda" adalah sesuatu yang harus selalu dipertimbangkan ketika berhadapan dengan masalah umum seperti ini. Sangat disayangkan saya tidak bisa memilih lebih dari satu kali.
BgrWorker
3
@Machado "Misalnya, beberapa aplikasi yang saya lihat menggunakan masking spesifik pada ToString, seperti .ToString (" #, ## 0.00 ", lokal), tetapi mask itu sendiri tidak valid jika saya menunjukkan nomor ini kepada orang India . " - Mungkin tidak jelas, tetapi perhatikan bahwa posisi ,dalam format string sebagian besar tidak relevan dan "#, 0,00" akan memiliki efek yang sama. ,hanya berarti "menggunakan pemisah grup angka dengan cara yang ditentukan oleh lokal".
hvd
23

Beberapa jawaban yang bagus sudah ada di sini, tetapi mereka tidak menyebutkan satu hal yang saya pikir penting untuk tidak dilupakan: pastikan di mana pun terjadi pemformatan angka, jelas (atau dapat dikontrol) untuk apa output digunakan:

  • ketika itu untuk antarmuka pengguna, pemformatan lokal harus diterapkan

  • ketika nomor akan ditulis ke file, atau dikirim melalui jaringan, atau bentuk lain di mana nomor tersebut diperlukan dalam bentuk yang dapat dibaca mesin , pastikan itu tidak diformat sesuai dengan budaya saat ini, tetapi sesuai dengan pengaturan tetap (misalnya, di lingkungan .NET, gunakan InvariantCulture).

Kalau tidak, Anda mendapatkan masalah ketika angka ditulis atau dikirim menggunakan budaya A, dan membaca atau diterima menggunakan budaya B.

Menurut pengalaman saya, ini adalah salah satu rintangan terbesar dalam melakukan pelokalan angka yang tepat: dalam upaya memusatkan pemformatan dan konversi angka, orang-orang mulai membuat fungsi umum yang dapat digunakan kembali untuk pemformatan, dan kemudian mulai menggunakannya di seluruh tempat. Namun, segera setelah seseorang membutuhkan angka-angka juga dalam format string yang dapat dibaca mesin di tempat lain dalam program ini, diperlukan dua varian: format lokal dan non-lokal. Ini menimbulkan risiko tinggi untuk menggabungkan dua bentuk konversi (terutama ketika pengembang dan mesin pengujian memiliki pengaturan lokal default yang mirip dengan pengaturan "tetap" yang digunakan untuk pemformatan non-UI, tetapi sebagian basis pengguna belum).

Tambahan: masalah ini dapat menjadi benar-benar buruk dalam situasi di mana tidak jelas sebelumnya apakah nomor tersebut akan diproses oleh mesin, atau oleh manusia (atau keduanya) nanti. Misalnya, sebagai bagian dari output file log. Dalam kasus seperti itu, mungkin yang terbaik adalah tetap menggunakan standar "netral" untuk tidak menggunakan pemisah kecuali titik sebagai pemisah desimal.

Doc Brown
sumber
2
Dan lebih buruk lagi banyak bahasa pogram modern fungsi jelas / default di perpustakaan standar "terlokalisasi". Jadi jika pengembang tidak tahu atau peduli tentang pelokalan, aplikasi yang dihasilkan cenderung tidak berfungsi daripada hanya jelek pada sistem asing.
Peter Green
4
Saya tidak setuju sama buruknya. Alat yang tidak mengikuti konvensi numerik lokal di UI itu masih dapat digunakan. Alat yang gagal membaca file datanya sendiri atau gagal berbicara dengan servernya karena ketidakcocokan konvensi numerik jauh lebih mungkin tidak dapat digunakan.
Peter Green
5
Sebuah anekdot tentang ini: Pemisah desimal untuk en-ZA berubah antara Win 7 dan Win 8. Sebelumnya nilai yang disimpan secara lokal mulai gagal untuk deserialize
Caleth
1
@PeterGreen: alat yang tidak mengikuti konvensi numerik lokal di UI itu mungkin masih dapat digunakan, atau mungkin sepenuhnya tidak dapat digunakan untuk kasus penggunaan tertentu. Saya akan sangat berhati-hati dalam membuat asumsi seperti itu. Alasan mengapa begitu banyak dev mendapatkan lokalisasi angka salah adalah justru - membuat asumsi seperti ini.
Doc Brown
1
@DocBrown Saya memiliki kode warisan yang paling mengerikan untuk dipelihara yang menderita rutinitas integer / float parsing terlampir perpustakaan standar. Saya pikir itu adil untuk mengatakan bahwa sebuah program yang ditulis tanpa peduli lokalisasi ketika rutinitas default untuk pekerjaan ini non-lokal mungkin tidak dapat digunakan untuk beberapa situasi, tetapi jika rutin default dilokalisasi, program akan selalu rusak saat itu dieksekusi di komputer di mana lokal global bukan bahasa Inggris.
Sebastian Redl
9

Pelokalan yang tepat cukup sulit. Sebagian besar ekosistem pemrograman mencoba mencari solusi untuk pelokalan, tetapi menurut pengalaman saya, semuanya kurang lebih rusak. Karena itu saya akan menyarankan:

  • Jangan mencoba mengotomatiskan pelokalan. Itu tidak akan selalu berhasil. Sulit bagi Anda untuk menemukan masalah, dan membuat frustrasi bagi pengguna Anda.

  • Konsisten: jangan mencampur bahasa yang berbeda dan konvensi pemformatan, misalnya pemisah desimal gaya Brasil dalam teks bahasa Inggris.

  • Secara eksplisit mendukung serangkaian lokal yang diberikan. Bekerja sama dengan penerjemah Anda untuk mengetahui pemformatan yang tepat untuk tanggal dan angka. Anda mungkin akan akhirnya membuat perangkat lokalisasi Anda sendiri, meskipun sebagian besar (tetapi tidak semua) masalah dapat didelegasikan ke perpustakaan yang ada.

  • Buat pilihan pemformatan sederhana yang dapat dikonfigurasi oleh setiap pengguna: format untuk tanggal dan waktu, pemisah desimal, mata uang pilihan,…. Ini sangat berguna untuk pelancong, ekspatriat, atau orang lain yang perlu mencampur beberapa lokal atau budaya secara terpisah dari bahasa.

amon
sumber
18
Perlu diketahui juga bahwa sejumlah besar pengguna membenci konvensi yang dianggap "benar untuk lokasi mereka", menganggapnya sebagai praktik warisan yang mengerikan, dan tidak ingin ada pengelompokan sama sekali, atau jenis pengelompokan yang berbeda. Karena itu mungkin harus ada opsi untuk mematikannya atau menimpanya secara manual.
R ..
2

Pertimbangan penting: Anda harus memutuskan berapa banyak yang cukup. Karena jika Anda turun ke lubang kelinci untuk mencoba melokalisasi dengan sempurna, itu akan menjadi semakin kompleks.

Ambil label khas seperti "Anda telah memilih n item." Ini terbaca salah jika hanya ada satu item yang dipilih. Solusi jelek tapi pragmatis adalah menulis "Anda telah memilih n item." Tetapi jika Anda ingin melakukannya dengan benar, Anda memerlukan dua teks berbeda tergantung pada n. Jika Anda mencoba melakukan ini di banyak lokal, itu akan menjadi sangat rumit, karena berbagai bahasa memiliki tata bahasa yang berbeda. Beberapa bahasa memiliki konjugasi berbeda untuk satu, dua, dan banyak item dan sebagainya. Untuk alasan ini orang yang tahu akan selalu mengeluh bahwa kerangka kerja lokalisasi yang ada tidak cukup.

Tetapi Anda harus memilih pertempuran Anda, dan memutuskan tingkat kecanggihan apa yang cukup. Untuk banyak tujuan, perpustakaan pelokalan standar untuk memformat angka dan tanggal harus memadai.

JacquesB
sumber
Ini diselesaikan oleh ICU (MessageFormat). Kekurangannya adalah bahwa adopsi ICU pada banyak bahasa masih lemah. Namun, pengembang masih perlu membuat pesan dengan cara yang benar. Ini benar-benar lebih dari aspek teknik itu. userguide.icu-project.org/formatparse/messages
noderman
Ini juga dipecahkan oleh fungsi ngettext yang tersedia lebih luas di GNU gettext, tetapi kelas MessageFormat tampaknya juga memecahkan beberapa masalah tambahan yang tidak dimiliki ngettext.
hvd
2

Anda tidak dapat menyadari semua peringatan bahasa. Anda berbicara tentang angka, tetapi ada bentuk jamak, jenis kelamin, susunan. Anda perlu tahu bahwa mereka ada dan bergantung pada pekerjaan ekstensif yang dilakukan oleh orang lain, terutama proyek ICU dan CLDR.

Sebagian besar bahasa modern menerapkan beberapa atau semua fitur dari proyek ini, tetapi meskipun tidak, membaca tentang proyek ini akan memberi Anda ide yang baik tentang apa yang harus dicari.

http://site.icu-project.org

http://cldr.unicode.org

Memperbarui

Alat survei CLDR menyediakan akses ke semua pola. Itu akan menunjukkan kepada Anda bagaimana memformat angka dalam bahasa dan wilayah tertentu. Misalnya, bahasa Portugis (Portugal):

http://st.unicode.org/cldr-apps/v#/pt_PT/Number_Formatting_Patterns/

Dan jika Anda benar-benar ingin memeriksa semua data (dan mungkin menggunakannya), Anda dapat mengunduh CLDR dalam format JSON dari GitHub:

https://github.com/unicode-cldr/cldr-json#cldr-json

Info lebih lanjut tentang unduhan di sini:

http://cldr.unicode.org/index/downloads

noderman
sumber
Terima kasih atas masukannya, tapi sekarang saya lebih tertarik pada angka. :)
Machado
Yakin. Saya baru saja mengedit respons untuk menyertakan tautan ke alat survei, tempat Anda dapat mempersempit pencarian Anda.
noderman
Saya mencoba mengubah do Brazil, untuk memeriksa perbedaannya, tetapi sepertinya tidak memungkinkan visualisasi untuk itu: st.unicode.org/cldr-apps/v#/pt_BR/Number_Formatting_Patterns Kalau tidak, alat ini sepertinya cukup bagus.
Machado
Itu karena Brasil adalah bahasa utama. Alat survei sebenarnya digunakan untuk membuat perubahan pada data CLDR, sehingga akarnya memerlukan akun khusus. Anda dapat pergi ke GitHub dan mendapatkan semua info secara langsung: github.com/unicode-cldr/cldr-numbers-modern/tree/master/main Secara khusus, Brasil ada di sini: github.com/unicode-cldr/cldr-numbers-modern/ gumpalan / master / utama / pt / ...
noderman
0

Yah, sementara saya senang dengan semua jawaban di sini, saya tidak benar-benar puas dengan masing-masing secara terpisah untuk menandai satu sebagai jawaban yang benar.

Sejauh ini yang harus kita waspadai saat melokalkan angka:

Untuk manusia :

  • Ribuan pemisah tidak selalu terpisah ribuan. Lihat kasus India dalam pertanyaan;
  • Ribuan dan desimal karakter bervariasi dari budaya ke budaya. Di Jerman ribuan dipisah menggunakan spasi, misalnya, sedangkan dalam bahasa Inggris itu adalah komandan dan dalam bahasa Portugis itu adalah titik;
  • Kami tidak memiliki informasi jika ada perbedaan yang relevan antara bahasa dari kiri ke kanan dan kanan ke kiri;
  • Berikan satu set spesifik pelokalan yang didukung dan jelaskan untuk pengguna Anda;
  • Izinkan pengguna Anda mengubah lokalisasi default ke salah satu lokalisasi yang didukung dan mereka akan senang dan mengirimi Anda kue bersyukur, karena Anda adalah dewa yang baik. :);

Untuk komputer :

  • Ingat bahwa mesin tidak lunak dan harus selalu menerima pemformatan yang sama saat membuat cerita bersambung dan menghapus cerita bersambung;
  • Tetap dengan satu format untuk itu;
  • Gunakan format minimum yang diperlukan. Hindari ribuan pemisahan, desimal harus cukup untuk serialisasi dan de-serialisasi.

Untuk pengembang :

  • (seperti yang disarankan oleh @hyde di bawah): Gunakan perpustakaan yang ada untuk pelokalan;
  • Jika Anda bisa, gunakan penguji asli dan tentukan kasus uji lokalisasi / internasionalisasi, kalau tidak percayakan perpustakaan;
  • Ingat bahwa pelokalan adalah masalah yang sebagian besar diselesaikan. Setiap bahasa utama memiliki perpustakaan, asli atau eksternal, yang dapat melokalkan angka, tanggal dan waktu;
Machado
sumber
1
Item tidak ada: Untuk pengembang: gunakan perpustakaan yang ada untuk pelokalan. Jika Anda bisa, gunakan penguji asli dan tentukan kasus uji lokalisasi / internasionalisasi, jika tidak percaya perpustakaan.
hyde