How to Globalise/Internationalise Dates and Numbers using the Compact Framework
Well I learnt something new, lots of languages use a ',' rather than a '.' as the decimal separator and until last night I hadn't really thought through all the implications of that. For a bit of fun (in a dev geek sort of why) I wrote and published a Smartphone Conversion Application called "Convert It" and it seems to have been popular enough, around 800 downloads in 2 days.
Last night I spotted that a guy on a French Smartphone site was having problems with my app, it would throw a format exception on startup. Initially I thought it was just a date format problem and easy to fix but after setting the locale of my phone to "French(France)" and stepping through my code I discovered that the problem was with how I was storing floating point numbers.
I keep floating point ratios in XML as follows:-
<
Item Name="USD" Value="0.8307" />
I just did a System.Convert.ToDouble() and it worked just fine for me and life was good. What I hadn't realised was that if a user running the application had a different locale set then Convert.ToDouble() would throw an exception if the decimal place holder for the language wasn't the fullstop '.' character.
So I grabbed a copy of "Developing International Software" off my shelf (yes it really was there, ummm, but not well read until last night:-)) and finally figured how to store and retrieve numbers and dates in a culture neutral manner. It was actually really simple once I'd figured out what to do, but figuring out how simple it was took quite a bit of time...
using
System.Globalization;
private static CultureInfo Invc = CultureInfo.InvariantCulture; //InvariantCulture is the neutral culture
private static NumberFormatInfo nfi = (NumberFormatInfo)Invc.GetFormat(typeof(System.Globalization.NumberFormatInfo));
private static DateTimeFormatInfo dfi = (DateTimeFormatInfo)Invc.GetFormat(typeof(System.Globalization.DateTimeFormatInfo));
I changed
Convert.ToDouble(myfloatingPointNumberString)
to
double.Parse(myfloatingPointNumberString, nfi);
for the date string I changed from
System.Convert.ToDateTime(myDateString);
to
DateTime.Parse(myDateString, dfi);
I had to make a change to how I saved data to make that culturally neutral as well - simple enough...
did as follows:
thisCategory.item[index].itemValue.ToString(nfi);
and
thisCategory.dataDate.ToString(dfi));
Lessons learned:
- Test your app with different locales (under Regional Settings)
- When persisting number, dates etc - think about doing in a culture neutral way, it's actually really simple and may save you some pain
Btw, if you are thinking I could have just changed the thread culture then note you cant do that on the compact framework and anyway I don't think that would have been the right approach:-)
Cheers, dave
Comments
- Anonymous
October 12, 2005
For info on what I did to internationalise/Globalise then see http://blogs.msdn.com/dglover/archive/2005/10/13/480370.aspx - Anonymous
January 01, 2008
PingBack from http://movies.247blogging.info/?p=4776