JsWorld
Features
1. Clean separation between formatting logic and locale data
- A powerful JavaScript engine provides formatting and parsing of numbers, money and dates/times;
- Loadable JavaScript / JSON / properties describe the formatting rules for the available locales.
2. Use of POSIX-style locale properties
Care is taken to keep things standard and unsurprising. To describe the formatting conventions of the various locales JsWorld follows the POSIX specification, which is well known to OS and systems programmers.
Formatting | POSIX specification |
---|---|
Numeric | LC_NUMERIC |
Monetary | LC_MONETARY |
Date/time | LC_TIME |
If you open a locale definition file from the locales/js/
directory, you'll see a JavaScript object with the various POSIX LC_NUMERIC,
LC_MONETARY and LC_TIME properties. Here is the file storing the properties
for the French locale:
locales/js/fr_FR.js
if(typeof POSIX_LC == "undefined") var POSIX_LC = {}; POSIX_LC.fr_FR = { "decimal_point" : ",", "thousands_sep" : "\u00a0", "grouping" : "3", "abday" : ["dim.","lun.","mar.", "mer.","jeu.","ven.", "sam."], "day" : ["dimanche","lundi","mardi", "mercredi","jeudi","vendredi", "samedi"], "abmon" : ["janv.","f\u00e9vr.","mars", "avr.","mai","juin", "juil.","ao\u00fbt","sept.", "oct.","nov.","d\u00e9c."], "mon" : ["janvier","f\u00e9vrier","mars", "avril","mai","juin", "juillet","ao\u00fbt","septembre", "octobre","novembre","d\u00e9cembre"], "d_fmt" : "%d/%m/%y", "t_fmt" : "%H:%M:%S", "d_t_fmt" : "%e %B %Y %H:%M:%S %Z", "am_pm" : ["AM","PM"], "int_curr_symbol" : "EUR ", "currency_symbol" : "\u20ac", "mon_decimal_point" : ",", "mon_thousands_sep" : "\u00a0", "mon_grouping" : "3", "positive_sign" : "", "negative_sign" : "-", "int_frac_digits" : 2, "frac_digits" : 2, "p_cs_precedes" : 0, "n_cs_precedes" : 0, "p_sep_by_space" : 1, "n_sep_by_space" : 1, "p_sign_posn" : 1, "n_sign_posn" : 1, "int_p_cs_precedes" : 0, "int_n_cs_precedes" : 0, "int_p_sep_by_space" : 1, "int_n_sep_by_space" : 1, "int_p_sign_posn" : 1, "int_n_sign_posn" : 1 };
Note that all non-ASCII characters have been replaced with the appropriate Unicode escape sequences.
The locale definition is used to construct a jsworld.Locale
object which is then used to create the corresponding formatting
or parsing object.
// Create a new locale object from the fr_FR locale data var lc = new jsworld.Locale(POSIX.fr_FR); // Print the current date in French var formatter = new jsworld.DateTimeFormatter(lc); document.writeln(formatter.formatDate(new Date())); // Print the current time in French document.write(formatter.formatTime(new Date()));
The meaning of the individual locale properties is described in the corresponding POSIX specifications (see LC_NUMERIC, LC_MONETARY and LC_TIME) as well as in JsWorld's API docs.
3. Locale data formats
You can choose between three locale definition formats, depending on the type of your application.
Format | File location | Suitable for |
---|---|---|
JavaScript | locales/js/ | Static inclusion in HTML pages via <script> tag |
JSON | locales/json/ | Dynamic loading via XMLHTTPRequest |
Mozilla properties | locales/mozilla/ | Mozilla XULRunner applications |
3.1 JavaScript
For simple web applications you can use the regular JavaScript
files in the locales/js/
directory. Use a <script> tag to
include them, which places an object "POSIX_LC.<locale_code>
"
into your JavaScript namespace. The namespacing is done in way which allows
you to include multiple locale definitions, without causing clashes.
<!-- Include the JsWorld formatting classes --> <script type="text/javascript" src="JsWorld.js"></script> <!-- Include the en_US locale data --> <script type="text/javascript" src="locales/js/en_US.js"></script> <!-- Include the de_DE (German) locale data --> <script type="text/javascript" src="locales/js/de_DE.js"></script> <script> // Create formatter for US locale var usLocale = new jsworld.Locale(POSIX_LC.en_US); var usNumericFormatter = new jsworld.NumericFormatter(usLocale); // Create formatter for German locale var germanLocale = new jsworld.Locale(POSIX_LC.de_DE); var germanNumericFormatter = new jsworld.NumericFormatter(germanLocale); // Show number in US locale alert(usNumericFormatter(25000.10)); // Show number in German locale alert(germanNumericFormatter(74999.90)); </script>
You also have the option to include the definitions of all available
locales (over 300) by pointing to the locales/js/POSIX_LC.js
file. This, however, will consume a lot more memory and bandwidth as the
aggregate data for all locales takes up about 500KB.
<!-- Include data for all available locales --> <script type="text/javascript" src="locales/js/POSIX_LC.js"></script>
3.2 JSON
For interactive (Ajax) web applications use the locale definitions
in the locales/json/
directory. They are
JSON-encoded, making them
suitable for dynamic loading with
XMLHTTPRequest.
<!-- Include the JsWorld formatting classes --> <script type="text/javascript" src="JsWorld.js"></script> <script> // Example assumes Firefox 3.5! // The locale data file (e.g. Canadian English) in JSON format var url = "http://my-site.com/jsworld/locales/json/en_CA.json"; // Make request var req = new XMLHttpRequest(); req.open("GET", url, true); req.onreadystatechange = function (aEvt) { if (req.readyState == 4) { if(req.status == 200) { // Parse response JSON var localeData = JSON.parse(req.responseText); // Create new formatter with received locale properties var lc = new jsworld.Locale(localeData); var dateTimeFormatter = new jsworld.DateTimeFormatter(lc); } else { alert("Error loading locale data"); } } }; req.send(null); </script>
3.3 Mozilla property files
The locale definitions are also avilable as
property files,
a format XULRunner
applications and Firefox add-ons.
These are located in the locales/mozilla/
directory.
Here is an example how to import all items from a Mozilla property file and pack them into a single JavaScript object:
// XPCOM shorthands const Cc = Components.classes; const Ci = Components.interfaces; // Location of the properties file var stringBundleURI = "chrome://app/locale/en_US.properties"; // Open properties file var stringService = Cc["@mozilla.org/intl/stringbundle;1"] .getService(Ci.nsIStringBundleService); var sb = stringService.createBundle(stringBundleURI); // Retrieve locale data var localeProps = {}; var propertyList = sb.getSimpleEnumeration(); while (propertyList.hasMoreElements()) { var prop = propertyList.getNext().QueryInterface(Ci.nsIPropertyElement); localeProps[prop.key] = prop.value; } // Create locale object from the raw properties var lc = new jsworld.Locale(localeProps); // Create the corresponding formatters var nf = new jsworld.NumericFormatter(lc); var mf = new jsworld.MonetaryFormatter(lc); var dtf = new jsworld.DateTimeFormatter(lc);
4. Exception handling
The formatting / parsing classes will raise an exception if something goes wrong, e.g. on:
- Invalid or missing locale properties
- Invalid input to the format method
You can handle these error conditions by using a try-catch clause:
try { var lc = new jsworld.Locale(POSIX_LC.en_GB); var mf = new jsworld.MonetaryFormatter(lc); // attempt to format an invalid amount mf.format("abc"); } catch (error) { alert(error); }
5. API documentation
Auto-generated API documentation is provided with the package as well as online: