sprintf for JavaScript
Avoid writing formatting functions in JavaScript by grabbing yourself a decent sprintf implementation - handling padding, truncation, floating-point numbers, left/right alignment and re-ordered arguments.
You can download sprintf for JavaScript, available under the Create Commons Attribution License. Now license free (use it where/when/how you like.)
The version I’ve written is based strongly on Perl’s sprintf implementation, allowing argument reordering to help with internationalisation (i18n). Some overly simplistic examples follow, leaving room for obvious improvements like:
- letting the user specify their locale as a preference
- set default locale based on visitor demographics
- use locale-specific message-bundles with a fall-back to the default locale
On with the examples:
var locale = "es";
var messages = {
en: "I am %d years and %d months old.",
es: "Tengo %2$d meses y %1$d años.",
};
var message = sprintf(messages[locale], 31, 7);
You could also use it for
var date = new Date();
var dateFormats = [
/* ISO-8601: */ "%04d-%02d-%02d %02d:%02d:%02d",
/* British: */ "%3$02d/%2$02d/%1$02d",
/* U.S.: */ "%2$02d/%3$02d/%1$02d",
];
// for example only: choose random date format
var dateFormat = dateFormats[(3 * Math.random()) >>> 0];
var formatted = sprintf(
dateFormat,
date.getFullYear(),
date.getMonth() + 1,
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds()
);
alert(formatted);
The Perl documentation has more examples in the ”order of arguments section”. Note: this implementation allows the precision of a number to be set from a specific argument (using e.g. ”%.*3$f”), which the perldocs (perldoc -f sprintf
) say hasn’t been implemented yet.
I haven’t (re)written any documentation for it, but you should be able to use Firebug (or the javascript:
protocol) to try out sprintf
on this page, and you can also check out the test page for sprintf for more input/output samples.
As usual, writing test-cases uncovered a couple of browser-dependent issues. Safari has some bizarre behaviour with Maths.abs(0).toFixed(6)
resulting in "0.0000-0"
instead of "0.000000"
. Another issue I came across is that 0.5
rounds to 0
or 1
depending on browser (worded differently: numbers are rounded off inconsistently across browsers.)
Dependencies
On modern browsers, there are no dependencies. But to run sprintf
on older browsers you’ll need to patch the Number
and String
objects. Number
needs toFixed
, toExponential
and toPrecision
methods, while String
needs a replace
method capable of using functions in the replacement parameter.