<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Your Catchphrase Here! &#187; Software Development</title>
	<atom:link href="http://blog.christopherschultz.net/index.php/category/Tech/software-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.christopherschultz.net</link>
	<description>Rantings of a Lunatic</description>
	<lastBuildDate>Tue, 30 Nov 2010 20:37:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Cure for OpenOffice.org Calc &#8220;the maximum number of rows has been exceeded&#8221;</title>
		<link>http://blog.christopherschultz.net/index.php/2010/11/30/cure-for-openoffice-org-calc-the-maximum-number-of-rows-has-been-exceeded/</link>
		<comments>http://blog.christopherschultz.net/index.php/2010/11/30/cure-for-openoffice-org-calc-the-maximum-number-of-rows-has-been-exceeded/#comments</comments>
		<pubDate>Tue, 30 Nov 2010 17:42:00 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.christopherschultz.net/?p=96</guid>
		<description><![CDATA[Today, I was working with a colleague to generate a report in CSV format and she was having trouble opening it in OpenOffice.org&#8217;s calc (spreadsheet) program. She was getting the error &#8220;the maximum number of rows has been exceeded&#8221;, yet the file had only about 2800 rows in it. I tried it and got the [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I was working with a colleague to generate a report in CSV format and she was having trouble opening it in OpenOffice.org&#8217;s calc (spreadsheet) program. She was getting the error &#8220;the maximum number of rows has been exceeded&#8221;, yet the file had only about 2800 rows in it. I tried it and got the same error. Hrm.</p>
<p>It turns out that the CSV file itself had an error in it: a mismatched number of &#8221; characters in the file, which is not legal &#8212; or at least not a good idea. We fixed the code that generated the CSV file to properly escape those &#8221; characters and all was well.</p>
<p>I&#8217;m posting this in the hope that others searching for answers will look at their files and see that there is a problem with them. There seem to be a bunch of sites and fora on the web where people ask these questions and don&#8217;t really get much of an answer, so this post may help those people.</p>
<p>Oh, and I should file a bug against OpenOffice.org calc saying that this is a really bad error message.</p>
<p><strong>Update:</strong> <a href="http://www.openoffice.org/issues/show_bug.cgi?id=78926">http://www.openoffice.org/issues/show_bug.cgi?id=78926</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherschultz.net/index.php/2010/11/30/cure-for-openoffice-org-calc-the-maximum-number-of-rows-has-been-exceeded/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Indenting HTML &lt;select&gt; options</title>
		<link>http://blog.christopherschultz.net/index.php/2009/02/10/indenting-html-select-options/</link>
		<comments>http://blog.christopherschultz.net/index.php/2009/02/10/indenting-html-select-options/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 19:55:26 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.christopherschultz.net/?p=53</guid>
		<description><![CDATA[In CHADIS, we had a requirement to indent certain &#60;option&#62; elements within a &#60;select&#62; dropdown list. Until recently, only team administrators had to use these pages, so we just made it work in Mozilla Firefox and left the other browsers out in the cold. Now that we have some new features that need this capability, [...]]]></description>
			<content:encoded><![CDATA[<p>In <a title="CHADIS" href="http://www.chadis.com/">CHADIS</a>, we had a requirement to indent certain &lt;option&gt; elements within a &lt;select&gt; dropdown list. Until recently, only team administrators had to use these pages, so we just made it work in <a href="http://www.mozilla.com/">Mozilla Firefox</a> and left the other browsers out in the cold. Now that we have some new features that need this capability, I decided to write-up a quick page to demonstrate each technique we tried and how each browser renders them. You can see the investigation and results below. Enjoy.</p>
<p><span id="more-53"></span></p>
<p><strong>Update (2009-06-29): </strong> Andreas Stieger points out that &lt;optgroup&gt; is an possibility, here. Unfortunately, for our purposes, we needed multiple levels of indentation <em>and</em> the options must be selectable. &lt;optgroup&gt;, while easy to implement and relatively consistent rendering across browsers, fails to meet these criteria.</p>
<p>This first dropdown uses only <a title="Cascading Style Sheets" href="http://en.wikipedia.org/wiki/Css">CSS</a> to attempt to indent the select       options. Also, CSS bold property is being used to style the top-level       items while italics are used to style the second-level items.       This ideal rendering was produced by Mozilla Firefox 3.0.6 with no       alterations.</p>
<div id="attachment_57" class="wp-caption alignnone" style="width: 170px"><a href="/wp-content/uploads/2009/02/dropdown_css_styles.png"><img class="size-medium wp-image-57" title="Select dropdown using CSS styles" src="/wp-content/uploads/2009/02/dropdown_css_styles.png" alt="Select dropdown using CSS styles" width="160" height="150" /></a><p class="wp-caption-text">Select dropdown indentation using CSS styles</p></div>
<p>This is how your browser renders the HTML for this technique. View the source to see exactly how it&#8217;s done.</p>
<select id="css_only">
<option style="font-weight:bold;">Top-level item</option>
<option style="padding-left:1em;">First-level item</option>
<option style="padding-left:1em;">First-level item</option>
<option style="padding-left:2em; font-style:italic;">Second-level item</option>
<option style="font-weight:bold;">Top-level item</option>
<option style="padding-left:1em;">First-level item</option>
<option style="padding-left:1em;">First-level item</option>
<option style="padding-left:2em; font-style:italic;">Second-level item</option>
</select>
<p>This next dropdown uses nonbreaking space (&amp;nbsp;) characters to       indent the sub-items. The bold and italic items from the previous       attempt are being left in place. Three &amp;nbsp; characters for each       level of indentation seem to look the best on most browsers.       This ideal rendering was produced by Mozilla Firefox 3.0.6 with no       alterations.</p>
<div id="attachment_58" class="wp-caption alignnone" style="width: 164px"><a href="/wp-content/uploads/2009/02/dropdown_nbsp.png"><img class="size-medium wp-image-58" title="Select dropdown indentation using  " src="/wp-content/uploads/2009/02/dropdown_nbsp.png" alt="Select dropdown indentation using  " width="154" height="150" /></a><p class="wp-caption-text">Select dropdown indentation using  &amp;nbsp;</p></div>
<p>This is how your browser renders the HTML for this technique. View the source to see exactly how it&#8217;s done.</p>
<select id="nonbreaking_spaces">
<option style="font-weight:bold;">Top-level item</option>
<option> First-level item</option>
<option> First-level item</option>
<option style="font-style:italic;"> Second-level item</option>
<option style="font-weight:bold;">Top-level item</option>
<option> First-level item</option>
<option> First-level item</option>
<option style="font-style:italic;"> Second-level item</option>
</select>
<p>Now, em dashes (&amp;mdash;) are used for indentation instead of       nonbreaking spaces, along with a trailing standard space.       Bold and italics are still in place.       This ideal rendering was produced by Mozilla Firefox 3.0.6 with no       alterations.</p>
<div id="attachment_60" class="wp-caption alignnone" style="width: 167px"><a href="/wp-content/uploads/2009/02/dropdown_mdashes.png"><img class="size-medium wp-image-60" title="Select dropdown indentation with &amp;mdash;es" src="/wp-content/uploads/2009/02/dropdown_mdashes.png" alt="Select dropdown indentation with &amp;mdash;es" width="157" height="150" /></a><p class="wp-caption-text">Select dropdown indentation with &amp;mdash;es</p></div>
<p>This is how your browser renders the HTML for this technique. View the source to see exactly how it&#8217;s done.</p>
<select id="emdashes">
<option style="font-weight:bold;">Top-level item</option>
<option>— First-level item</option>
<option>— First-level item</option>
<option style="font-style:italic;">—— Second-level item</option>
<option style="font-weight:bold;">Top-level item</option>
<option>— First-level item</option>
<option>— First-level item</option>
<option style="font-style:italic;">—— Second-level item</option>
</select>
<p>Now, the em dashes (&amp;mdash;) used for indentation are being 	    styled as white-on-white, so they should disappear. 	    Bold and italics are done using &lt;i&gt; and &lt;b&gt; tags.       This ideal rendering was produced by rendering the previous       strategy in Mozilla Firefox 3.0.6 and removing the dashes by hand.</p>
<div id="attachment_61" class="wp-caption alignnone" style="width: 167px"><a href="/wp-content/uploads/2009/02/dropdown_whitened_mdashes.png"><img class="size-medium wp-image-61" title="Select dropdown indentation using whitened &amp;mdash;es" src="/wp-content/uploads/2009/02/dropdown_whitened_mdashes.png" alt="Select dropdown indentation using whitened &amp;mdash;es" width="157" height="150" /></a><p class="wp-caption-text">Select dropdown indentation using whitened &amp;mdash;es</p></div>
<p>This is how your browser renders the HTML for this technique. View the source to see exactly how it&#8217;s done.</p>
<select id="invisible_emdashes">
<option>Top-level item</option>
<option>— First-level item</option>
<option>— First-level item</option>
<option>—— Second-level item</option>
<option>Top-level item</option>
<option>— First-level item</option>
<option>— First-level item</option>
<option style="font-style:italic;">—— Second-level item</option>
</select>
<p>After trying these techniques on the major web browsers, here&#8217;s what I found:</p>
<table style="border:1px solid black; border-collapse:collapse; font-size:small;" border="0">
<tbody>
<tr>
<th style="border:1px solid black;">Browser</th>
<th style="border:1px solid black;">CSS</th>
<th style="border:1px solid black;">nbsp</th>
<th style="border:1px solid black;">mdash</th>
<th style="border:1px solid black;">white mdash (&lt;style&gt;)</th>
<th style="border:1px solid black;">CSS bold/italic</th>
<th style="border:1px solid black;">&lt;b&gt;/&lt;i&gt;</th>
</tr>
<tr>
<td>Microsoft Internet Explorer</td>
<td>no</td>
<td>yes</td>
<td>yes</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>Mozilla Firefox</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
<td>no</td>
<td>yes</td>
<td>no</td>
</tr>
<tr>
<td>Opera</td>
<td>no</td>
<td>yes</td>
<td>yes</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>Apple Safari</td>
<td>no</td>
<td>yes</td>
<td>yes</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>Google Chrome</td>
<td>no</td>
<td>yes</td>
<td>yes</td>
<td>no</td>
<td>yes</td>
<td>no</td>
</tr>
<tr>
<td>Konqueror</td>
<td>no</td>
<td></td>
<td>no</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
</tbody>
</table>
<p>Looks like using &amp;amp;nbsp; is the best solution for all browsers, and using CSS styling will enhance the display for certain browsers but not interfere with others.</p>
<p><strong>Updated 2009-02-13:</strong> Added Konqueror info.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherschultz.net/index.php/2009/02/10/indenting-html-select-options/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Attempting AJAX</title>
		<link>http://blog.christopherschultz.net/index.php/2006/10/23/attempting-ajax/</link>
		<comments>http://blog.christopherschultz.net/index.php/2006/10/23/attempting-ajax/#comments</comments>
		<pubDate>Mon, 23 Oct 2006 16:16:02 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://blog.christopherschultz.net/?p=42</guid>
		<description><![CDATA[So, AJAX is one of the more recent causes of excitement in the web-based application delivery world. The first major site to feature AJAX (as far as I know) was Google&#8217;s gmail. Assuming that you are okay with writing tons of Javascript, it&#8217;s quite a nice way to spice up your application enough to make [...]]]></description>
			<content:encoded><![CDATA[<p>So, AJAX is one of the more recent causes of excitement in the web-based application delivery world. The first major site to feature AJAX (as far as I know) was Google&#8217;s gmail. Assuming that you are okay with writing tons of Javascript, it&#8217;s quite a nice way to spice up your application enough to make your users feel a little less like they&#8217;re using a web-based app.</p>
<p>I have to admit that I generally like to use the minimum of Javascript on my sites that can possibly work, because it usually doesn&#8217;t. Javascript is notorious for failing on various browsers and platforms with no specific rhyme or reason. Most often, it is because the application developer did not take the time to test and debug the Javascript on various browsers, or failed to use standards-compliant code and chose a single target browser (this more often happens when an application is targeted towards Microsoft Internet Explorer).</p>
<p>My rule of thumb is that Javascript should not be used unless there is some non-Javascript backup for the same functionality. Basically, Javascript may only be used to <em>enhance</em> the user interface; it cannot be used to <em>drive</em> the user interface.</p>
<p>We have a page that allows users to tick items off of a list. The list is pagenated, to it can be quite long. They can either tick them or un-tick them, and the page reflects the current status of each item. There is one big problem with this type of interface: the user expects to interact with a standard widget (the checkbox), but the page itself does not respond to checking or unchecking the checkbox: you have to submit a form. This basically won&#8217;t work because users are not going to tolerate having to check these items and then click a button, especially when moving from one page to another. They might also tick an item and then leave the page entirely. There is no way to stop them, and the only way to capture the event of ticking the checkbox is to use Javascript.</p>
<p>I am unhappy with the Javascript-only solution because it breaks down when the user&#8217;s browser does not have Javascript available. The user might not have Javascript available because of the browser (think lynx), or because they have turned off Javascript for security reasons, or because their Javascript implementation is buggy and isn&#8217;t going to work for some reason. Another approach is required.</p>
<p>My solution in the past was to make the checkbox into an image that looks like a checkbox, but it actually a link. That link points to the URL that selects (or de-selects) the item in question, which then re-displays the page with the proper status update. This works very well, except for the fact that the page view often re-sets itself back to the top of the page. That is inconvenient when you want to select multiple items from the same page, and you have to scroll down the page to see them.</p>
<p>This is a perfect example of when I have a non-Javascript solution working that could be significantly improved through the use of Javascript.</p>
<p>Enter AJAX.</p>
<p>If all the planets are aligned (i.e. the user has Javascript available and enabled, and it supports AJAX, and nothing else goes wrong), we can use some AJAX magic to improve the user experience.</p>
<p>AJAX is little more than a single (at least, from an AJAX developer&#8217;s point of view) very useful Javascript object called XMLHttpRequest. It&#8217;s job is to make an asynchronous HTTP request to some URL and provide the response either as text or as an XML document. If you elect to use the response as an XML document, then you can use the standard DOM methods to traverse everything.</p>
<p>I started out by consulting Mozilla&#8217;s <a href="http://developer.mozilla.org/en/docs/AJAX:Getting_Started">AJAX:Getting Started</a> page. It gives a fairly straightforward example of, well, getting started with AJAX. Using the information presented on that page, I was able to get something up and working relatively quickly. They had even listed the changes I would have to make in order to use the code under Microsoft Internet Explorer, so I figured I was covered when I went to test on MSIE.</p>
<p>Unfortunately, there&#8217;s a relatively large caveat when using MSIE up through version 6 when working with XML: the document.getElementsByTagName function is not namespace-aware. That means that those of us who came out from under the non-namespace-using rock several <em>years</em> ago have to deal with some pretty stupid code in order to work around it.</p>
<p>At this point, AJAX pros are saying to themselves &#8220;why doesn&#8217;t this guy just use one of the dozen or so cross-platform AJAX libraries that are out there &#8212; then he won&#8217;t have this problem&#8221;. Well, I&#8217;ll tell you: because I wanted to solve the problem myself in order to understand what was going wrong. It did take quite a while, and I ended up using information presented on Apple&#8217;s Dynamic HTML and XML: <a href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html">The XMLHttpRequest object</a>. This was the only place where I saw any mention of MSIE&#8217;s failure to support namespaces.</p>
<p>Working around non-namespace-aware Javascript is pretty ugly. Under normal circumstances, one would simply call document.getElementsByTagName and pass the &#8220;local name&#8221; of the element to that function. You&#8217;d get an array of nodes back and everything would be fine. But, since MSIE sees &#8220;foo:bar&#8221; as the local name (instead of just &#8220;bar&#8221;), you&#8217;d have to change your code to look for &#8220;foo:bar&#8221;. But, that wouldn&#8217;t work in browsers that are namespace-aware, and it&#8217;s difficult, if not impossible, to tell at runtime which way a browser will behave.</p>
<p>So, I was forced to implement my own function that loops through the children of a particular node and looks for matching elements. :(</p>
<p>It occured to me just now that I could probably get away with making two calls: one that uses the preferred method, and then, if the call returns no nodes, another that calls the same method with the namespace attached. The only problem with this option is that you have to know the text of the namespace that is being used. Typically, you only have to deal with the namespace URI instead of the actual value being used (such as &#8220;foo&#8221; in the example above). In this case, I&#8217;ll have to hard-code the namespace into the Javascript, which is non-ideal. My existing solution has no such restrictions, so I&#8217;ll probably keep it for the time being.</p>
<p>A special thanks to the MSIE team for once again stepping outside of the standard (which, in all fairness, may or may not have existed at the time of implementation) and spicing up my day.</p>
<p>Now, time to test on MSIE 7. And Opera. And Safari&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherschultz.net/index.php/2006/10/23/attempting-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(Yet Another) Microsoft Internet Explorer Rendering Bug</title>
		<link>http://blog.christopherschultz.net/index.php/2006/03/21/yet-another-microsoft-internet-explorer-rendering-bug/</link>
		<comments>http://blog.christopherschultz.net/index.php/2006/03/21/yet-another-microsoft-internet-explorer-rendering-bug/#comments</comments>
		<pubDate>Tue, 21 Mar 2006 19:49:45 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.christopherschultz.net/?p=39</guid>
		<description><![CDATA[Microsoft Internet Explorer always has the more interesting interpretations of markup.]]></description>
			<content:encoded><![CDATA[<p>For years, standard operating procedure for developing a web application would be to design and implement it with Microsoft&#8217;s Internet Explorer as the test bed. You&#8217;d pick a version and tell everyone that they needed to use it and that was that. I have to admit that even I committed such sins.</p>
<p>These days, I want my pages to be usable on as wide a variety of web browsers as possible, so I use Mozilla Firefox for development, and then just check MSIE at the end to see if anything is amiss. Yet, with MSIE, something is almost always amiss&#8230;</p>
<p>I&#8217;ve had trouble with good-looking logos and mastheads for a long time. Back in the day, tables were the way to go. More recently, CSS is the preferred (and really the only) way to do layouts. The trouble is that MSIE has some schizophrenia when it comes to CSS. The folks that wrote MSIE implement only part of the CSS specifications, and often took shortcuts whenever they wanted.</p>
<p>A few days ago, I noticed that MSIE was acting strangely when viewing one of my current projects. It appeared that the text in my masthead wasn&#8217;t being displayed. Perhaps I had some conflicting CSS styles that were giving my text the same background and foreground colors. I checked, and everything was okay. Reload after reload, application server restart after application server restart didn&#8217;t solve the problem. Mozilla Firefox never blinked an eye and rendered the (quite simple) page without a problem.</p>
<p>Then, I noticed that scrolling the page past the fold and back again would mysteriously reveal the text. That&#8217;s <em>not</em> something that can be done using CSS.</p>
<p>Check out this movie that demonstrates the problem:</p>
<p><a title="Demonstration Movie (3.3MB)" href="/wp-content/uploads/older/ie_rendering_bug/demo.mpg"><img style="border: 1px solid black" alt="Screenshot of MSIE Rendering Bug" src="/wp-content/uploads/older/ie_rendering_bug/screenshot.png" /></a></p>
<p>It&#8217;s definitely a bug. The markup is validated correct strict XHTML 1.0 and the CSS is also spick-and-span clean.</p>
<p>The markup is fairly straightforward; there&#8217;s a <em>div</em> surrounding the entire masthead (both the topmost blue bar and the bar containing the tri-colored regions), and then a <em>div</em>containing everything within the topmost blue bar. The blue bar contains a <em>form</em> containing the login form. All the other text elements are plain-old <em>h1</em> and <em>h2</em> <em>h2</em>elements. The tri-colored regions live in their own <em>div</em>and are made up of the surrounding <em>div</em>(black background) and two nested <em>div</em>elements with appropriate background colors.</p>
<p>The styles are also straightforward; colors, margins, borders, etc. I didn&#8217;t even have to use the &#8216;line-height&#8217; trick to get MSIE to display an empty <em>div</em>(for the tri-colored regions).</p>
<p>It turns out that the problem can be solved by adding a simple non-breaking space between the blue-bar and tri-colored-bar <em>div</em>elements. MSIE interprets this change by finally giving me what I wanted in the first place. Unfortunately, it adds a small vertical space before the tri-colored-bar which I would prefer not to have&#8230; it looks like unnecessary padding in the blue <em>div</em>.</p>
<p>I have a virtual machine running Microsoft Windows XP with MSIE 7 beta running on it, so I decided to comfort myself with the fact that MSIE 7 had probably fixed this bug. It hasn&#8217;t, at least not yet. I hope the MSIE engineers really try to get CSS right this time.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherschultz.net/index.php/2006/03/21/yet-another-microsoft-internet-explorer-rendering-bug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Character Assassination</title>
		<link>http://blog.christopherschultz.net/index.php/2005/11/18/character-assassination/</link>
		<comments>http://blog.christopherschultz.net/index.php/2005/11/18/character-assassination/#comments</comments>
		<pubDate>Fri, 18 Nov 2005 17:35:56 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.christopherschultz.net/?p=35</guid>
		<description><![CDATA[Using a programming language touted for its strong internationalization support along with an application server that should do the same, one would think that "international" characters would be easier to deal with. It turns out that the world is out to get me.]]></description>
			<content:encoded><![CDATA[<p>
    At the dawn of (computer) time, someone decided that computers being able     to deal with letters as well as numbers would be a great idea. And it turned     out to be a big &#8216;ole mess. </p>
<p>
    The problem is that you have to decide how to <i>encode</i> these letters     (or characters) into numbers, which is the only thing that computers can handle.     <a href="http://en.wikipedia.org/wiki/EBCDIC">EBCDIC</a> and     <a href="http://en.wikipedia.org/wiki/ASCII">ASCII</a> were two of the first,     and while DBCDIC has effectively died, ASCII has turned into a few (relatively     compatible) standards such as US-ASCII and ISO-8859-1 (also called &#8220;Latin-1&#8243;).     These jumbles of letters are called <i>character sets</i>, and the describe how     to take the concept of a letter and turn it into one or more 8-bit bytes for     processing within the computer. </p>
<p>
    One of the most flexible characters sets is called     <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a>, and represents an     efficient packing of bytes by only using the minimum necessary. For example,     there are jillions of characters out there in human language if you take into     account written languages like Chinese, Sanskrit, etc. We would need many     bytes to represent all character possibilities (maybe 4 or 5), but UTF-8     has a trick up its sleeve that helps reduce the number of bytes taken up     by common (read: Latin-1) characters. It&#8217;s also completely backward-compatible     with ASCII, which makes it super-handy to use in places where ASCII was     already being used, and it&#8217;s time to add support for international characters. </p>
<p>
    Now that the history lesson is over, it&#8217;s time to complain. </p>
<p>
    I&#8217;m writing an application in the Java programming language, which is generally     highly touted as having excellent internationalization (or     <a href="http://en.wikipedia.org/wiki/I18n">i18n</a>) support: it has     encoding and decoding capability for a number of different character sets     (ASCII, UTF-8, Big5, Shift_JIS, any number of ISO-xyz-pdq encodings, etc.),     natively uses Unicode (actually, UTF-16, which is a specific type of Unicode),     and has some really sexy ways to localize (that&#8217;s the process of managing     translations of your stuff into non-native languages &#8212; such as Spanish     being non-native to me, an English speaker) content. </p>
<p>
    I was tyring to do something very simple: get my application to accept a     &#8220;funny&#8221; (or &#8220;international&#8221; or non-Latin-1&#8230; I&#8217;ll just say &#8220;funny&#8221;, since I don&#8217;t     use those characters very often) character. I love the Spanish use of     open-exclaimation and open-question characters. They&#8217;re upside-down versions     of ! and ? and preceed questions and exclaimations. It makes sense when you     think about it. Anyhow, I was trying to successfully take the string     &#8220;¡Bienvenidos!&#8221;, put it into my database, and get it back out successfully,     using a web browser as the client and my own software to move the data     back and forth. </p>
<p>
    It wasn&#8217;t working. Repeated submissions/views/re-submissions were resulting     in additional characters being inserted before the &#8220;¡&#8221;. Funny stuff that I had     clearly not entered. </p>
<p>
    I&#8217;ve done this before, but the mechanics are miserable and I pretty much block     out the painful memories each time if happens. </p>
<p>
    The problem is that many pieces of code get their grubby little hands on the     data from the time you type it on your keyboard and the time it gets into     my database. Here is a short list of code that handles those characters,     and where opportunities for cock-ups occur. </p>
<ul>
<li>Keyboard controller. Your keyboard has to be able to &#8220;type&#8221; these     characters correctly so that the operating system can read them. I can&#8217;t     type a &#8220;¡&#8221;on my keyboard, so I need to take other steps.</li>
<li>Your operating system. MS-DOS in its default configuration in the US isn&#8217;t     going to handle Kanji characters very well.</li>
<li>Your web browser. The browser has to take your characters and submit     them in a request to the web server. Guess what? There&#8217;s a character encoding     that is used in the request itself, which can complicate matters.</li>
<li>The web server, which may or may not perform any interpretation of the     bytes being sent from the web browser.</li>
<li>The application server, which provides the code necessary to convert     incoming request data into Java strings.</li>
<li>My database driver, which shuttles data back and forth between Java     and the database server.</li>
<li>The database itself, which has to store strings and retrieve them.</li>
</ul>
<p>
    I can pretty much absolve the keyboard and operating system at this point.     If I can see the &#8220;¡&#8221; on the screen, I&#8217;m pretty happy. I can also be reasonably     sure that the web browser knows what character I&#8217;m taking about, since it&#8217;s     being displayed in the text area where I&#8217;m entering this stuff. My web server     is actually ignoring request content and just piping it through to my app server.     The database and     driver should be okay, as I have specified that I want UTF-8 to be used both     as the storage format of characters in the database, and for communication     between the Java database driver and the database server. </p>
<p>
    That leaves 2 possibilities: the request itself (made by the web browser) or     the application server (converts bytes into Java strings). </p>
<p>
    The first step in determining the problem is research: what happens when     the web browser submits the form, and how is it accepted and converted into     a Java string? </p>
<ol>
<li>The web browser creates a request by converting all the data in a form into     bytes. It does this by using the content-type     &#8220;application/x-www-form-urlencoded&#8221; and some character encoding. You can     ignore the content-type for now.</li>
<li>The request is sent to the server.</li>
<li>The application uses the <code>ServletRequest.getParameter</code>    method to get a String value for a request parameter.</li>
<li>The application server reads the parameter out of the request using some     character encoding, and converts it into a String.</li>
</ol>
<p>
    So, it looks like the possibilties for confusion are where the character sets     are chosen.  The     <a href="http://www.w3.org/TR/REC-html40/interact/forms.html#edef-FORM">W3C</a>    says that &lt;form&gt; elements can specify their preferred character set     by using the <code>accept-charset</code> attribute. The default value for     that attribute is &#8220;UNKNOWN&#8221;, which means that the browser is free to     choose an arbitrary character set. A semi-tacit recommendation is that the     browser use the character encoding that was used to provide the form (i.e.     the charset of the current page) as the charset to use to make the request. </p>
<p>
    That seems relatively straightforward. My responses are currently using UTF-8     as their only charset, so the forms ought to be submitted as UTF-8. Perfect!     &#8220;¡&#8221; ought to successfully be transmitted in UTF-8 format, and go     straight-through to my database without ever being mangled. Since this wasn&#8217;t     happening, there was obviously a problem. What character set *was* the     browser using? A quick debug log message ought to help: </p>
<pre class="code">
DEBUG - request charset=null </pre>
<p>
    Uh, oh. A <code>null</code> charset means that the app server has to do     some of it&#8217;s own thinking, and that usually spells trouble. </p>
<p>
    Time to take a look at the &#8216;ole API specification. First stop,     <a href="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletRequest.html#getParameter(java.lang.String)">ServletRequest.getParameter()</a>,     which is the first place my code gets a crack at reading data. There&#8217;s no mention     of charsets, but it does mention that if you&#8217;re using POST (which I am),     that calling <code>getInputStream</code> or <code>getReader</code>    before calling <code>getParameter</code> might cause problems. That&#8217;s     a tip-off that one of those methods gets called in order to read the parameter     values themselves. Since <code>InputStream</code>s don&#8217;t care about     character sets (they deal directly with bytes), I can ignore that one.     <a href="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletRequest.html#getReader()">ServletRequest.getReader()</a>    claims to throw <code>UnsupportedEncodingException</code> if the encoding     is (duh) unsupported, so it must be applying the encoding itself. There is no     indication of how the API determines the charset to use. </p>
<p>
    The HTTP specification has a header field which can be used to communicate     the charset to be used to decode the request. The header is &#8220;content-type&#8221;,     and has the form: &#8220;Content-Type: major/minor; charset=[charset]&#8220;. I already     mentioned that the content-type of a form submission was     &#8220;application/x-www-form-urlencoded&#8221;, so I should expect something like     &#8220;Content-Type: application/x-www-form-urlencoded; charset=UTF-8&#8243;     to be included in the headers from the browser. Let&#8217;s have a look: </p>
<pre class="code">
DEBUG - Header['host']=[deleted]
DEBUG - Header['user-agent']=Mozilla/5.0 [etc...]
DEBUG - Header['accept']=text/xml, [etc...]
DEBUG - Header['accept-language']=en-us,en;q=0.5
DEBUG - Header['accept-encoding']=gzip,deflate
DEBUG - Header['accept-charset']=ISO-8859-1,utf-8;q=0.7,*;q=0.7
DEBUG - Header['keep-alive']=300
DEBUG - Header['connection']=keep-alive
DEBUG - Header['referer']=[deleted]
DEBUG - Header['cookie']=JSESSIONID=[deleted]
DEBUG - Header['content-type']=application/x-www-form-urlencoded
DEBUG RequestDumper- Header['content-length']=121
</pre>
<p>
    Huh? The Content-Type line doesn&#8217;t contain a charset. That means that     the application server is free to choose one arbitrarily. Again, the unspecified     charset comes back to haunt me. </p>
<p>
    So, the implication is that the web browser is submitting the form using UTF-8,     but that the app server is choosing its own character set. Since things aren&#8217;t     working, I&#8217;m assuming that it&#8217;s choosing incorrectly. Since the Servlet spec     doesn&#8217;t say what to do in the absence of a charset in the request, okly reading     the code can help you figure out what&#8217;s going on. Unfortunately, Tomcat&#8217;s     code is so byzantine, you don&#8217;t get very far into the request wrapping and facade     classes before you go crazy. </p>
<p>
    So, you try other things. Maybe the app server is using the default file encoding     for the environment (it happens to be &#8220;ANSI_X3.4-1968&#8243;) for me. Setting     the &#8220;file.encoding&#8221; system property changes the file encoding used in the system,     so I tried that. No change. The last-ditch effort was to simply smack the     request into submission by explicitly setting the character encoding in the     request if none was provided by the client (in this case, the browser). </p>
<p>
    The best way to do this is with a servlet <i>filter</i>, which gets ahold of the     request before it is processed by any servlet. I simply check for a     <code>null</code> charset and set it to UTF-8 if it&#8217;s missing. </p>
<pre class="code">
public class EncodingFilter
    implements Filter
{
    public static final String DEFAULT_ENCODING = "UTF-8";

    private String _encoding;

    /**
     * Called by the servlet container to indicate to a filter that it is
     * being put into service.
     *
     * @param config The Filter configuration.
     */
    public void init(FilterConfig config)
    {
	_encoding = config.getInitParameter("encoding");
	if(null == _encoding)
	    _encoding = DEFAULT_ENCODING;
    }

    protected String getDefaultEncoding()
    {
	return _encoding;
    }

    /**
     * Performs the filtering operation provided by this filter.
     *
     * This filter performs the following:
     *
     * Sets the character encoding on the request to that specified in the
     * init parameters, but only if the request does not already have
     * a specified encoding.
     *
     * @param request The request being made to the server.
     * @param response The response object prepared for the client.
     * @param chain The chain of filters providing request services.
     */
    public void doFilter(ServletRequest request,
			 ServletResponse response,
			 FilterChain chain)
	throws IOException, ServletException
    {
	request.setCharacterEncoding(getCharacterEncoding(request));

	chain.doFilter(request, response);
    }

    protected String getCharacterEncoding(ServletRequest request)
    {
	String charset=request.getCharacterEncoding();

	if(null == charset)
	    return this.getDefaultEncoding();
	else
	    return charset;
    }

    /**
     * Called by the servlet container to indicate that a filter is being
     * taken out of service.
     */
    public void destroy()
    {
    }
}
</pre>
<p>
    This filter has been written before: at least <a href="http://wiki.apache.org/tomcat/Tomcat/UTF-8">here</a> and     <a href="http://java.sun.com/products/servlet/Filters.html#72673">here</a>. </p>
<p>
    It turns out that adding this filter solves the problem. It&#8217;s very odd that     browsers are not notifying the server about the charset they used to encode     their requests. Remember the &#8220;accept-charset&#8221; attribute from the HTML     &lt;form&gt; element? If you specify that to be &#8220;ISO-8859-1&#8243;,     <a href="http://www.mozilla.org/products/firefox">Mozilla Firefox</a>    will happily submit using ISO-8859-1 and not tell the server which encoding     was used. Same thing with <a href="http://www.microsoft.com/windows/ie">Microsoft Internet Explorer</a>. </p>
<p>
    I can understand why the browser might choose not to include the charset     in the content type header because the server ought to &#8220;know&#8221; what to expect,     since the browser is likely to re-use the charset from the page containing the     form. But what if the form comes from one server and submits to another?     Neither of these two browsers provide the charset if the form submits to     a different page, so it&#8217;s not just an &#8220;optimization&#8221;&#8230; it&#8217;s an oversight. </p>
<p>
    There&#8217;s actually a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=241540">bug</a>    in Mozilla related to this. Unfortunately, the fix for it was removed because     of incompatibilities that the addition of the charset to the content type was     causing. Since Mozilla doesn&#8217;t want to get the reputation that their browser     doesn&#8217;t work very well, they decided to drop the charset. :( </p>
<p>
    The bottom line is that, due to some bad implementations out there that ruin     things for everyone, I&#8217;m forced to use this awful forced-encoding hack.     Fortunately, it &#8220;degrades&#8221; nicely if and when browsers start enforcing the     HTTP specification a little better. My interpretation is that &#8220;old&#8221;     implementations always expect ISO-8859-1 and can&#8217;t handle the &#8220;charset&#8221;     portion of the header. Fine. But, if a browser is going to submit data in any     format <i>other than</i> ISO-8859-1, then they should include the charset     in the header. It&#8217;s the only thing that makes sense. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherschultz.net/index.php/2005/11/18/character-assassination/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How old are you, really?</title>
		<link>http://blog.christopherschultz.net/index.php/2005/08/07/how-old-are-you-really/</link>
		<comments>http://blog.christopherschultz.net/index.php/2005/08/07/how-old-are-you-really/#comments</comments>
		<pubDate>Mon, 08 Aug 2005 01:09:00 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.christopherschultz.net/?p=32</guid>
		<description><![CDATA[An investigation into time delta computation.]]></description>
			<content:encoded><![CDATA[<blockquote>
<p>
    When a man sits with a pretty girl for an hour, it seems like a minute. But let him sit on     a hot stove for a minute&#8211;and it&#8217;s longer than any hour. That&#8217;s relativity.     </p>
<p>
    -Albert Einstein     </p>
</blockquote>
<p>
    Reckoning time has always been a problem for humans, it seems. We have argued     over <a href="http://www.hermetic.ch/cal_stud.htm">which calendar to use</a>    for quote a long time. Even worse is trying to figure out how long ago something     happened. </p>
<p>
    The answers to many &#8220;how long ago&#8221; questions can be answered with a certain degree     of slop. For example, &#8220;how long ago was <a href="http://en.wikipedia.org/wiki/Jesus">Jesus     of Nazareth</a> born?&#8221; could be answered,     &#8220;about 2000 years ago&#8221;. &#8220;When was peace declared at the end of     <a href="http://en.wikipedia.org/wiki/World_War_II">World War II</a>?&#8221;, &#8220;60 years ago&#8221;.     But what a question to which the answer should be more specific, such as &#8220;how long ago     was I born?&#8221;. I want to know the years, months, and days for that figure, and here&#8217;s why. </p>
<p>
    As part of my continuing work with <a href="http://www.childhealthcare.org">The Center     for Promotion of Child Development Through Primary Care</a>, I have to be able to display     ages for patients that our doctors will be treating. More often than not, these patients are     young, so we&#8217;re talking about newborns through adolescencts. For the newborns, the number     of months and days is very important, while the ages of adolescent patients are okay to round-off     to years and months, and maybe just years. </p>
<p>
    It turns out that it&#8217;s somewhat difficult to answer the question &#8220;how old are you?&#8221;. It doesn&#8217;t     really seem all that hard, until you actually try to do it. The problem is that people disagree about     a lot of things. For example, you won&#8217;t get much argument that there are 10 days separating     2000-01-01 and 2000-01-11, or that there is 1 month separating 2000-01-01 and 2000-02-01.     But what about the date difference between 2000-01-31 and 2000-02-30? Is that 30 days or     is it 1 month? </p>
<p>
    <a href="http://www.boyet.com/">Julian Bucknall</a> is a guy who studies algorithms,     at least as a hobby. He has a <a href="http://www.boyet.com/Articles/PublishedArticles/Calculatingthenumberofmon.html">discussion     of time reckoning in software</a> including a sample implementation in C#. Although I appreciate     his discussion (and created a few new unit tests based upon some of the problematic date ranges     he presents), I don&#8217;t entirely agree with how he did his implementation. I happen to be using     Java for my purposes, but I did my own implementation because I needed to, not because I&#8217;m     just a Java wonk. </p>
<p>
    Before I start, those without a programming background have to realize that most programming     languages have very poor tools for handling dates. Mostly they center around counting milliseconds     since a certain date (usually <a href="http://en.wikipedia.org/wiki/Unixtime">1970-01-01</a>).     This is great for quick calculations of numbers of days between events, since a day has a fixed     number of milliseconds (1000 ms/sec * 60 sec/min * 60 min/hr * 24 hr/day = 86400000 ms/day). </p>
<p style="font-style:italic;">
    For those of you who are too smart for your own good, I&#8217;m going to be ignoring     <a href="http://tycho.usno.navy.mil/leapsec.html">leap seconds</a> and things     like that for the time being, since computers generally don&#8217;t handle those, anyway. If you want your     computer&#8217;s time to be correct to the nearest leap-second mandated by the     <a href="http://hpiers.obspm.fr/">IEOS</a>, you should just manually adjust your clock     whenever it&#8217;s convenient&#8230; no date library is going to worry about keeping a list of all leap-seconds     ever added to civil time. </p>
<p>
    So, back to dates in software. Since the number of milliseconds in a day is fixed, and computers     often represent dates as a number of milliseconds from a fixed date (generally known as the epoch),     it&#8217;s very easy to calculate the difference between two dates as a number of days. For example, I     was born on 1977-10-27. That means that I am 10146 days old (wow, that doesn&#8217;t seem like a lot&#8230;).     But how many years, months, and days old am I? </p>
<p>
    Fortunately, for discussion purposes, I&#8217;m writing this entry on 2005-08-07, which has both the     day-of-month, as well as the month itself, less than the same numbers in my birth date (that is,     8 is less than 10, and 7 is less than 27). That&#8217;s good because it makes the math harder.     If I had been born on 1977-08-01, then you could count on your fingers that I am 28 years, 0 months,     and 6 days old. Since I was born later in the month and later in the year, there are all kinds of     fun things that have to happen. </p>
<p>
    If you were to perform these calculations on your fingers, you&#8217;d probably start with the birth date     and keep adding years until you couldn&#8217;t add them anymore without going over. You&#8217;d easily get to     27 and stop (if you had that many fingers). But then, you have to figure out what the differences     are between the months and days. Exactly 27 years after my birth would be 2004-10-27. In order to     get yourself to 2005-08-07, you need to add a bunch of months. If you add 10 months, you&#8217;ll get     2005-08-27, which is too much. So, you have to add 9 months instead, and then figure the days.     Exactly 27 years and 9 months after my birth would be 2005-07-27. In order to get to today, you have     to add days. If you add 11 days, you&#8217;ll get to 2005-08-07. Ta-da! </p>
<p>
    Now, that didn&#8217;t seem too bad, did it? Actually, an implementation which basically follows this     on-your-fingers calculation is the one proposed by Julian Bucknall as well as many others     on the web. I don&#8217;t like this implementation because is it computational overkill (you have to do     <i>lots</i> of looping, and most Date object implementations that exist out there will re-calculate     a bunch of stuff whenever you update a single field, such as the year or month). I actually wrote     mine before I read his article, and I don&#8217;t have a C# compiler handy to run his algorithm through     my test cases, so I can&#8217;t be sure that they yield the same results. At any rate, I have an     implementation that should be a little more efficient and meets my needs. </p>
<p>
    Oh, one last note: we had been using a Java library called     <a href="http://mindprod.com/jgloss/bigdate.html">BigDate</a> to do our date calculations.     I knew it was going to be a pain in the neck to write our own, so we found a library that     would do it for us. Unfortunately, it fails with Java Date objects representing dates before     1970-01-01. The author claims that his library handles dates prior to 1970 in contrast to Java&#8217;s Date,     but it appears that he is wrong on two counts: Java&#8217;s Date class does, in fact, handle dates before 1970,     and his library trips over them. I was able to use his library by passing-in the year, month, and date     separately, but that required me to use deprecated methods in the Date API, and I was already     starting to look down my nose at it, slightly. Just for the heck of it, I tried to use BigDate to calculate     the date delta between a BCE date and today, and BigDate ignored the era, so I got the wrong answers     there, too. </p>
<p>
    So, I wrote my own implementation (in Java) that quickly calculates deltas for all three fields (I&#8217;m not     concerned with time, just the date), possibly ajdusts them for BCE dates, and then runs a fairly     simple algorithm to move the date, then month and year to their correct values. We use a class     called DiffDate which just stores a year, month, and date as a return value. I have one method     that accepts a pair of Date objects, and one that accepts a pair of Calendars. Use of the Calendar     avoids deprecation warnings during compilation, and offers two methods for client code, making     it easier to use in situations that call for either Dates or Calendars. </p>
<blockquote>
<pre>
    //
    // Copyright and licence notice: I intend for this code to be freely copied, edited, improved, etc.
    // Please give me (Chris Schultz, http://www.christopherschultz.net/) credit as the source of
    // this code, and let me know if you find ways to improve it.
    //
    public static DiffDate diffDates(Date earlier, Date later)
    {
      Calendar c_e = Calendar.getInstance();
      c_e.setTime(earlier);
      Calendar c_l = Calendar.getInstance();
      c_l.setTime(later);
      return diff(c_e, c_l);
    }

    public static DiffDate diff(Calendar earlier, Calendar later)
    {
      int y1 = earlier.get(Calendar.YEAR);
      int m1 = earlier.get(Calendar.MONTH);
      int d1 = earlier.get(Calendar.DATE);
      int y2 = later.get(Calendar.YEAR);
      int m2 = later.get(Calendar.MONTH);
      int d2 = later.get(Calendar.DATE);

      // Adjust years across eras (BC dates should be negative, here).
      if(java.util.GregorianCalendar.BC == earlier.get(Calendar.ERA))
        y1 = -y1;
      if(java.util.GregorianCalendar.BC == later.get(Calendar.ERA))
        y2 = -y2;

      int d_y = y2 - y1;
      int d_m = m2 - m1;
      int d_d;

      // Now that we've got deltas, start with the days and work backward
      // changing any negatives into positives, and rippling up to larger
      // fields.
      if(d2 >= d1)
      {
        d_d = d2 - d1; // Easy
      }
      else
      {
        // To determine how big the months are.
        Calendar work = (Calendar)later.clone();
        while(d1 > d2)
        {
          // Move backward through the months, adding a whole month
          // until we have enough days to cover the deficit.
          --m2;
          // To track our progress through the month
          --d_m;
          // Now, there's one less month between dates
          if(0 > m2)
          {
            --d_y;
            work.set(Calendar.YEAR, work.get(Calendar.YEAR) - 1);
            m2 = Calendar.DECEMBER;
          }

          work.set(Calendar.MONTH, m2);
          d2 += work.getActualMaximum(Calendar.DAY_OF_MONTH);
        }

        d_d = d2 - d1;
      }

      // Adjust the months and years
      while(0 > d_m)
      {
        d_m += 12;
        d_y -= 1;
      }

      return new DiffDate(d_y, d_m, d_d);
    }
</pre>
</blockquote>
<p>
    The whole thing is very straightforward, with the notable exception of the big &#8220;else&#8221; block in the     middle of the code. It is here where we handle cases when the earlier date has a day-of-month     that is later in the month than the later date. In that case, we need to count backwards, enlisting     the help of a Calendar object to give me the lengths of various months. That &#8216;work&#8217; calendar actually     exists only to help me with leap-year determination. I suppose I would have used the old &#8220;years     evenly divisible by 4, except every 100, except every 400&#8243;, but that would have complicated my code     even further, and, I think, been inaccurate for old dates because of changes to the calendar.     Then again, I think that GregorianCalendar (the default calendar in my locale) had those same     rules, so I&#8217;d get the same results in both cases. If you want to calculate dates in October of 1582,     <a href="http://www.wisegeek.com/what-happened-to-the-calendar-in-october-1582.htm">you&#8217;re on your own</a>. </p>
<p>
    You may have noticed, but this implementation does not handle time zones in any way.     The reason is that this is intended to be for age calculation. If you were born in Sydney     on 2000-01-01, then it might still have been 1999-12-31 in New York. However, you&#8217;re     certainly not going to maintain your birthday to be 1999-12-31 when you&#8217;re in the US and     2000-01-01 when you&#8217;re in Sydney. Or, at least, we won&#8217;t ;) </p>
<p>
    It occurs to be that I&#8217;d like to write an entirely new Date implementation for Java, to handle things     like bizarre missing dates (like October 1582) and a few other things that bother me about the Date     class, but it&#8217;s just not going to happen. There are too many APIs that already use Date (or Calendar)     and they&#8217;re not likely to change. Also, one of the things that I haven&#8217;t liked about the APIs is that     they were able to neither calculate nor store delta dates. I have solved both with a delta date     implementation and a simple delta date class. </p>
<p>
    So, how old are you, exactly? My code says that I&#8217;m 27 years, 9 months, and 11 days old.     But I feel much younger than that. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherschultz.net/index.php/2005/08/07/how-old-are-you-really/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Can I Get A Witness?</title>
		<link>http://blog.christopherschultz.net/index.php/2005/07/18/can-i-get-a-witness/</link>
		<comments>http://blog.christopherschultz.net/index.php/2005/07/18/can-i-get-a-witness/#comments</comments>
		<pubDate>Mon, 18 Jul 2005 16:49:49 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.christopherschultz.net/?p=31</guid>
		<description><![CDATA[Chris begs for recognition for some prior art...]]></description>
			<content:encoded><![CDATA[<p>
    On the 13<sup>th</sup> of July, <a href="http://slashdot.org/">Slashdot</a>    had a <a href="http://it.slashdot.org/article.pl?sid=05/07/13/1351239">post</a>   about a guy who had, using some Javascript and interaction with the HTML DOM, replaced    standard checkboxes and radio buttons on web forms with nicer looking versions;    basically, he has a way to use nicer looking widgets on a web form. They&#8217;re quite     attractive. His research can be found on <a href="http://www.gamingheadlines.co.uk/wod/formstyle/index.html">this page</a>. </p>
<p>
    He mentions in &#8220;The Code&#8221; section that this is &#8212; as far as he knows &#8212; an original idea.     There&#8217;s no date on the page itself, so it&#8217;s difficult to tell when he had the idea. </p>
<p>
    What I can tell you is this: I had this working somewhere between 2005-02-14 and     2005-02-16 according to my CVS logs. I&#8217;m working on an online questionnaire delivery     and decision-processing system for <a href="http://www.childhealthcare.org" title="Child Health And Development Interactive System">CHADIS</a>,     and I developed this technique over a period of time, and finally checked the code into     my CVS repo over a period of 2 days, including updates and fixes. Of course, I have root     access on the servers which host our CVS repositories, so I could be falsifying that     information, however I don&#8217;t really have any motivation to do so. </p>
<p style="text-align;center; max-width:640px;margin-left:auto;margin-right:auto;">
   <a style="border:none;"href="/wp-content/uploads/older/chadis_question.png"><img src="/wp-content/uploads/older/chadis_question_sm.png" title="Styled example" /></a><br />
   <i>Radio buttons replaced with stylized buttons. The orange-lit button is the     currently-selected button, while the light-blue-lit one is under the cursor.    <b>Update: 2005-07-18 15:09</b>: Oops. When I did a screenshot, the &#8220;light-blue&#8221;     button that I describe disappeared, probably because the cursor disappears when you     take a screenshot. I promose that it works ;)</i>
</p>
<p>
    My code is all in Javasript, keps in a separate file with a smattering of <i>onclick</i>-style     hooks into the library that I&#8217;ve written. All of the form elements are standard HTML form     elements, and the whole thing degrades gracefully on non-CSS/Javascript browsers     (yes, I test my software on <a href="http://lynx.isc.org/" title="Lynx, the text web browser">Lynx</a>, thank you very much). </p>
<p style="text-align:center;">
    <a style="border:none;"href="/wp-content/uploads/older/chadis_question_unstyled.png"><img src="/wp-content/uploads/older/chadis_question_unstyled_sm.png" title="Unstyled example" /></a><br />
    <i>The same page with styles disabled.</i>
</p>
<p>
    I&#8217;m sure that someone else has identified this problem (of not being able to adequately     style HTML radio buttons and checkboxes) and developed a similar solution as well.     It&#8217;s nice to know that someone has found a solution very similar to my own. It gives     me a sense of validation that someone else came to the same conclusions that I did:     that this is a problem that is best solved with Javascript and DOM manipulation,     and that degrading usefully on browsers that don&#8217;t support all the whiz-bang features     is not only possible, but a worthwhile goal. </p>
<p style="text-align:center;">
    <img src="/wp-content/uploads/older/chadis_question_lynx.png" title="I told you it worked in Lynx" /><br />
    <i>The same page when viewed with Lynx v2.8.5rel.1.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherschultz.net/index.php/2005/07/18/can-i-get-a-witness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Doughnuts! I like Doughnuts!</title>
		<link>http://blog.christopherschultz.net/index.php/2004/09/15/doughnuts-i-like-doughnuts/</link>
		<comments>http://blog.christopherschultz.net/index.php/2004/09/15/doughnuts-i-like-doughnuts/#comments</comments>
		<pubDate>Wed, 15 Sep 2004 14:02:52 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://blog.christopherschultz.net/?p=7</guid>
		<description><![CDATA[I&#8217;ve been a software developer for quite some time, and at my last job, I was indoctrinated into the practice of buying doughnuts for the development team if one of the developers &#8220;broke the build&#8221;. For those who don&#8217;t know what that means, let me tell you. Any decent software project has a central repository [...]]]></description>
			<content:encoded><![CDATA[<p>
    I&#8217;ve been a software developer for quite some time, and at my last     job, I was indoctrinated into the practice of buying doughnuts for     the development team if one of the developers &#8220;broke the build&#8221;. </p>
<p>
    For those who don&#8217;t know what that means, let me tell you. Any decent     software project has a central repository for source code which does     versioning. That allows you to &#8220;undo&#8221; some changes if you decide that     you made a mistake, or that a feature shouldn&#8217;t have been added, etc.     It also lets you see wny each change was made because you typically     add a comment for each &#8220;commit&#8221; that you do to the source repository. </p>
<p>
    <i>Breaking the build</i> is not really breaking the &#8220;build&#8221;, per se,     but committing a piece of code to the software respository that causes     the <i>next</i> build to fail (a &#8220;build&#8221; is when you compile all the     code in the project &#8212; usually for testing purposes). </p>
<p>
    The penalty for breaking the build was therefore furnishing the entire     development team with doughnuts the following morning. Sometimes,     people woulc bring the crap from around the corner &#8212; one of these places     in downtown Washington, DC that couldn&#8217;t possibly stay in buisiness unless     everyone who worked on the block went there for breakfast and lunch (which     they did&#8230; apparently because they derive no joy whatsoever from meals).     However, those of us who knew what we were doing would seek out and find     the very best in doughnut-land:     <a href="http://www.krispykreme.com/">Krispy Kremes</a>. </p>
<p>
    After I got married, I switched jobs and I&#8217;m now leading the development     team for an organization in Baltimore, MD. There is no central office     and so everyone works from home. This is a big advantage for me, since I     live in Virginia. However, even the development team doesn&#8217;t work     physically in the same location, so if someone breaks the build, it&#8217;s kinda     hard for someone to provide doughnuts to everyong in retribution for breaking     the build. </p>
<p>
    Several days ago, one of our engineers, Luke, broke the build. In jest     (since we really can&#8217;t do the whole doughnut thing), I created a bug report     in our <a href="http://www.bugzilla.org/">bug tracking system</a>, and     mentioned doughnuts. </p>
<p>
    Needless to say, the &#8220;bug&#8221; was fixed in minutes. </p>
<hr style="margin-left:30%; margin-right:30%;"/>
<p>
    This morning, my friend the UPS dude comes to my door (poor guy&#8230; he&#8217;s     lugged a TiVo up 4 flights of stairs to my apartment when the elevator was     dead for a couple of days) with this box from     <a href="https://www.dunkindonuts.com/">Dunkin Doughnuts</a>. </p>
<p>
    &#8220;What the hell is Dunkin&#8217; Doughnuts sending me?&#8221;, I said to my wife.<br />
    &#8220;Open it!&#8221;, she yells as she starts tearing into the box.     &#8220;There could be doughnuts in there!&#8221; </p>
<p>
    It was way too light to be doughnuts. It was also way too light to contain     a bomb, so I figured it would be cool to open it. </p>
<p style="text-align:center;">
    <img src="/wp-content/uploads/older/lukes_doughnuts_sm.jpg" alt="Image of Dunkin' Doughnuts box (9x12x6&quot;) containing several gift coupons -- from Luke" title="Dunkin' Doughnuts Gift Checks -- from Luke" />
</p>
<p>
    I laughed so hard I almost fell our of my chair. I think I&#8217;ll send Katie out     to get us some doughnuts. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christopherschultz.net/index.php/2004/09/15/doughnuts-i-like-doughnuts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

