<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Flagrant Badassery &#187; Code Challenge</title>
	<atom:link href="http://blog.stevenlevithan.com/category/code-challenge/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.stevenlevithan.com</link>
	<description>A JavaScript and regular expression centric blog</description>
	<pubDate>Sat, 09 Aug 2008 15:09:54 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Code Challenge: Change Dispenser</title>
		<link>http://blog.stevenlevithan.com/archives/change-dispenser</link>
		<comments>http://blog.stevenlevithan.com/archives/change-dispenser#comments</comments>
		<pubDate>Fri, 20 Jun 2008 18:00:16 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
		
		<category><![CDATA[Code Challenge]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/?p=79</guid>
		<description><![CDATA[I recently encountered a brain teaser that asked to take an amount of change and return the equivalent in dollars and coins.

Here's the five-minute solution I first came up with.

function makeChange (money) {
    var i, num,
        output = [],
       [...]]]></description>
			<content:encoded><![CDATA[<p>I recently encountered a brain teaser that asked to take an amount of change and return the equivalent in dollars and coins.</p>

<p>Here's the five-minute solution I first came up with.</p>

<pre class="code">function makeChange (money) {
    var i, num,
        output = [],
        coins  = [
            [100, "dollar",  "dollars" ],
            [25,  "quarter", "quarters"],
            [10,  "dime",    "dimes"   ],
            [5,   "nickel",  "nickels" ],
            [1,   "penny",   "pennies" ]
        ];
    money = money * 100; // avoid float precision issues
    for (i = 0; i < coins.length; i++) {
        num = Math.floor(money / coins[i][0]);
        money -= num * coins[i][0];
        if (num) {
            output.push(num + " " + coins[i][num > 1 ? 2 : 1]);
        }
    }
    return output.join(", ");
}

makeChange(0.37); <span class="comment">// "1 quarter, 1 dime, 2 pennies"</span></pre>

<p>I feel like I'm missing something, though. <span style="font-size:125%;"><em>How would you improve this code to make it shorter, faster, or otherwise better?</em></span></p>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/change-dispenser/feed</wfw:commentRss>
		</item>
		<item>
		<title>Regex Day Contest</title>
		<link>http://blog.stevenlevithan.com/archives/regexday-2008</link>
		<comments>http://blog.stevenlevithan.com/archives/regexday-2008#comments</comments>
		<pubDate>Thu, 29 May 2008 09:24:47 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
		
		<category><![CDATA[Code Challenge]]></category>

		<category><![CDATA[Regular Expressions]]></category>

		<category><![CDATA[contest]]></category>

		<category><![CDATA[schwag]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/regexday-2008</guid>
		<description><![CDATA[A few months ago Ben Nadel (a regex fan and prominent ColdFusion blogger) asked me if I was interested in promoting his idea for a "National Regular Expression Day," where he'd give away some shirts and books and basically just have some fun with regex evangelism. Well, Ben finally kicked if off, assigning the honor [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago <a href="http://www.bennadel.com">Ben Nadel</a> (a regex fan and prominent ColdFusion blogger) asked me if I was interested in promoting his idea for a "National Regular Expression Day," where he'd give away some shirts and books and basically just have some fun with regex evangelism. Well, Ben finally <strong><a href="http://www.bennadel.com/index.cfm?dax=blog:1243.view">kicked if off</a></strong>, assigning the honor to June 1st, 2008. Make sure to check out his blog post, because by simply posting a comment noting your preferred item from his list before June 2nd, you're entered to win it.</p>

<p>I'm all for regex evangelism, so I figured I'd get in on the action with my own regex contest where you can win the best commercial regex products I know of, worth up to $150! The rules are a little different here though. For one thing, you've got more time to enter &mdash; I'll keep this open until the end of Friday, June 13. Second, this isn't a lottery. The rules are still pretty simple, though.</p>

<ul>
	<li>Write (or link to) some kind of creative regex content in a comment on this blog post.</li>
	<li>It has to be something new, specifically for this contest.</li>
	<li>Enter by unlucky Friday, June 13.</li>
	<li>When submitting your entry, make sure to include an email address where I can reach you in the email field (it won't be visible to others, and I'll only use it to contact you about this contest).</li>
	<li>You can submit multiple entries, but each will be judged on its own and one person cannot win more than one award.</li>
	<li>I get to be the judge and jury.</li>
</ul>

<p>As for what kind of content is eligible, well, pretty much anything as long as it's regex related. You can write a regex joke (preferably not ending with the punchline "now they have two problems"), post a regex article somewhere, create a regex comic strip, share your favorite regex you've written, design a regex superhero, create a regex game, tell a story about how regexes saved the day, link to a blog post you've written about Regular Expression Day, or whatever you can come up with. Go nuts.</p>

<p>Here's what the winners can choose from. If you win first or second place but none of the prizes in that tier interest you, you can pick <strong>two</strong> items from a lower level.</p>

<ul>
	<li><strong>First Prize:</strong>
		<ul>
			<li><a href="http://www.powergrep.com/cgi-bin/affref.pl?aff=SteveL">PowerGREP</a></li>
		</ul>
	</li>
	<li><strong>Second Prize:</strong>
		<ul>
			<li><a href="http://www.regexbuddy.com/cgi-bin/affref.pl?aff=SteveL">RegexBuddy</a></li>
			<li><a href="http://www.amazon.com/dp/0596528124/?tag=slfb-20">Mastering Regular Expressions, 3rd Edition</a></li>
			<li><a href="http://www.thinkgeek.com/tshirts/itdepartment/57f0/">Shakespeare Regular Expression Shirt</a></li>
			<li><a href="http://store.xkcd.com">XKCD Regular Expressions Shirt</a>, based on <a href="http://xkcd.com/208/">comic 208</a></li>
			<li><a href="http://www.zazzle.com/168497609810962553">Regular Expressions Quick Reference Mug</a></li>
			<li><a href="http://www.amazon.com/dp/1411677609/?tag=slfb-20">Regular Expressions: The Complete Tutorial</a></li>
			<li><a href="http://silveragesoftware.com/search-replace-text-tool.html">HandyFile Find and Replace Text Workbench</a> &mdash; I haven't tried this</li>
		</ul>
	</li>
	<li><strong>Third Prize:</strong>
		<ul>
			<li><a href="http://www.amazon.com/dp/0672325667/?tag=slfb-20">Regular Expressions in 10 Minutes</a></li>
			<li><a href="http://www.amazon.com/dp/0596514271/?tag=slfb-20">Regular Expression Pocket Reference, 2nd Edition</a></li>
			<li><a href="http://www.amazon.com/dp/0596006012/?tag=slfb-20">Oracle Regular Expressions Pocket Reference</a></li>
			<li><a href="http://www.amazon.com/dp/0596003528/?tag=slfb-20">sed and awk Pocket Reference, 2nd Edition</a></li>
		</ul>
	</li>
</ul>

<p>Good luck, and I hope you have fun with this. <img src="http://blog.stevenlevithan.com/wp-includes/images/smilies/icon_smile.gif" alt="smile" /> (Once again, make sure to check out <a href="http://www.bennadel.com/index.cfm?dax=blog:1243.view">Ben's post</a> that started this.)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/regexday-2008/feed</wfw:commentRss>
		</item>
		<item>
		<title>JavaScript Roman Numeral Converter</title>
		<link>http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter</link>
		<comments>http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter#comments</comments>
		<pubDate>Sun, 16 Mar 2008 04:59:51 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
		
		<category><![CDATA[Code Challenge]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter</guid>
		<description><![CDATA[While looking for something quick to do during a brief internet outage, I wrote some code to convert to and from Roman numerals. Once things were back up I searched for equivalent code, but only found stuff that was multiple pages long, limited the range of what it could convert, or both. I figured I [...]]]></description>
			<content:encoded><![CDATA[<p>While looking for something quick to do during a brief internet outage, I wrote some code to convert to and from Roman numerals. Once things were back up I searched for equivalent code, but only found stuff that was multiple pages long, limited the range of what it could convert, or both. I figured I might as well share what I came up with:</p>

<pre class="code">function romanize (num) {
	if (!+num)
		return false;
	var	digits = String(+num).split(""),
		key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
		       "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
		       "","I","II","III","IV","V","VI","VII","VIII","IX"],
		roman = "",
		i = 3;
	while (i--)
		roman = (key[+digits.pop() + (i * 10)] || "") + roman;
	return Array(+digits.join("") + 1).join("M") + roman;
}

function deromanize (str) {
	var	str = str.toUpperCase(),
		validator = <span class="regex">/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/</span>,
		token = <span class="regex">/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g</span>,
		key = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},
		num = 0, m;
	if (!(str &amp;&amp; validator.test(str)))
		return false;
	while (m = token.exec(str))
		num += key[m[0]];
	return num;
}

</pre>

<p style="font-size:130%">How would <em>you</em> rewrite this code? Can you create a shorter version?</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter/feed</wfw:commentRss>
		</item>
		<item>
		<title>JavaScript String Multiplication Performance Exploration</title>
		<link>http://blog.stevenlevithan.com/archives/fast-string-multiply</link>
		<comments>http://blog.stevenlevithan.com/archives/fast-string-multiply#comments</comments>
		<pubDate>Sun, 18 Nov 2007 07:56:43 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
		
		<category><![CDATA[Code Challenge]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/fast-string-multiply</guid>
		<description><![CDATA[Since JavaScript concatenates strings with the + operator, it would be nifty if it would also let you multiply strings using e.g. str * 10 (as can be done in Python, at least). Since you can't do that, and no native string multiplication method is provided, I recently explored a few ways to pull it [...]]]></description>
			<content:encoded><![CDATA[<p>Since JavaScript concatenates strings with the <code>+</code> operator, it would be nifty if it would also let you multiply strings using e.g. <code>str * 10</code> (as can be done in Python, at least). Since you can't do that, and no native string multiplication method is provided, I recently explored a few ways to pull it off&hellip;</p>

<p>A naïve approach to writing a string multiplier function goes something like this:</p>

<pre class="code">function mul0 (str, num) {
	if (!num) return "";
	var newStr = str;
	while (--num) newStr += str;
	return newStr;
}
</pre>

<p>As many JavaScripters are aware, that isn't the best approach since string concatenation can be quite slow in Internet Explorer. And while IE tends to get a bad rap for this (fortunately, the IE team is <a href="http://blogs.msdn.com/jscript/archive/2007/10/17/performance-issues-with-string-concatenation-in-jscript.aspx">fixing the problem</a> in the next version of their browser), Firefox isn't exactly blazing fast at string concatenation either. Due to the performance issues, the typical string multiplication approach is to build an array and <code>join</code> it. Here's a nice, short way to do that:</p>

<pre class="code">function mul1 (str, num) {
	return num ? Array(num + 1).join(str) : "";
}
</pre>

<p>Note that the falsy <code>num</code> handling is probably not warranted in this case since the function would handle value <code>0</code> correctly without it. It's done anyway to keep functionality equivalent across the variations.</p>

<p>Unfortunately, <code>mul1</code> can still be pretty slow in Firefox 2 when multiplying large strings many times. It might be unnoticeable with small strings and repetition numbers, but the completion time goes up at a super-linear rate as the numbers increase. In search of a faster solution, I tried using a regex to keep down the size of the string being worked with:</p>

<pre class="code">var mul2 = function () {
	function mul (str, num) {
		return Array(num + 1).join(str);
	}
	return function (str, num) {
		return num ? str.replace(/^/, mul("$'", num - 1)) : "";
	};
}();
</pre>

<p>The above multiplies the two-character string "<code>$'</code>" <code>num - 1</code> times, then uses that as the replacement for a regex which just matches the start of the string (<code>$'</code> returns the text to the right of the match). How does that perform? It delivers in Firefox 2 on my Windows Vista system, with numbers like 95ms vs. 29800ms (<code>mul1</code>) when using a 2700x2700 string length/multiplier. However, based on my testing, that sort of speed gain appears to be limited to Firefox, and in Safari 3 beta <code>mul2</code> is considerably slower that the alternative versions.</p>

<p>Finally, I tried creating a version which multiplied the string at an exponential rate:</p>

<pre class="code">function mul3 (str, num) {
	if (!num) return "";
	var	orig = str,
		soFar = [str],
		added = 1,
		left, i;
	while (added &lt; num) {
		left = num - added;
		str = orig;
		for (i = 2; i &lt; left; i *= 2) {
			str += str;
		}
		soFar.push(str);
		added += (i / 2);
	}
	return soFar.join("");
}
</pre>

<p>Although that might be more code than you're willing to dedicate to a string multiplication method, it's the fastest of the above versions on average cross-browser. I've also tried a few variations using from zero to two arrays and various array methods (<code>push</code>, <code>concat</code>, etc.), but the above seems to be the fastest on average across the big four browsers.</p>

<p>Make sure to <a href="http://stevenlevithan.com/demo/mul/test.html">try the tests for yourself</a>, and let me know your thoughts and how you would improve the code.</p>

<hr/>

<p><strong>Edit:</strong> <a href="http://cixar.com/~kris.kowal/">Kris Kowal</a> contributed <code>mul4</code> (shown below, and added to the test page). It uses binary interpolation, and in Kris's words "it takes advantage of a fun bitwise identity: <code>(1 &lt;&lt; n) == Math.pow(2, n)</code>". On my system it's significantly faster than <code>mul3</code> in Firefox, but a little slower than <code>mul3</code> in IE, Safari, and Opera. Due to its high speed and lighter weight, this looks like the one to beat. Try the <a href="http://stevenlevithan.com/demo/mul/test.html">test page</a> in several browsers and see what you think.</p>

<pre class="code">function mul4 (str, num) {
	var acc = [];
	for (var i = 0; (1 &lt;&lt; i) &lt;= num; i++) {
		if ((1 &lt;&lt; i) &amp; num)
			acc.push(str);
		str += str;
	}
	return acc.join("");
}
</pre>

<hr/>

<p><strong>Edit 2:</strong> <a href="http://www.liucougar.net/blog">LiuCougar</a> of the Dojo development team posted a <a href="http://www.liucougar.net/blog/archives/76">follow-up</a> which includes several additional variations, and <a href="http://web-graphics.com/">David Andersson</a> emailed me an additional four variations including this one:</p>

<pre class="code">function mul8 (str, num) {
	var	i = Math.ceil(Math.log(num) / Math.LN2),
		res = str;
	do {
		res += res;
	} while (0 &lt; --i);
	return res.slice(0, str.length * num);
}
</pre>

<p>I should clarify however that this is mostly just academic discussion, since repeating the kinds of strings in the test page as many times as it does is a pretty crazy idea. Still, it's fun to experiment. <img src="http://blog.stevenlevithan.com/wp-includes/images/smilies/icon_smile.gif" alt="smile"/></p>

<hr/>

<p><strong>Edit 3:</strong> All the variations posted or emailed in response to this post can be seen at <strong style="font-size:120%"><a href="http://stevenlevithan.com/demo/mul/all.js">stevenlevithan.com/demo/mul/all.js</a></strong>. For the sake of consistency I've made a few minor adjustments to some of the functions such as whitespace tweaks and renaming the input arguments to <code>str</code> and <code>num</code>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/fast-string-multiply/feed</wfw:commentRss>
		</item>
		<item>
		<title>JavaScript Date Format</title>
		<link>http://blog.stevenlevithan.com/archives/date-time-format</link>
		<comments>http://blog.stevenlevithan.com/archives/date-time-format#comments</comments>
		<pubDate>Sat, 09 Jun 2007 23:15:43 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
		
		<category><![CDATA[Code Challenge]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Performance]]></category>

		<category><![CDATA[Project Releases]]></category>

		<category><![CDATA[date]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/javascript/date-format/</guid>
		<description><![CDATA[
	Update: The documentation below has been updated for the new Date Format 1.2. Get it now!


Although JavaScript provides a bunch of methods for getting and setting parts of a date object, it lacks a simple way to format dates and times according to a user-specified mask. There are a few scripts out there which provide [...]]]></description>
			<content:encoded><![CDATA[<div class="update">
	<p><strong>Update:</strong> The documentation below has been updated for the new Date Format 1.2. <a href="http://stevenlevithan.com/assets/misc/date.format.js">Get it now!</a></p>
</div>

<p>Although JavaScript provides a bunch of <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date#Methods">methods for getting and setting parts of a date object</a>, it lacks a simple way to format dates and times according to a user-specified mask. There are a few scripts out there which provide this functionality, but I've never seen one that worked well for me&hellip; Most are needlessly bulky or slow, tie in unrelated functionality, use complicated mask syntaxes that more or less require you to read the documentation every time you want to use them, or don't account for special cases like escaping mask characters within the generated string.</p>

<p>When choosing which special mask characters to use for my JavaScript date formatter, I looked at <a href="http://php.net/date">PHP's date function</a> and ColdFusion's discrete <a href="http://livedocs.adobe.com/coldfusion/8/htmldocs/functions_c-d_29.html">dateFormat</a> and <a href="http://livedocs.adobe.com/coldfusion/8/htmldocs/functions_t-z_02.html">timeFormat</a> functions. PHP uses a crazy mix of letters (to me at least, since I'm not a PHP programmer) to represent various date entities, and while I'll probably never memorize the full list, it does offer the advantages that you can apply both date and time formatting with one function, and that none of the special characters overlap (unlike ColdFusion where <code>m</code> and <code>mm</code> mean different things depending on whether you're dealing with dates or times). On the other hand, ColdFusion uses very easy to remember special characters for masks.</p>

<p>With my date formatter, I've tried to take the best features from both, and add some sugar of my own. It did end up a lot like the ColdFusion implementation though, since I've primarily used CF's mask syntax.</p>

<p>Before getting into further details, here are some examples of how this script can be used:</p>

<pre class="code">var now = new Date();

now.format("m/dd/yy");
<span class="comment">// Returns, e.g., <strong>6/09/07</strong></span>

<span class="comment">// Can also be used as a standalone function</span>
dateFormat(now, "dddd, mmmm d, yyyy, h:MM:ss TT");
<span class="comment">// <strong>Saturday, June 9, 2007, 5:46:21 PM</strong></span>

<span class="comment">// You can use one of several named masks</span>
now.format("isoDateTime");
<span class="comment">// <strong>2007-06-09T17:46:21</strong></span>

<span class="comment">// ...Or add your own</span>
dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"';
now.format("hammerTime");
<span class="comment">// <strong>17:46! Can't touch this!</strong></span>

<span class="comment">// When using the standalone dateFormat function,
// you can also provide the date as a string</span>
dateFormat("Jun 9 2007", "fullDate");
<span class="comment">// <strong>Saturday, June 9, 2007</strong></span>

<span class="comment">// Note that if you don't include the mask argument,
// dateFormat.masks.default is used</span>
now.format();
<span class="comment">// <strong>Sat Jun 09 2007 17:46:21</strong></span>

<span class="comment">// And if you don't include the date argument,
// the current date and time is used</span>
dateFormat();
<span class="comment">// <strong>Sat Jun 09 2007 17:46:22</strong></span>

<span class="comment">// You can also skip the date argument (as long as your mask doesn't
// contain any numbers), in which case the current date/time is used</span>
dateFormat("longTime");
<span class="comment">// <strong>5:46:22 PM EST</strong></span>

<span class="comment">// And finally, you can convert local time to UTC time. Either pass in
// true as an additional argument (no argument skipping allowed in this case):</span>
dateFormat(now, "longTime", true);
now.format("longTime", true);
<span class="comment">// Both lines return, e.g., <strong>10:46:21 PM UTC</strong></span>

<span class="comment">// ...Or add the prefix "UTC:" to your mask.</span>
now.format("UTC:h:MM:ss TT Z");
<span class="comment">// <strong>10:46:21 PM UTC</strong></span>
</pre>

<p>Following are the special characters supported. Any differences in meaning from ColdFusion's <code>dateFormat</code> and <code>timeFormat</code> functions are noted.</p>

<table cellspacing="0" summary="Date Format mask metasequences">
	<thead>
		<tr>
			<th>Mask</th>
			<th>Description</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><code>d</code></td>
			<td>Day of the month as digits; no leading zero for single-digit days.</td>
		</tr>
		<tr class="altBg">
			<td><code>dd</code></td>
			<td>Day of the month as digits; leading zero for single-digit days.</td>
		</tr>
		<tr>
			<td><code>ddd</code></td>
			<td>Day of the week as a three-letter abbreviation.</td>
		</tr>
		<tr class="altBg">
			<td><code>dddd</code></td>
			<td>Day of the week as its full name.</td>
		</tr>
		<tr>
			<td><code>m</code></td>
			<td>Month as digits; no leading zero for single-digit months.</td>
		</tr>
		<tr class="altBg">
			<td><code>mm</code></td>
			<td>Month as digits; leading zero for single-digit months.</td>
		</tr>
		<tr>
			<td><code>mmm</code></td>
			<td>Month as a three-letter abbreviation.</td>
		</tr>
		<tr class="altBg">
			<td><code>mmmm</code></td>
			<td>Month as its full name.</td>
		</tr>
		<tr>
			<td><code>yy</code></td>
			<td>Year as last two digits; leading zero for years less than 10.</td>
		</tr>
		<tr class="altBg">
			<td><code>yyyy</code></td>
			<td>Year represented by four digits.</td>
		</tr>
		<tr>
			<td><code>h</code></td>
			<td>Hours; no leading zero for single-digit hours (12-hour clock).</td>
		</tr>
		<tr class="altBg">
			<td><code>hh</code></td>
			<td>Hours; leading zero for single-digit hours (12-hour clock).</td>
		</tr>
		<tr>
			<td><code>H</code></td>
			<td>Hours; no leading zero for single-digit hours (24-hour clock).</td>
		</tr>
		<tr class="altBg">
			<td><code>HH</code></td>
			<td>Hours; leading zero for single-digit hours (24-hour clock).</td>
		</tr>
		<tr>
			<td><code>M</code></td>
			<td>Minutes; no leading zero for single-digit minutes.<br />
				<span class="small">Uppercase M unlike CF <code>timeFormat</code>'s m to avoid conflict with months.</span></td>
		</tr>
		<tr class="altBg">
			<td><code>MM</code></td>
			<td>Minutes; leading zero for single-digit minutes.<br />
				<span class="small">Uppercase MM unlike CF <code>timeFormat</code>'s mm to avoid conflict with months.</span></td>
		</tr>
		<tr>
			<td><code>s</code></td>
			<td>Seconds; no leading zero for single-digit seconds.</td>
		</tr>
		<tr class="altBg">
			<td><code>ss</code></td>
			<td>Seconds; leading zero for single-digit seconds.</td>
		</tr>
		<tr>
			<td><code>l</code> <em>or</em> <code>L</code></td>
			<td>Milliseconds. <code>l</code> gives 3 digits. <code>L</code> gives 2 digits.</td>
		</tr>
		<tr class="altBg">
			<td><code>t</code></td>
			<td>Lowercase, single-character time marker string: <em>a</em> or <em>p</em>.<br />
				<span class="small">No equivalent in CF.</span></td>
		</tr>
		<tr>
			<td><code>tt</code></td>
			<td>Lowercase, two-character time marker string: <em>am</em> or <em>pm</em>.<br />
				<span class="small">No equivalent in CF.</span></td>
		</tr>
		<tr class="altBg">
			<td><code>T</code></td>
			<td>Uppercase, single-character time marker string: <em>A</em> or <em>P</em>.<br />
				<span class="small">Uppercase T unlike CF's t to allow for user-specified casing.</span></td>
		</tr>
		<tr>
			<td><code>TT</code></td>
			<td>Uppercase, two-character time marker string: <em>AM</em> or <em>PM</em>.<br />
				<span class="small">Uppercase TT unlike CF's tt to allow for user-specified casing.</span></td>
		</tr>
		<tr class="altBg">
			<td><code>Z</code></td>
			<td>US timezone abbreviation, e.g. <em>EST</em> or <em>MDT</em>. With non-US timezones or in the Opera browser, the GMT/UTC offset is returned, e.g. <em>GMT-0500</em><br />
				<span class="small">No equivalent in CF.</span></td>
		</tr>
		<tr>
			<td><code>o</code></td>
			<td>GMT/UTC timezone offset, e.g. <em>-0500</em> or <em>+0230</em>.<br />
				<span class="small">No equivalent in CF.</span></td>
		</tr>
		<tr class="altBg">
			<td><code>S</code></td>
			<td>The date's ordinal suffix (<em>st</em>, <em>nd</em>, <em>rd</em>, or <em>th</em>). Works well with <code>d</code>.<br />
				<span class="small">No equivalent in CF.</span></td>
		</tr>
		<tr>
			<td><code>'&hellip;'</code> <em>or</em> <code>"&hellip;"</code></td>
			<td>Literal character sequence. Surrounding quotes are removed.<br />
				<span class="small">No equivalent in CF.</span></td>
		</tr>
		<tr class="altBg">
			<td><code>UTC:</code></td>
			<td>Must be the first four characters of the mask. Converts the date from local time to UTC/GMT/Zulu time before applying the mask. The "UTC:" prefix is removed.<br />
				<span class="small">No equivalent in CF.</span></td>
		</tr>
	</tbody>
</table>

<p>And here are the named masks provided by default (you can easily change these or add your own):</p>

<table cellspacing="0" summary="Date Format named masks">
	<thead>
		<tr>
			<th>Name</th>
			<th>Mask</th>
			<th>Example</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>default</td>
			<td>ddd mmm dd yyyy HH:MM:ss</td>
			<td>Sat Jun 09 2007 17:46:21</td>
		</tr>
		<tr class="altBg">
			<td>shortDate</td>
			<td>m/d/yy</td>
			<td>6/9/07</td>
		</tr>
		<tr>
			<td>mediumDate</td>
			<td>mmm d, yyyy</td>
			<td>Jun 9, 2007</td>
		</tr>
		<tr class="altBg">
			<td>longDate</td>
			<td>mmmm d, yyyy</td>
			<td>June 9, 2007</td>
		</tr>
		<tr>
			<td>fullDate</td>
			<td>dddd, mmmm d, yyyy</td>
			<td>Saturday, June 9, 2007</td>
		</tr>
		<tr class="altBg">
			<td>shortTime</td>
			<td>h:MM TT</td>
			<td>5:46 PM</td>
		</tr>
		<tr>
			<td>mediumTime</td>
			<td>h:MM:ss TT</td>
			<td>5:46:21 PM</td>
		</tr>
		<tr class="altBg">
			<td>longTime</td>
			<td>h:MM:ss TT Z</td>
			<td>5:46:21 PM EST</td>
		</tr>
		<tr>
			<td>isoDate</td>
			<td>yyyy-mm-dd</td>
			<td>2007-06-09</td>
		</tr>
		<tr class="altBg">
			<td>isoTime</td>
			<td>HH:MM:ss</td>
			<td>17:46:21</td>
		</tr>
		<tr>
			<td>isoDateTime</td>
			<td>yyyy-mm-dd'T'HH:MM:ss</td>
			<td>2007-06-09T17:46:21</td>
		</tr>
		<tr class="altBg">
			<td>isoUtcDateTime</td>
			<td>UTC:yyyy-mm-dd'T'HH:MM:ss'Z'</td>
			<td>2007-06-09T22:46:21Z</td>
		</tr>
	</tbody>
</table>

<p>A couple issues:</p>

<ul>
	<li>In the unlikely event that there is ambiguity in the meaning of your mask (e.g., <code>m</code> followed by <code>mm</code>, with no separating characters), put a pair of empty quotes between your metasequences. The quotes will be removed automatically.</li>
	<li>If you need to include literal quotes in your mask, the following rules apply:
		<ul>
			<li>Unpaired quotes do not need special handling.</li>
			<li>To include literal quotes inside masks which contain any other quote marks of the same type, you need to enclose them with the alternative quote type (i.e., double quotes for single quotes, and vice versa). E.g., <code>date.format('h "o\'clock, y\'all!"')</code> returns "6 o'clock, y'all". This can get a little hairy, perhaps, but I doubt people will really run into it that often. The previous example can also be written as <code>date.format("h") + "o'clock, y'all!"</code>.</li>
		</ul>
	</li>
</ul>

<p>Here's the code:</p>

<pre class="code fixedHeight"><span class="comment">/*
 * Date Format 1.2.2
 * (c) 2007-2008 Steven Levithan &lt;stevenlevithan.com&gt;
 * MIT license
 * Includes enhancements by Scott Trenda &lt;scott.trenda.net&gt; and Kris Kowal &lt;cixar.com/~kris.kowal/&gt;
 *
 * Accepts a date, a mask, or a date and a mask.
 * Returns a formatted version of the given date.
 * The date defaults to the current date/time.
 * The mask defaults to dateFormat.masks.default.
 */</span>
var dateFormat = function () {
	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length &lt; len) val = "0" + val;
			return val;
		};

	<span class="comment">// Regexes and supporting functions are cached through closure</span>
	return function (date, mask, utc) {
		var dF = dateFormat;

		<span class="comment">// You can't provide utc if you skip other args (use the "UTC:" mask prefix)</span>
		if (arguments.length == 1 &amp;&amp; (typeof date == "string" || date instanceof String) &amp;&amp; !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		<span class="comment">// Passing date through Date applies Date.parse, if necessary</span>
		date = date ? new Date(date) : new Date();
		if (isNaN(date)) throw new SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		<span class="comment">// Allow setting the utc argument via the mask</span>
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var	_ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d:    d,
				dd:   pad(d),
				ddd:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				H:    H,
				HH:   pad(H),
				M:    M,
				MM:   pad(M),
				s:    s,
				ss:   pad(s),
				l:    pad(L, 3),
				L:    pad(L &gt; 99 ? Math.round(L / 10) : L),
				t:    H &lt; 12 ? "a"  : "p",
				tt:   H &lt; 12 ? "am" : "pm",
				T:    H &lt; 12 ? "A"  : "P",
				TT:   H &lt; 12 ? "AM" : "PM",
				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o:    (o &gt; 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S:    ["th", "st", "nd", "rd"][d % 10 &gt; 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

<span class="comment">// Some common format strings</span>
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	mediumDate:     "mmm d, yyyy",
	longDate:       "mmmm d, yyyy",
	fullDate:       "dddd, mmmm d, yyyy",
	shortTime:      "h:MM TT",
	mediumTime:     "h:MM:ss TT",
	longTime:       "h:MM:ss TT Z",
	isoDate:        "yyyy-mm-dd",
	isoTime:        "HH:MM:ss",
	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

<span class="comment">// Internationalization strings</span>
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

<span class="comment">// For convenience...</span>
Date.prototype.format = function (mask, utc) {
	return dateFormat(this, mask, utc);
}
</pre>

<p><a href="http://stevenlevithan.com/assets/misc/date.format.js"><strong>Download it here</strong></a> (1.2 KB when minified and gzipped).</p>

<p>Note that the day and month names can be changed (for internationalization or other purposes) by updating the <code>dateFormat.i18n</code> object.

<p>If you have any suggestions or find any issues, lemme know.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/date-time-format/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
