views:

122

answers:

4

I have a string that might be between 1 and 8 characters long. I need to convert those into a day, a month and a year. For missing parts I will use the current one.

The code I have now is kind of big and ugly, and I was wondering if someone have a more clever idea on how to do this.

My current code is listed below:

var day = DateTime.Now.Day;
var month = DateTime.Now.Month;
var year = DateTime.Now.Year;

switch (digits.Length)
{
    case 1:
    case 2:
        day = int.Parse(digits.Substring(0));
        break;

    case 3:
    case 4:
        day = int.Parse(digits.Substring(0, 2));
        month = int.Parse(digits.Substring(2));
        break;
    case 5:
    case 6:
    case 7:
    case 8:
        day = int.Parse(digits.Substring(0, 2));
        month = int.Parse(digits.Substring(2, 2));
        year = int.Parse(digits.Substring(4));
        break;
    default:
        break;
}

Note: I know this isn't taking culture into consideration, but it is not supposed to :)

I tried to do it like this:

day = int.Parse(digits.Substring(0, 2));
if(digits.Length > 2)
    month = int.Parse(digits.Substring(2, 2));
if(digits.Length > 4)
    year = int.Parse(digits.Substring(4, 4));

But it will throw an ArgumentOutOfRangeException if the string is 1, 3, 5, 6 or 7 digits long... so that didn't work so well. If only the Substring method would have just taken as many letters as it could instead of failing when there were not enough letters to "fill" the substring...

Could regular expressions maybe be used for this?

A: 

You could get your second snippet to work if you pad the right side of the digits string with a bit of whitespace:

digits += " ";
day = int.Parse(digits.Substring(0, 2));
if(digits.Length > 2)
    month = int.Parse(digits.Substring(2, 2));
if(digits.Length > 4)
    year = int.Parse(digits.Substring(4, 4));
Jake Pearson
+7  A: 

Look at the TryParseExact method.

DateTime date;
if (DateTime.TryParseExact(
    digits, 
    new[] { "dd", "ddMM", "ddMMyyyy" }, 
    CultureInfo.InvariantCulture, 
    DateTimeStyles.None, 
    out date))
{
    int day = date.Day;
    int month = date.Month;
    int year = date.Year;    
}
Darin Dimitrov
Now, see that is brilliant! Never really used that method before actually. Thank you!
Svish
A: 

Regex might be a good solution. Off the top of my head this might look like:

^([0-9]{1,2})([0-9]{1,2})?([0-9]{1,4})?

which would provide up to 4 groups, indexed like: 0 - the entire string 1 - the first 2 digits (1 if there's only 1 digit) 2 - the second pair of digits (1 if there's only 3 digits) 3 - the last set of 1-4 digits

statichippo
A: 

So for the program the first two numbers will also be a day and not a day month like 38 day = 3, month = 8? The day would always be zero leading for under 10?

Jason Too Cool Webs
Pretty much. Good point. Could probably have made it better to deal with that, but when I was making it was already a bit too complicated :p How would do it to support that? All I can think of is a very ugly jungle of if statements :p
Svish