Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing DateTime on Localized Systems

Tags:

c#

.net

datetime

We have a web application that produces reports. Data are taken from a database.

When we ran the web application on a localized system, it blows up. We traced the problem on a DateTime.Parse(dateString); call.

The dates stored in the database is somewhat dependent on the locale of the machine.

On an English system, the date is stored as MM/DD/YYYY (06/25/2009) which is perfectly normal.

On a Russian system, the date is stored as MM.DD.YYYY (06.25.2009). This is weird because the default setting (I checked) for Short Date format in Russian Systems is dd.MM.yyyyy... So it should be 25.06.2009. I don't it get why it accepted the default separator (.) but not the default date format.

So anyway, how can I parse the date string on a localized system? If I use the Russian cultureinfo, it would still throw an error since it is expecting dd.MM.yyyyy.

Thanks!

like image 681
Ian Avatar asked Dec 18 '22 07:12

Ian


2 Answers

You should never store a localized date string in the database.

You must store dates in date columns and then localize the data at the moment of showing it.

1. Set the locale of your site UI

This example set the lang according to the request path, but may have other mechanism.

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
    Dim lang As String
    If HttpContext.Current.Request.Path.Contains("/en/") Then
        lang = "en" 'english'
    ElseIf HttpContext.Current.Request.Path.Contains("/pt/") Then
        lang = "pt" 'portugues'
    Else
        lang = "es" 'español, the default for the site'
    End If
    Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang)
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang)

End Sub

2. Get the input to date variables

Getting the data from the text input is easy, this is an example, but with a date validator you should be ok.

dim theDate as date
if IsDate( txtDate.text ) then
   theDate = DateTime.Parse(txtDate.text)
else
   'throw exception or something
end if

Edit

Since you say you can't change the way it is stored, you are in big trouble, unless you have in the db record some way to tell the format of the date. The problem is not the separators, but when you find a date like 6/3/2009 you dont know if it is 6 of march or 3 of june.

like image 123
Eduardo Molteni Avatar answered Jan 09 '23 01:01

Eduardo Molteni


At the database, if you must store it as text, you should standardize the format. Even better, though, store it as datetime, and there is nothing to parse - just read it out from the database as a date...

If you have a string, use the known culture (perhaps the invariant culture) when parsing:

DateTime when = DateTime.Parse(s, CultureInfo.InvariantCulture);
like image 29
Marc Gravell Avatar answered Jan 08 '23 23:01

Marc Gravell