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.Substrin开发者_开发百科g(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?
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;
}
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));
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
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?
精彩评论