The Culture of Silverlight

Silverlight Logo

If you were paying attention yesterday, you probably noticed the little ItemsControl article that I dropped on the blog. Almost immediately I received comments from readers who where unable to run the app, either on the site or with the source code. What the heck is going on?  There was almost zero code, it was a very simple example...and it works on my machine.

So what went wrong? A big thanks to Hugo for posting the error he was getting:

Line: 0
Error: Unhandled Error in Silverlight 2 Application String was not recognized as a valid DateTime. at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)

That pointed to exactly what was happening. I was parsing dates in some code to create a set of data to bind to.  And some of those dates were invalid.  Weren't they?  Let's look at the innocent code:

DateTime dt = DateTime.Parse("7/23/2008 12:00:00 AM");

Why is this bad? Because Silverlight runs in the culture of the machine that it runs on. That means that when some of my non-North American readers (the only ones to test my code at 3am) ran the app it failed.  Being ethnocentric myself, this date is decidedly American-English (us-en). Europeans were the first th point this out when Silverlight correctly attempted to convert that date to the 7th day of the 23rd month of 2008.  D'oh!

I had two ways of solving this, I could have re-generated all the dates as UTC dates to solve it, but I opted for the simple approach:  use a culture. Because these dates were American-English dates, I simply grabbed a "us-en" culture and told the parser to use it:

// Get my Culture, who knew it was so small
CultureInfo culture = new CultureInfo("en-US");

// Parse the date with my ethnocentricity
DateTime dt = DateTime.Parse("7/23/2008 12:00:00 AM", culture);

Lesson learned...be careful of letting my culture invade my code.

Comments:

Gravatar

I've always thought of you as being a very cultured geek, Shawn. This just proves the point.

Gravatar

The same of course apply to any code that attempts to parse dates or numbers, whether under SL, javascript/ajax, or something else. A common annoyance when whoever wrote the code 'forgot' to take cultures into account so it will only work with the default user culture set to 'en-us'.

Always specify culture when parsing (or formatting) dates or numbers if there is any chance that your code will run on a PC other than your own.

Gravatar

Thanks Kristofer. In fact this is a stickler for anyone who is used to server-side code (many ASP.NET devs) as they're used to controlling the hardware.

Gravatar

Even server-side code (asp.net) needs to take this into account - if you have a field where users can input a date or number the server side code need to take their culture into account. So the easiest way to stay safe is to _always_ specify culture whenever parsing or formatting dates and numbers.

It becomes even more fun when some asian cultures are involved and the current year is not 2008 but in the 2500's or 1400's. :)

ASP.NET Ajax added culture support to client side javascript but 'forgot' the cultures with a different calendar era leading to all kinds of funny side-effects when a date was interpreted one way by the server-side .net code and another way by the client-side javascript. Fortunately they're working on getting all (or at least most) cultures supported in future versions:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=333261

Gravatar

Alas, I was hoping to find an in-depth examination of the Silverlight community culture. Instead I was treated to a useful tip. Maybe another day :)

Gravatar

Indeed, it's the classic development team war: The UK dev team says Year-Month-Day, and the US team says Month-Day-Year. And then after failing to agree to disagree, the resulting system errors send the Earth crashing into the Sun.

You can guess where I is from:
Convert.ToDateTime(value,new CultureInfo("EN-GB"));

BTW, has anyone done at <DateAnimation> tag? That might be cool.

Happy Obama Day :-)

Gravatar

If you only want to instantiate a specific date, you can also use this foolproof method:
DateTime dt = new DateTime(2008,7,23);
I would even expect it to be faster than parsing a string.

Gravatar

Use invariantculture solves this eg: http://geekswithblogs.net/kobush/archive/2007/09/16/avoidcommonglobalizationerrors.aspx

Gravatar

The problem with InvariantCulture and new DateTime() is that the date strings I am dealing with were scraped from the us-en version of XBox.com...therefore they are english not invariant (and are strings). But thanks.


 



 
Save Cancel