Came across a curious problem. In our code the other day. I’ve come up with a quick fix, but I couldn’t help wondering if there was a better way of doing it.
The problem comes when parsing the string values submitted via QueryString into typed objects that eventually end up in a SQL stored procedure. For most eventual comparison types, comparing strings is fine, but to do “less than” or “greater than” and the like with dates, the string has to be converted to a date first.
So we were doing this – value is submitted into the function as a string after being pulled out of the querystring:
if (DateTime.TryParse(value, out newTime))
{
value = newTime.ToStringIsoUtc();
}
return value
Which worked fine for years, until someone tried to submit a three-part version number. Suddenly 1.3.1 became 2001-03-01 and the comparison stopped working.
My quick fix was just to check to see if there was more than one dot in the potential “date” and if so, leave it as a string. Easy. But the trouble is that while none of our clients currently use anything other than UTC date format, I got scared when I looked on Wikipedia and found how many countries use something like dd.mm.yy as a standard date format.
Is there a better way of telling an untyped version number from a date?
There is no way that you can do this with just the date value alone. What you really need is another value indicating what the format of the
DateTimein the querystring is.Take for example your
1.3.1format. Who is to say that it’s not really able to be interpreted as January 3rd, 2011 (looking at it from left-to-right as opposed to right-to-left).You have two options:
If you want a completely open value, you need a hint indicating how it should be interpreted (which you would use to adjust your call to set the options in the call to
DateTime.TryParse), along with the caveat that if the hint is not provided, then the results may be indeterminable when the input is ambiguousReject anything that isn’t in the expected format.
The first is preferable when dealing with user input, as you want to make it as easy as possible for your users and lower the bar to entry.
Note that if the user input is coming from say, a web page that uses HTML 5, you should be aware that the
inputtag allows fordateanddatetimeinput types. Not only does this have the benefit of allowing browsers to provide standardized (at least, across a platform) way of inputting this type of data, but it also provides for standardizing the format that data is transmitted in, meaning your input falls more into #2 than it does in #1.The second is preferable when When dealing calls made from APIs, as the DateTime instances (or representations of them) can be modified to fit your expectations (since they have a strongly typed representation in memory already before calling your API).