Technical Notes
Localization
NOTE: This section concentrates on locale issues in the code.
When you start an application, the system sets a default locale that the application uses to determine what decimal points and thousands separators should look like. You can, however, change the locale at runtime. For example, you might start off using one locale where the decimal point is a period and the thousands separator is a comma, read in a set of values with embedded decimal points and commas interpreted in this way, switch to a new locale where the meanings are reversed, then print out the numbers with the new punctuation meanings.
 
#include <rw/dec64.h>
 
// Create two distinct user locales.
RWLocaleSnapshot GermanLocale("de"), USALocale("C");
RWLocale::global(&USALocale); //1
// redundant in USA
RWDecimal64 dollars = "2,368.2096";
cout << dollars;
// 2368.2096
 
RWLocale::global(&GermanLocale); //2
cout << dollars;
// 2368,2096
Changes in locale are specified using the global() method of the RWLocale class of the Essential Tools Module, as shown in lines //1 and //2. This method changes the interpretation of commas and decimal points during the input and output parsing of strings in the RWDecimal and RWDecimalPortable classes. The setLocale method should be called only if the default locale, initialized at the start of a program, is not desired.
Note that picture objects of type RWDecimalFormat do not change their meanings when you change locales, nor is a picture object interpreted properly at construction time if the wrong locale is set. In the following example, the picture objects would not work as expected if the German picture were created while the USA locale was active:
 
// This will not work properly!
RWLocale::global(&USALocale);
RWDecimalFormat GermanFormat1("DM__.___,__");
 
//This is the correct way:
RWLocale::global(&GermanLocale);
RWDecimalFormat GermanFormat2("DM_l_,_");
The following example shows another way to output currency values according to different locales, using picture objects instead of changing the global locale directly:
 
RWDecimalFormat USFormat, DEFormat;
RWLocaleSnapshot GermanLocale("german"), USALocale("C");
 
USFormat.setLocale(USALocale); // global locale is unaffected
DEFormat.setLocale(GermanLocale); // by these statements
 
RWDecimal64 dollars = "2,368.2096"; // assumes "C" locale
// is active
cout << "US Format: " << USFormat(dollars) << endl;
// 2,368.2096
 
cout << "German Format: " << DEFormat(dollars) << endl;
// 2.368,2096
Also note that when you initialize an RWDecimal object with a string containing embedded decimal points and commas, the punctuation marks are interpreted according to the currently active locale. For example:
 
// In the USA, the default locale uses "." as a decimal point.
RWDecimal64 dollars = "2,368.2096";
cout << dollars;
// 2368.2096
 
// The USA locale doesn't understand numbers in German format.
RWDecimal64 marks = "2.368,2096";
cout << marks;
// 2.3682096
 
 
// Switch to the German locale to read in numbers with German
// punctuation.
RWLocale::global(&GermanLocale);
RWDecimal64 marks2 = "2.368,2096";
cout << marks2;
// 2368,2096
If you print out numbers with embedded decimal points and commas, the punctuation marks is interpreted according to the currently active locale, as illustrated in the first example.
For more information on what you can do with locales, see the documentation for RWLocaleSnapshot in the SourcePro API Reference Guide. For instance, this code prints out a number with the currency symbol of the currently active locale:
 
RWLocaleSnapshot currentLocale("");
RWDecimalFormat format("__.__");
RWCString currency_sym = currentLocale.currency_symbol_;
format.setNearLeftText(currency_sym.data());
 
RWDecimal64 x = "3.85";
cout << format(x);
// $ 3.85 in USA.
// DM 3.85 in Germany.