Saturday, February 13, 2010

Formatting dates in JavaScript

In most ways JavaScript is a pretty bare-bones language/development environment. Sure there are libraries like JQuery, MooTools, Dojo Toolkit etc., but there's nothing like Java's or C#'s accompanying standard libraries. So what's a programmer to do?

When you are starting out using JavaScript, probably one of the first areas where you'll feel this lack of standard libraries is in formatting dates. Every time you want to format dates into a presentable string, you have to roll your own solution. Well, given below is my solution to the problem (use the horizontal scrollbar to see the full code). JA_DateFormat(...) lets you format Date objects just by specifying a simple string. I saw the basic idea of using regular expressions to do global substitutions somewhere on the 'Net (couldn't find the reference), so I can't claim full credit for this solution:

function JA_FormatDate(dateFormat, date) {
    if (arguments.length < 1) throw new Error(1, "At least one argument required");
    if (arguments.length < 2) date = new Date(); //Default behaviour: format current time
    return dateFormat.replace(/(yyyy|yy|mmmm|mmm|mm|dddd|ddd|dd|hh|h|nn|n|ss|s|a\/?p)/gi,
        function($1) {
            switch ($1.toLowerCase()) {
                case 'yyyy': return date.getFullYear();
                case 'yy': return JA_PadNumber(date.getFullYear() % 100);
                case 'mmmm': return JA_MONTH_NAMES[date.getMonth()];
                case 'mmm': return JA_MONTH_NAMES[date.getMonth()].substr(0, 3);
                case 'mm': return JA_PadNumber(date.getMonth() + 1);
                case 'dddd': return JA_DAY_NAMES[date.getDay()];
                case 'ddd': return JA_DAY_NAMES[date.getDay()].substr(0, 3);
                case 'dd': return JA_PadNumber(date.getDate());
                case 'n': return date.getMinutes();
                case 'nn': return JA_PadNumber(date.getMinutes());
                case 's': return date.getSeconds();
                case 'ss': return JA_PadNumber(date.getSeconds());
                case 'ap':
                case 'a/p': return date.getHours() < 12 ? 'am' : 'pm';
            }
            switch ($1) {
                case 'HH': return JA_PadNumber(date.getHours());
                case 'H': return date.getHours();
                case 'hh':   return JA_PadNumber((h = date.getHours() % 12) ? h : 12);
                case 'h': return (h = date.getHours() % 12) ? h : 12;
            }
        }
    );
}

function JA_PadNumber(number, padLength, padWith) {
    var padsRequired;
    var retVal = "";
    if (arguments.length < 2) padLength = 2; //default
    if (arguments.length < 3) padWith = "0"; //default
    with (Math) {
        if (0 == number) padsRequired = padLength - 1;
        else padsRequired = padLength - floor(log(number) / log(10)) - 1;
    }
    for (var i = 0; i < padsRequired; ++i) retVal += padWith;
    return retVal += number;
}
The code (once you see it written down) is very simple, so just play with it to get a feel for it. Note that you can either call JA_FormatDate(...) with a Date object, or if you call it with just one argument it will create and use the current date. For example, calling JA_FormatDate("dd mmm yyy HH:mm:ss") will return something like 09 Feb 2010 14:35:20. Function JA_PadNumber(...) above is an assisting function that is used to 0-pad numbers (it can be use for padding with spaces or other characters too).
Bookmark and Share

No comments:

Post a Comment