Translating Values and Behaviors

In the process of globalizing your .NET application, you may notice a number of aspects that are handled differently compared to building an application that is devoid of globalization, including how dates are represented and how currencies are shown. This section looks at some of these issues.

Understanding Differences in Dates

Different cultures specify dates and time very differently. Consider the following date as an example:

08/11/2008

Is this date August 11, 2008, or is it November 8, 2008? It should be the job of the business logic layer or the presentation layer to convert all date and times for use by the end user. To avoid interpretation errors, always use the same culture (or invariant culture) when storing values, such as dates and times, in a database or other data store.

Setting the culture at the server level in ASP.NET or within a Windows Forms application, as shown in the earlier examples, enables your .NET application to make these conversions for you. You can also simply assign a new culture to the thread in which the code is running. Close out the ASP.NET solution you were looking at in the preceding section and return to the ProVB2012_Localization project. Now consider the following code, which can be called from the Button_Click_1 event handler. Note that this Sub is dependent on the Imports statements (code file: MainWindow .xaml.vb):

Imports System.Globalization
Imports System.Threading
        
Private Sub DisplayCalendarByCulture()
    Dim dt As DateTime = New DateTime(2012, 9, 12, 13, 5, 1, 10)        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("pt-br")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("es-mx")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("es-es")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("ru-RU")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("fi-FI")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("ar-SA")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("am-ET")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("as-IN")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("th-TH")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("zh-cn")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("zh-tw")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("ko-kr")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("zh-hk")
    TextBoxResult.Text +=
      Thread.CurrentThread.CurrentCulture.EnglishName & " : " & _
      dt.ToString() & Environment.NewLine
End Sub

Using the ProVB2012_Localization test form again, you can test this code. The code snippet captures the current date/time for output, but does so while referencing a dozen or more different cultures, one for each copy output to the screen. The date/time construction used by the defined culture is written to the TextBox control. The result from this code operation is presented in Figure 15.6.

Figure 15.6 Different Date/Time formats by culture

15.6

Clearly, the formats used to represent a date/time value can be dramatically different between cultures—some, such as Saudi Arabia (ar-SA) and Thailand, (th-TH) use entirely different calendar baselines.

Differences in Numbers and Currencies

In addition to date/time values, numbers are displayed quite differently from one culture to the next. How can a number be represented differently in different cultures? Well, it has less to do with the actual number (although certain cultures use different number symbols) and more to do with how the number separators are used for decimals or for showing amounts such as thousands, millions, and more. For instance, in the English culture of the United States (en-US), numbers are represented in the following fashion:

5,123,456.00

From this example, you can see that the en-US culture uses a comma as a separator for thousands and a period for signifying the start of any decimals that might appear after the number is presented. It is quite different when working with other cultures. The following snippet shows an example of representing numbers in other cultures (code file: MainWindow.xaml.vb):

Private Sub Numbers()
    Dim myNumber As Double = 5123456.0
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
    TextBoxResult.Text += Thread.CurrentThread.CurrentCulture.EnglishName &
       " : " & myNumber.ToString("n") & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("vi-VN")
    TextBoxResult.Text += Thread.CurrentThread.CurrentCulture.EnglishName &
       " : " & myNumber.ToString("n") & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("fi-FI")
    TextBoxResult.Text += Thread.CurrentThread.CurrentCulture.EnglishName &
       " : " & myNumber.ToString("n") & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("fr-CH")
    TextBoxResult.Text += Thread.CurrentThread.CurrentCulture.EnglishName &
       " : " & myNumber.ToString("n") & Environment.NewLine
        
End Sub

Adding this code to your project and running it from the click event produces the results shown in Figure 15.7.

Figure 15.7 Different numeric formats across cultures

15.7

As you can see, cultures show numbers in numerous different formats. The second culture listed in the figure, vi-VN (Vietnamese in Vietnam), constructs a number exactly the opposite from the way it is constructed in en-US. The Vietnamese culture uses periods for the thousand separators and a comma for signifying decimals, a somewhat common format around the world. Finnish uses spaces for the thousand separators and a comma for the decimal separator, whereas the French-speaking Swiss use an apostrophe for separating thousands, and a period for the decimal separator. This demonstrates that not only do you need to consider dates and language constructs, but that it is also important to “translate” numbers to the proper format so that users of your application can properly understand the numbers represented.

Another scenario in which you represent numbers is when working with currencies. It is one thing to convert currencies so that end users understand the proper value of an item; it is another to translate the construction of the currency just as you would a basic number.

Each culture has a distinct currency symbol used to signify that a number represented is an actual currency value. For instance, the en-US culture represents currency in the following format:

$5,123,456.00

The en-US culture uses a U.S. dollar symbol ($), and the location of this symbol is just as important as the symbol itself. For en-US, the $ symbol directly precedes the currency value (with no space in between the symbol and the first character of the number). Other cultures use different symbols to represent currency and often place those currency symbols in different locations.

Create another Sub that can be called from the button's click event handler, and this time format the same numbers using the built-in .NET currency formatting shown here (code file: MainWindow.xaml.vb):

Private Sub Currency()
    Dim myNumber As Double = 5123456.0
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
    TextBoxResult.Text += Thread.CurrentThread.CurrentCulture.EnglishName &
       " : " & myNumber.ToString("c") & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("vi-VN")
    TextBoxResult.Text += Thread.CurrentThread.CurrentCulture.EnglishName &
           " : " & myNumber.ToString("c") & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("fi-FI")
    TextBoxResult.Text += Thread.CurrentThread.CurrentCulture.EnglishName &
       " : " & myNumber.ToString("c") & Environment.NewLine
        
    Thread.CurrentThread.CurrentCulture = New CultureInfo("fr-CH")
    TextBoxResult.Text += Thread.CurrentThread.CurrentCulture.EnglishName &
       " : " & myNumber.ToString("c") & Environment.NewLine
End Sub

Executing this code displays the output shown in Figure 15.8.

Figure 15.8 Formatting currency across cultures

15.8

Not only are the numbers constructed quite differently from one another, but the currency symbol and the location of the symbol in regard to the number are quite different as well.

Note that when you are using currencies on an ASP.NET page and you have provided an automatic culture setting for the page as a whole (such as setting the culture in the @Page directive), you need to specify a specific culture for the currency that is the same in all cases. Unlike dates, for which the differences are primarily display oriented, with a currency there is an expectation of value conversion. Thus, reformatting a currency can cause expensive errors unless you are actually doing a currency conversion.

For instance, if you are specifying a U.S. dollar currency value in your data, you do not want your ASP.NET page to display that value as something else (for example, the euro) based on translating the remainder of the page information to another language. Of course, if you actually performed a currency conversion and showed the appropriate euro value along with the culture specification of the currency, that makes sense and is the best solution.

Therefore, if you are using an automatic culture setting on your ASP.NET page and you are not converting the currency, you should perform something similar to the following code for currency values:

Dim myNumber As Double = 5123456.00
Dim usCurr As CultureInfo = New CultureInfo("en-US")
Response.Write(myNumber.ToString("c", usCurr))

Understanding Differences in Sorting

You have learned to translate textual values and alter the construction of the numbers, date/time values, currencies, and more when you are globalizing an application. You should also take care when applying culture settings to some of the programmatic behaviors that you establish for values in your applications. One operation that can change based upon the culture setting applied is how .NET sorts strings. You might think that all cultures sort strings in the same way (and generally they do), but sometimes differences exist. For example, the following snippet shows a sorting operation occurring in the en-US culture (code file: MainWindow.xaml.vb):

Private Sub Sorting()
    Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
    'Thread.CurrentThread.CurrentCulture = New CultureInfo("fi-FI")
        
    Dim myList As List(Of String) = New List(Of String)
        
    myList.Add("Washington D.C.")
    myList.Add("Helsinki")
    myList.Add("Moscow")
    myList.Add("Warsaw")
    myList.Add("Vienna")
    myList.Add("Tokyo")
        
    myList.Sort()
        
    For Each item As String In myList
        TextBoxResult.Text += item.ToString() & Environment.NewLine
    Next
End Sub

For this example to work, you have to reference the System.Collections and the System.Collections.Generic namespaces, because this example makes use of the List(Of String) object.

In this example, a generic list of capitals from various countries of the world is created in random order. Then the Sort method of the generic List(Of String) object is invoked. This sorting operation sorts the strings according to how sorting is done for the defined culture in which the application thread is running. The preceding code shows the sorting as it is done for the en-US culture. The result of this operation when used within the ProVB2012_Localization form is shown in Figure 15.9.

Figure 15.9 Typical sorting in English

15.9

This is pretty much what you would expect. Now, however, change the previous example so that the culture is set to the Finnish culture. Do this by uncommenting the second line of the Sub Sorting and commenting out the first line of the Sub Sorting which sets the “en-US” culture settings, in the preceding snippet.

If you run the same bit of code under the Finnish culture setting, you get the results presented in Figure 15.10.

Figure 15.10 Finnish cultural setting impact on sorting

15.10

Comparing the Finnish culture sorting shown in Figure 15.10 and the U.S. English culture sorting done in Figure 15.9, you can see that the city of Vienna is in a different place in the Finnish version. This is because in the Finnish language, there is no difference between the letter V and the letter W. Therefore, if you are sorting using the Finnish culture setting, Vi comes after Wa, and thus Vienna appears last in the list of strings in the sorting operation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset