Svish
Svish

Reputation: 158241

C#: How to simplify this string-of-numbers-to-various-date-parts-code

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?

Upvotes: 3

Views: 461

Answers (4)

Jason Too Cool Webs
Jason Too Cool Webs

Reputation: 133

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?

Upvotes: 0

asbestossupply
asbestossupply

Reputation: 11919

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

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1039318

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;    
}

Upvotes: 7

Jake Pearson
Jake Pearson

Reputation: 27737

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));

Upvotes: 0

Related Questions