String.format for JavaScript

String.format('{1}e{0:000;1##1,#}!', -0.4567, 'H');


This is a JavaScript implementation of the .NET Framework method String.Format, which you can use for building strings with formatted numbers, formatted dates, or just concatenate strings with other objects in a convenient way (especially if you have a localized web application). If you're not familiar with the syntax of .NET format strings, I would suggest you have a look at SteveX format string reference, as this article will not explain these any futher than showing a couple of examples.

The objective of this library was to offer a formatting method as compatible as possible to the one offered by Microsoft in .NET Framework, but still keep the size of the script down. Currently the script takes less than 5 kB, excluding additional localizations. The localizations offer a culture specific formatting of numbers, regardig radix points, thousands separators, currency, and of dates, regarding the names of the months and days, time formatting etc. Most of the .NET cultures are available.


A couple of months ago I needed to format some numbers using JavaScript. Everyone who has used JavaScript knows that the formatting options using JavaScript isn't overwhelming, so I searched the net for a JavaScript implementation similar to String.Format in .NET Framework. I found some implementations, but they only offered concatenation support (basically replaced {0} with arguments). Then I examined Microsoft's own implementation included in ASP.NET AJAX, but this implementation had some drawbacks too, for example it supports the default number format strings only. That was unfortunately not enough for me, as I needed more control over the output. That is the reason to why I decided to make my own implementation. This is basically a JavaScript implementation of the String.Format method in .NET Framework. It is not completely compatible with the MS one, but you will probably not notice any difference. I've optimized the performance of the script, and will perform fairly well, even with long format strings (string concatenation is definitely not the strong point in JavaScript).

How does it work?

Before you can use the script you have to load it somewhere on your page:

<script type="text/javascript" src="stringformat.js"></script>

Then it is up to you to decide how to use it. There are numerous ways of using this formatting library, but here are the two most basic ones:

String.format([full format string], [arguments...]);

// or:

[date|number].format([partial format string]);

Note that if you have another script occupying String.format, Date.prototype.format or Number.prototype.format, those methods will not be replaced. However you may still use the methods of this library by using the internal formatting methods, which are called '__Format' instead of just 'format'.

The current culture is automatically determined by looking at the browser language settings (as far it is possible, the culture support is still very limited, but is easy to extend). If no supporting culture is present, US English is used as default. However you may still override the automatically determination by using the method sffjs.setCulture(<culture>).


// Object path
String.format("Welcome back, {username}!", 
{ id: 3, username: "JohnDoe" });
// Result: "Welcome back, JohnDoe!"

// Date/time formatting
String.format("The time is now {0:t}.", 
new Date(2009, 5, 1, 13, 22));
// Result: "The time is now 01:22 PM."

// Date/time formatting (without using a full format string)
var d = new Date();
d.format("hh:mm:ss tt");
// Result: "02:28:06 PM"

// Custom number format string
String.format("Please call me at {0:+##0 (0) 000-00 00}.", 
// Result: "Please call me at +46 (0) 111-11 11."

// Another custom number format string
String.format("The last year result was {0:+$#,0.00;" + 
"-$#,0.00;0}.", -5543.346);
// Result: "The last year result was -$5,543.35."

// Alignment
String.format("|{0,10:PI=0.00}|", Math.PI);
// Result: "|   PI=3.14|"

// Rounding
String.format("1/3 ~ {0:0.00}", 1/3);
// Result: "1/3 ~ 0.33"

// Boolean values
String.format("{0:true;;false}", 0);
// Result: "false"

// Explicitly specified localization
// (note that you have to include the .js file for used cultures)
String.format("{0:#,0.0}", 3641.667);
// Result: "3,641.7"

String.format("{0:#,0.0}", 3641.667);
// Result: "3 641,7"

As you can see the decimal point and thousands separator is chosen depending on the localization set. The localization is automatically detected using the browser language settings, however the matching culture file is currently not automatically loaded. If the browser language is not supported by the script the invriant culture is selected as fallback.

Extending the format string support

Format strings (the code after the colon inside the curly braces) are supported for dates and numbers – for other data types the format string part is ignored. If you want to extend the format string support for your own classes, please add the method __Format(format) to your object. The method will be invoked as soon as an instance of your class appears as a parameter to the format method. The parameter is the format string portion of the curly brace content and the method must return a string. Example:

function MyClass(input) {
    this.member = input;
    this.__Format = function (format) {
        return this.member.__Format(format);

Note that your objects may still be used as arguments to the String.format method even if the __Format method is not existing. toString() will then be used to get a string representation of the object.


You may also wish to take a look at SteveX format string reference:


In Brief


View on GitHub


This script is released under the zlib license. Read more


2009-06-05: Initial release (v. 1.0)
2009-12-14: Date formatting bug fix (v. 1.01)
2009-12-20: Ms-PL replaced by the zlib license (v. 1.02)
2012-10-01: Fixed formatting bug when non-placeholder chars were included after decimal point (v. 1.03)
2013-04-01: Better support for standard number format strings + support for paths as complement to indexes (v. 1.04)
2013-04-07: Separated cultures from core script, added more cultures (v. 1.05)
2013-04-08: Text alignment was reversed (v. 1.06)
2013-06-14: No default culture was set on startup (v. 1.07)
2013-07-16: Crash without date format string + not all string literals were handled (v. 1.08)
2014-01-26: Renamed namespace from msf to sffjs (v. 1.09)
2015-10-09: Improved handling of escaped braces (v. 1.10)
2016-07-31: Improved handling of escaped '%' and ';' + improved support for thousand scaling (v. 1.11)
2017-02-22: Fixed infinity loop with G specifier (v. 1.12)
2017-05-17: Fixed incorrect formatting of 12-hour clock (v. 1.13)
2018-09-09: Replaced loop (v. 1.14)
2019-01-27: Improved support for large and small numbers + TS typing + Fixed broken G and E specifiers (v. 1.15.0)
2019-04-05: Improved support for custom date format strings (v. 1.16.0)
2019-07-22: Fixed incorrect formatting of numbers ending with a zero (v. 1.16.1)
2020-10-18: Added getCulture() method (v. 1.17.0)

| More

Read more

SteveX format string reference
MSDN Format String Documentation

Copyright © Daniel Mester Pirttijärvi 2018
All rights reserved