tags:

views:

135

answers:

4

Can anyone please explain what the following code checks for? I can make no sense of it, but don't want to leave it out of my rewrite merely out of ignorance. The complete code calculates a variance between now and detailLastDate, i.e. Days(detailLastDate) - Days(Now). For this case, detailLastDate has the value '090722':

int num3 = 0;
num3 = int.Parse(detailLastDate.Substring(0, 1) + int.Parse(detailLastDate.Substring(1, 1) + int.Parse(detailLastDate.Substring(2, 1) + int.Parse(detailLastDate.Substring(3, 1) + int.Parse(detailLastDate.Substring(4, 1) 
    + int.Parse(detailLastDate.Substring(0, 1) + int.Parse(detailLastDate.Substring(1, 1) + int.Parse(detailLastDate.Substring(2, 1) + int.Parse(detailLastDate.Substring(3, 1) + int.Parse(detailLastDate.Substring(5, 1);
if (num3 == 0)
{
    detailLastDate = "991231";
}

ADDED: What puzzles me is why it parses chars 0 to 3 twice.

+1  A: 

It looks like its checking to see if the date is all zeroes, and if it is, default it to 991231 (December 31st, 1999?)

Brandon
+5  A: 

Well, no wonder you can't make sense of it, because it makes no sense :)

Primarily, it's purpose seems to be to check if the passed date is "000000". It also checks if all the digits are in fact numeric however. There would be an exception if they weren't. There would also be an exception if the length of the string was less than 6.

If the date is "000000", it will default to "991231".

This should be mostly equivalent, assuming num3 is not used for other weird comparisons:

int num3;
if (detailLastDate.Length != 6 || !Int32.TryParse(detailLastDate, out num3))
    throw new FormatException("Invalid date");

if (num3 == 0)
    detailLastDate = "991231";

It will also error on string that are too long (unlike your code snippet), but I consider that a good thing. Personally I'd get rid of the integer parsing altogether, but I guess it works :)

If you want to do some refactoring the proper way, take a look at CMS' answer. Just be sure the surrounding code does not rely on the side effects I described.

Thorarin
If all you need to compare against is 0, then you don't really need any elaborate code, just this: if (detailLastDate == "000000")
Lasse V. Karlsen
Did you actually read what I wrote? I'm trying to point out possible pitfalls in refactoring this. I've provided a relatively safe replacement to use. If you're just going for clean code and side effects are irrelevant, then yes. OP will be the best judge of that, as he has all the code. Then again, if it were **good** code, why is the date in a string in the first place?
Thorarin
I'm going to get read of all parsing and use proper damn date fields, but I was wondering if there was any reason the 'checksum' includes digits 0 to 3 twice.
ProfK
it might be worth it to hanlde 6 and 8 digits (in case some one at some point passes something like YYYYMMDD instead of YYMMDD. Did any one say Y2K bug?) but nice explanation and worth an up vote
Rune FS
+2  A: 

You could parse the date according to the format yyMMdd, and see if the conversion succeeded using the DateTime.TryParseExact method.

An example:

//...
string detailLastDate = "090722";
DateTime lastDate;

if (!DateTime.TryParseExact(detailLastDate, "yyMMdd",
                CultureInfo.InvariantCulture, DateTimeStyles.None, out lastDate))
{
    // input doesn't match the format
    lastDate = new DateTime(1999, 12, 31); // default value 991231
}
//...
return (lastDate - DateTime.Today).Days;
CMS
Yeah, that would be the most sensible solution. The original code has a number of side effects that this code doesn't however. You will need to make sure the surrounding code doesn't rely on those side effects. That's why I posted my "mostly equivalent" code.
Thorarin
You need MM for months - currently you're parsing year, *minute* and day.
Jon Skeet
Thanks @Jon didn't noticed
CMS
The most sensible solution is to get rid of the scourge of storing dates in string fields. I just needed to know this 'checksum' did nothing before going ahead and ripping all date parsing out forever.
ProfK
+1  A: 

Well, first of all the code doesn't compile as the parentheses doesn't match. What does the original code look like?

If you add parentheses, the code still doesn't make much sense. It's parsing a character at a time and most characters more than once, when it could just parse the entire string instead.

If you know that the string is always six characters and always contains digits, you don't need the extra verification that the code gives by parsing the string, and you can just replace it with:

if (detailLastDate == "000000") detailLastDate = "991231";
Guffa