You cannot trust a thing. Forget intuition. As I recently posted, you can't just go about thinking every date value is representable under the current culture. Well, there's a lot more, and I'm learning some of it the hard way. You just cannot assume a case-insensitive comparison between "bit" and "BIT" would be true. "What?" you say with utter disbelief - and with a reason. That's what I said at first, too.
It's the Turkish-I problem. In most Latin alphabets the small letter i capitalizes to I. In Turkish it's not so. The small letter i capitalizes to İ; (capital I with a dot - a glyph never even seen in English or Finnish!). And you guessed, "our" capital I isn't i in lowercase - it's rather ı, a small i without a dot.
As long as you're comparing user input, this doesn't probably make a difference. But what about your internal data structures such as configuration keys, table names and so on? Right... You may have buried bugs and even security holes by using string comparisons incorrectly.
Microsoft has an article on this and a few other issues in regard to .NET 2.0 - that's a good read. But once you know it, there's always another i18n surprise around the corner. Paranoia rules the day.
Next up: Hacking the stemming algorithm of a full-text-indexer to properly handle Chinese. <sigh>
Microsoft now supports Firefox and Opera for downloading stuff in MSDN subscriber area. I'm certainly not praising Microsoft for making a simple download service work with any browser - it should've done so a long time ago. Yet still, I do see a significant attitude shift here. Even with IE7 and all that coming out, they're actually recognizing that a group of by-heart Microsoft people such as the MSDN Subscribers has a valid desire to use other browsers.
No matter what IE7 does, it will be in a competitive position. Even though people at Microsoft (quite rightfully) seem to believe in its success, it's nice to see it not get supported by building non-compliant web sites. We're getting in a better direction, and I honestly believe it this time.
Not like it's anything new, but I'll repeat it anyway: There's much too much going on in Microsoft world. Of course, at the time of PDC05 all the news channels naturally pick up... but still, this is getting ridiculous. I'm a fast reader and in a position where information flows are rather organized and readable - but I still have serious trouble staying even remotely up-to-date with everything going on in the Microsoft software development world.
There are plenty of Whidbey things I still don't fully grasp - well actually, that's true even for .NET 1.1! And what is Microsoft doing? Out comes another set of new APIs, a few standards extensions, WPF (former Avalon), WCF (former Indigo) and a load of other stuff. Well let's not forget IE7, Office 12 and of course, Windows Vista.
There was a time when saying "Those who know Microsoft's new products don't understand a bit about how to use them" was mostly backed by envy. But... these days I'm starting to believe it. To fully leverage an enormous technological wave such as Whidbey you need to have a huge amount of knowledge - and experience - under your belt. Actually understanding the possibilities of WPF (just as a single example!) requires a lot of time - time you can't spend in real projects.
Perhaps there's still a little slice of envy behind the words. Of course, it's nice to be on top of the technology geysir. On the other hand, most developers aren't going to be. The majority of programmer job applicants still don't have managed code experience. The other extreme is writing their first WPF applications. We're going to have an "impedance mismatch" far greater than the one the LINQ project is trying to solve.
I've always known bad code bites you back in a number of ways, but this one was new. See the following code snippet:
string lastHeading = DateTime.MinValue.ToShortDateString();
foreach (Item i in GetItems()) {
if (i.Date.ToShortDateString() != lastHeading) {
lastHeading = i.Date.ToShortDateString();
Console.WriteLine(lastHeading);
}
Console.WriteLine(" " + i.Text);
}
So what does it do? Quite nicely, it takes care of printing date headers for printed items in date order. That is, under the heading "2005-09-14" are printed the entries related to that particular date.
Now, you could ask, "What's wrong with that code then?" Yes, that's not entirely obvious. The issue here is that comparisons related to the "lastHeading" are string comparisons when in fact it's DateTimes being compared. Thus, this example violates the rule of "Always use the most correct and exact data type". However, the current approach could also be argued for by saying it's actually the "heading semantics" that rule here, thus making strings the correct data type - but I won't be going there. Not now.
Well, why did this sort of structure from somebody's code fail on me today? Believe it or not, it was because of the initialization to DateTime.MinValue.ToShortDateString(). Now, there's nothing fundamentally wrong with that - it's a surefire way to force the header to be printed (although setting the string to empty or null would be more logical here if we consider this to be purely string data).
Well, we got an ArgumentNullException with an interesting error message. Why's that? Because somebody ran the software using Arabic culture (ar-SA), which uses Hijri calendar system. Unfortunately Hijri calendar doesn't have a way to format anything as low as DateTime.MinValue. Uh... What a really awkward reason to fail.
The moral of the story: Date operations (DateTime, TimeSpan et al.) are by nature culture independent. Display formatting for them rarely is, so never assume too much. And use the correct data types.