Làm thế nào để địa phương hóa đúng số?


38

Những lưu ý nào tôi cần lưu ý trong khi bản địa hóa các số trong ứng dụng front-end của mình?

Ví dụ: Trong tiếng Bồ Đào Nha Brazil (pt-BR), chúng tôi chia hàng ngàn dấu chấm và số thập phân bằng dấu phẩy. Trong tiếng Anh Mỹ (en-US) thì ngược lại. Trong pt-BR, chúng tôi trình bày các chữ số cách nhau bởi hàng ngàn, giống như en-US. Nhưng đọc về tiếng Anh Ấn Độ (en-IN) ngày hôm nay tôi đã bắt gặp viên ngọc này:

Hệ thống đánh số Ấn Độ được ưa thích để phân nhóm chữ số. Khi được viết bằng từ hoặc khi được nói, các số nhỏ hơn 100.000 / 100 000 được thể hiện giống như trong tiếng Anh chuẩn. Các số bao gồm và hơn 100.000 / 100 000 được thể hiện trong một tập hợp con của hệ thống đánh số Ấn Độ.

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

Nghĩa là:

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

Bên cạnh dấu phẩy và dấu chấm và các dấu tách cụ thể khác, có vẻ như mặt nạ cũng là một mối quan tâm hợp lệ.

Những lưu ý nào khác tôi nên biết trong khi bản địa hóa các số trong ứng dụng front-end của mình? Đặc biệt nếu tôi đang hiển thị số cho các bộ ký tự không phải là tiếng Latin?


3
Thậm chí còn thú vị hơn khi giao dịch với tiền! :-)
Stephan bijzitter

4
Không nói về hệ thống đánh số sao Hỏa có cơ sở 6 (hai lần 3 ngón tay) ;-) Nhưng tiếng Nhật cũng có một điều kỳ lạ: man = 10.000 được viết là 1.0000, oku = 100.000.000 được viết tại Nhật Bản là 1.0000.0000 và chō. .. đoán
qwerty_so

6
Tại sao bạn phải lo lắng về điều này? Bạn không thể làm theo các cài đặt hệ điều hành?
Jan Doggen

3
@JanDoggen vì đó là một trong những vấn đề thú vị của miền Kỹ thuật phần mềm, "làm thế nào để trình bày dữ liệu đúng cách cho mọi người". Điều tôi nên lo lắng khi thiết kế một hệ thống là miền của câu hỏi này. Và tôi thậm chí không nói về tiền, như người bạn Stephan của chúng tôi đã nói, cũng không phải ngày giờ. Chỉ là số nguyên.
Machado

5
@JanDoggen, điều này trở nên phức tạp hơn rất nhiều khi giao dịch với phần mềm trực tuyến. Người dùng có thể ở Ấn Độ, trên máy tính tiếng Anh Mỹ, nhưng đọc một trang web bằng tiếng Bồ Đào Nha Brazil. Máy chủ của bạn có thể là người Trung Quốc. Ứng dụng của bạn phải hiểu người dùng muốn gì, bất kể anh ấy / cô ấy đang sử dụng hệ điều hành nào, hoặc máy chủ của bạn đang ở đâu. Vì vậy, 1.000 đô la của bạn trở thành 67,545,00 rupee: một loại tiền tệ của Mỹ, được chuyển đổi theo tỷ giá hối đoái địa phương, nhưng được hiển thị ở định dạng Bồ Đào Nha.
gật đầu

Câu trả lời:


87

Hầu hết các ngôn ngữ lập trình và khung đã có một cơ chế làm việc hợp lý mà bạn có thể sử dụng cho việc này.

Ví dụ: hệ sinh thái C # có không gian tên System.Globalization , cho phép bạn chỉ định Culturebạn muốn:

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

Đây không phải là thứ mà bạn muốn phát minh lại. Sử dụng các tính năng quốc tế hóa được cung cấp bởi ngôn ngữ hoặc khung yêu thích của bạn.


2
Tôi biết về System.Globalization và các khung công tác khác xử lý các loại phức tạp này đối với tôi. Những gì tôi không biết là những gì họ đang giải quyết. Chẳng hạn, một số ứng dụng tôi thấy sử dụng mặt nạ cụ thể trên ToString, như .ToString ("#, ## 0,00", miền địa phương), nhưng mặt nạ đó không hợp lệ nếu tôi hiển thị số này cho người Ấn Độ. Vì vậy, ngoài "không sử dụng mặt nạ cụ thể", tôi cần lưu ý điều gì khác?
Machado

7
Không có gì mà tôi biết. Nếu bạn sử dụng khung đúng cách, nó sẽ hoạt động. Có một số trường hợp cụ thể, cụ thể về các vấn đề quốc tế hóa, nhưng xây dựng một danh sách toàn diện về chúng không phải là điều chúng tôi làm ở đây. Xem ví dụ này .
Robert Harvey

5
Đây là câu trả lời đúng duy nhất: đặt ngôn ngữ của bạn, sau đó đẩy các giá trị của bạn qua lớp i18n trước khi hiển thị cho người dùng và để các tác giả khung xử lý nó. Điều này đúng với số, giá trị tiền tệ, chuỗi dịch, ngày, mọi thứ.

2
Câu trả lời hoàn hảo. "Không phát minh lại bánh xe" là điều cần luôn được xem xét trong khi xử lý các vấn đề phổ biến như vấn đề này. Thật đáng tiếc tôi không thể nâng cao hơn một lần.
BgrWorker

3
@Machado "Chẳng hạn, một số ứng dụng tôi thấy sử dụng mặt nạ cụ thể trên ToString, như .ToString (" #, ## 0,00 ", ngôn ngữ), nhưng mặt nạ đó không hợp lệ nếu tôi hiển thị số này cho người Ấn Độ . " - Có thể không rõ ràng, nhưng lưu ý rằng vị trí của ,chuỗi định dạng phần lớn không liên quan và "#, 0,00" sẽ có tác dụng tương tự. ,chỉ đơn giản có nghĩa là "sử dụng dấu phân cách nhóm số theo cách được chỉ định bởi miền địa phương".
hvd

23

Một số câu trả lời xuất sắc ở đây đã có, nhưng họ không đề cập đến một điều mà tôi nghĩ là quan trọng không nên quên: đảm bảo bất cứ nơi nào định dạng số diễn ra, rõ ràng (hoặc có thể được kiểm soát) những gì đầu ra được sử dụng cho:

  • Khi nó dành cho giao diện người dùng, định dạng cục bộ phải được áp dụng

  • khi số sẽ được ghi vào một tệp, hoặc được gửi qua mạng hoặc một dạng khác trong đó số cần ở dạng có thể đọc được bằng máy , hãy đảm bảo rằng nó không được định dạng theo văn hóa hiện tại, nhưng theo một cài đặt cố định (ví dụ, trong môi trường .NET, sử dụng InvariantCulture).

Mặt khác, bạn gặp vấn đề khi số được viết hoặc gửi bằng văn hóa A và đọc hoặc nhận bằng văn hóa B.

Theo kinh nghiệm của tôi, đây là một trong những trở ngại lớn nhất trong việc nội địa hóa các con số đúng cách: trong nỗ lực tập trung định dạng và chuyển đổi số, mọi người bắt đầu tạo các hàm chung, có thể sử dụng lại để định dạng và sau đó bắt đầu sử dụng chúng trên toàn bộ địa điểm. Tuy nhiên, ngay khi người ta cần các số ở định dạng chuỗi có thể đọc được bằng máy ở một nơi khác trong chương trình, thì cần có hai biến thể: định dạng cục bộ và định dạng không cục bộ. Điều này gây ra rủi ro cao khi trộn lẫn hai hình thức chuyển đổi (đặc biệt là khi nhà phát triển và máy thử nghiệm có cài đặt ngôn ngữ mặc định tương tự như cài đặt "cố định" được sử dụng cho định dạng không phải UI, nhưng một phần của cơ sở người dùng thì không).

Phụ lục: vấn đề này có thể trở nên thực sự khó chịu trong các tình huống không rõ ràng trước nếu số sẽ được xử lý bằng máy hoặc bởi một người (hoặc cả hai) sau đó. Ví dụ, như một phần của đầu ra của tệp nhật ký. Trong những trường hợp như vậy, có lẽ tốt nhất là tuân theo tiêu chuẩn "trung tính" không sử dụng dấu phân cách ngoại trừ điểm dưới dạng dấu phân cách thập phân.


2
Và tệ hơn nữa là nhiều ngôn ngữ tạo hình hiện đại, các hàm rõ ràng / mặc định trong thư viện chuẩn bị "cục bộ hóa". Vì vậy, nếu nhà phát triển không biết hoặc quan tâm đến việc bản địa hóa, ứng dụng kết quả có thể sẽ không hoạt động thay vì chỉ xấu xí trên các hệ thống nước ngoài.
Peter Green

4
Tôi không đồng ý về điều tồi tệ như nhau. Một công cụ không tuân theo các quy ước số cục bộ trong giao diện người dùng của nó vẫn có thể sử dụng được. Một công cụ không đọc được tệp dữ liệu của chính nó hoặc không thể nói chuyện với máy chủ của nó do sự không khớp quy ước số có nhiều khả năng không thể sử dụng được.
Peter Green

5
Một giai thoại về điều này: Công cụ phân tách thập phân cho en-ZA đã thay đổi giữa Win 7 và Win 8. Các giá trị được lưu trữ cục bộ trước đó bắt đầu không thể
khử

1
@PeterGreen: một công cụ không tuân theo công ước số địa phương trong đó là giao diện người dùng có thể vẫn có thể sử dụng, hoặc nó có thể hoàn toàn không sử dụng được cho trường hợp sử dụng nhất định. Tôi sẽ rất cẩn thận khi đưa ra các giả định như vậy. Lý do tại sao rất nhiều nhà phát triển nhận được sai số nội địa hóa chính xác là như vậy - làm cho các loại giả định này.
Doc Brown

1
@DocBrown Tôi có mã kế thừa khủng khiếp nhất để duy trì các thói quen phân tích cú pháp số nguyên / float cục bộ của thư viện chuẩn. Tôi nghĩ thật công bằng khi nói rằng một chương trình được viết mà không quan tâm đến nội địa hóa khi các thói quen mặc định cho các công việc này không được bản địa hóa thể không sử dụng được cho một số trường hợp, nhưng nếu các thói quen mặc định được bản địa hóa, chương trình sẽ luôn bị hỏng ngay lúc đó thực hiện trên một máy tính mà ngôn ngữ toàn cầu không phải là tiếng Anh.
Sebastian Redl

9

Nội địa hóa đúng là khá khó khăn. Hầu hết các hệ sinh thái lập trình đều cố gắng tìm giải pháp cho việc bản địa hóa, nhưng theo kinh nghiệm của tôi, tất cả chúng đều bị phá vỡ ít nhiều. Do đó tôi sẽ đề nghị:

  • Đừng cố tự động hóa nội địa hóa. Nó sẽ không luôn luôn hoạt động. Rất khó để bạn phát hiện ra các vấn đề và gây khó chịu cho người dùng của bạn.

  • Hãy nhất quán: không trộn lẫn các ngôn ngữ khác nhau và các quy ước định dạng, ví dụ: dấu phân cách thập phân kiểu Brasil trong văn bản tiếng Anh.

  • Hoàn toàn hỗ trợ một tập hợp các địa phương nhất định. Làm việc cùng với các dịch giả của bạn để tìm ra định dạng thích hợp cho ngày và số. Bạn có thể sẽ tạo ra bộ công cụ bản địa hóa của riêng bạn, mặc dù hầu hết các vấn đề (nhưng không phải tất cả) có thể được ủy quyền cho một thư viện hiện có.

  • Thực hiện các lựa chọn định dạng đơn giản có thể định cấu hình theo từng người dùng: định dạng cho ngày và thời gian, dấu tách thập phân, tiền tệ ưa thích, Số. Điều này đặc biệt hữu ích cho khách du lịch, người nước ngoài hoặc những người khác cần kết hợp nhiều địa phương hoặc văn hóa độc lập với ngôn ngữ.


18
Ngoài ra, hãy lưu ý rằng một số lượng lớn người dùng ghét quy ước được coi là "chính xác cho địa phương của họ", coi đó là một thực hành di sản gớm ghiếc và không muốn nhóm lại, hoặc một loại nhóm khác. Vì vậy, có lẽ nên có các tùy chọn để tắt hoặc ghi đè thủ công.
R ..

2

Một cân nhắc quan trọng: Bạn nên quyết định bao nhiêu là đủ. Bởi vì nếu bạn đi xuống hố thỏ cố gắng bản địa hóa một cách hoàn hảo, nó sẽ ngày càng trở nên phức tạp.

Lấy một nhãn điển hình như "Bạn đã chọn n mục." Điều này đọc sai nếu chỉ có một mục được chọn. Giải pháp xấu xí nhưng thực dụng là viết "Bạn đã chọn n mục." Nhưng nếu bạn muốn làm điều đó một cách chính xác, bạn cần hai văn bản khác nhau tùy thuộc vào n. Nếu bạn cố gắng làm điều này ở nhiều địa phương, nó sẽ nhanh chóng trở nên thực sự phức tạp, vì các ngôn ngữ khác nhau có ngữ pháp khác nhau. Một số ngôn ngữ có cách chia khác nhau cho một, hai và nhiều mục, v.v. Vì lý do này, những người biết sẽ luôn phàn nàn rằng các khung nội địa hóa hiện tại là không đủ.

Nhưng bạn phải chọn các trận đánh của mình, và quyết định mức độ tinh vi nào là đủ. Đối với nhiều mục đích, một thư viện nội địa hóa tiêu chuẩn để định dạng số và ngày là đủ.


Điều này được giải quyết bằng ICU (MessageFormat). Hạn chế là việc áp dụng ICU trên nhiều ngôn ngữ vẫn còn yếu. Tuy nhiên, nhà phát triển vẫn cần xây dựng thông điệp theo đúng cách. Nó thực sự nhiều hơn khía cạnh kỹ thuật của nó. userguide.icu-project.org/formatparse/messages
gật đầu

Điều này cũng được giải quyết bằng hàm ngettext có sẵn rộng rãi hơn trong GNU gettext, nhưng lớp MessageFormat dường như cũng giải quyết một số vấn đề bổ sung mà ngettext không có.
hvd

2

Bạn không thể nhận thức được tất cả các cảnh báo của ngôn ngữ. Bạn đang nói về những con số, nhưng có số nhiều, giới tính, đối chiếu. Bạn cần biết họ tồn tại và dựa vào công việc rộng rãi được thực hiện bởi những người khác, đặc biệt là các dự án ICU và CLDR.

Hầu hết các ngôn ngữ hiện đại thực hiện một số hoặc tất cả các tính năng của các dự án này, nhưng ngay cả khi chúng không có, đọc về các dự án này sẽ cho bạn ý tưởng tốt về những gì cần tìm kiếm.

http://site.icu-project.org

http://cldr.unicode.org

Cập nhật

Công cụ khảo sát CLDR cung cấp quyền truy cập vào tất cả các mẫu. Điều đó sẽ chỉ cho bạn cách định dạng một số trong ngôn ngữ và khu vực nhất định. Ví dụ: tiếng Bồ Đào Nha (Bồ Đào Nha):

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

Và nếu bạn thực sự muốn kiểm tra tất cả dữ liệu (và có thể sử dụng nó), bạn có thể tải xuống CLDR ở định dạng JSON từ GitHub:

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

Thông tin thêm về tải xuống ở đây:

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


Cảm ơn về đầu vào, nhưng bây giờ tôi chủ yếu quan tâm đến các con số. :)
Machado

Chắc chắn rồi. Tôi vừa chỉnh sửa phản hồi để bao gồm một liên kết đến công cụ khảo sát, nơi bạn có thể thu hẹp tìm kiếm của mình.
gật đầu

Tôi đã cố gắng thay đổi Brazil, để kiểm tra sự khác biệt, nhưng dường như nó không cho phép trực quan hóa cho điều đó: st.unicode.org/cldr-apps/v#/pt_BR/Number_Formatted_Potypes Nếu không, công cụ này có vẻ khá tốt.
Machado

Đó là bởi vì Brazil là ngôn ngữ gốc. Công cụ khảo sát thực sự được sử dụng để thực hiện các thay đổi đối với dữ liệu CLDR, do đó, các root yêu cầu các tài khoản đặc biệt. Bạn có thể truy cập GitHub và nhận tất cả thông tin trực tiếp: github.com/unicode-cldr/cldr-numbers-modern/tree/master/main Cụ thể, Brazil có tại đây: github.com/unicode-cldr/cldr-numbers-modern blob / master / main / pt /
Re

0

Chà, trong khi tôi hài lòng với tất cả các câu trả lời ở đây, tôi không thực sự hài lòng với từng câu trả lời riêng biệt để đánh dấu một câu trả lời đúng.

Cho đến nay, đây là những gì chúng ta nên biết khi bản địa hóa các số:

Đối với con người :

  • Hàng ngàn dải phân cách không phải lúc nào cũng phân tách ở hàng ngàn. Xem trường hợp Ấn Độ trong câu hỏi;
  • Hàng ngàn và số thập phân nhân vật thay đổi văn hóa để văn hóa. Trong tiếng Đức, hàng ngàn người được phân chia bằng cách sử dụng khoảng trắng, ví dụ, trong khi bằng tiếng Anh, nó là dấu phẩy và tiếng Bồ Đào Nha là dấu chấm;
  • Chúng tôi không có thông tin nếu có sự khác biệt có liên quan giữa các ngôn ngữ từ trái sang phải và phải sang trái;
  • Cung cấp một bộ nội địa hóa được hỗ trợ cụ thể và làm cho nó rõ ràng cho người dùng của bạn;
  • Cho phép người dùng của bạn thay đổi nội địa hóa mặc định thành một trong những bản địa hóa được hỗ trợ và họ sẽ rất vui và gửi cho bạn những chiếc bánh rất biết ơn, vì bạn là một vị thần hào phóng. :);

Đối với máy tính :

  • Hãy nhớ rằng các máy không khoan dung và phải luôn nhận được cùng định dạng trong khi xê-ri hóa và khử nối tiếp một số;
  • Gắn bó với một định dạng duy nhất cho nó;
  • Sử dụng định dạng cần thiết tối thiểu có thể. Tránh hàng ngàn phân tách, số thập phân phải đủ để tuần tự hóa và khử tuần tự.

Dành cho nhà phát triển :

  • (như được đề xuất bởi @hyde bên dưới): Sử dụng thư viện hiện có để bản địa hóa;
  • Nếu bạn có thể, hãy sử dụng các trình kiểm tra gốc và chỉ định các trường hợp kiểm thử bản địa hóa / quốc tế hóa, nếu không thì tin tưởng vào thư viện;
  • Hãy nhớ rằng nội địa hóa là một vấn đề chủ yếu được giải quyết. Mỗi ngôn ngữ chính có một thư viện, bản địa hoặc bên ngoài, có thể bản địa hóa số, ngày và thời gian;

1
Mục bị thiếu: Dành cho nhà phát triển: sử dụng thư viện hiện có để bản địa hóa. Nếu bạn có thể, hãy sử dụng các trình kiểm tra gốc và chỉ định các trường hợp kiểm thử bản địa hóa / quốc tế hóa, nếu không thì tin tưởng vào thư viện.
hyde
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.