views:

122

answers:

5

I have an internal business process that my finance dept runs. To kick it off they input a Date in the format of yyyyMM or 201009. I want to check for a valid date from that string but so far I got nothing.

I am currently exploring breaking the string up, taking the first 4 and checking that they are between 1990 and 2050(as example) and then the last 2 and checking that it is between 01 and 12.

Is there a better way?

+11  A: 

You can use DateTime.TryParseExact to see if it can be parsed correctly:

bool isValid = false;
DateTime dateValue;
if(DateTime.TryParseExact("201009", "yyyyMM", CultureInfo.InvariantCulture, 
                       DateTimeStyles.None, out dateValue))
{
   // DateTime parsed, dateValue contains the parsed DateTime

   // Can validate dateValue against business rules at this point
   isValid = (dateValue <= DateTime.Now && dateValue >= DateTime.Now.AddYears(-5));
}

If you would rather get an exception, you can use DateTime.ParseExact:

// Next line throws exception if format not correct
DateTime.ParseExact("201009", "yyyyMM", CultureInfo.InvariantCulture);
Oded
This accepts dates like "000101" and "999901", so you would still have to check if the year is a reasonable value...
Guffa
@Guffa - Good point. The OP needs to be more explicit as to what makes a valid date for his application.
Oded
Thanks for this, small follow up question. Will the following give me what I expect; which is a `TRUE` result if the `dateValue` is not in the future AND is no more then 1 year in the past? `isValid = ((dateValue <= DateTime.Today) `
Refracted Paladin
@Refracted Paladin - The second part of the boolean expression does not make sense - you are adding the parsed year to next year (for example 2010 + 2011 and checking if the result is less than this year, which it will never be). Try `isValid = ((dateValue <= DateTime.Today) ` - the second clause check that the parsed date is greater than a year ago.
Oded
A: 

The problem here is that the format "yyyyMM" cannot represent a specific DateTime. So the parsing methods built in to DateTime will do you no good.

Update: Never mind; I stand corrected. DateTime.TryParseExact will work just fine (which is ironic, if you ask me); it'll interpret your string to represent the first day of the given month.

I would do what you're describing: parsing the string into the two numeric components and simply compare those values to whatever range you require them to fall within.

Dan Tao
`TryParse` does not work for 201009 (yyyyMM), but `TryParseExact` does.
Anthony Pegram
@Anthony: Right, my bad. Totally what I meant to say.
Dan Tao
+1  A: 

I would go with DateTime.ParseExact:

DateTime d = DateTime.ParseExact("201009", "yyyyMM", System.Globalization.CultureInfo.InvariantCulture);
Torbjörn Hansson
+4  A: 

You can use a regular expression:

if (Regex.IsMatch(input, @"^(199\d|20[0-5]\d)(0[1-9]|1[0-2])$")) {
  // valid input between 199001 and 205912
}
Guffa
Plus 1 for regex validation. This is what I was going to suggest.
roviuser
A: 

I'd be tempted perform this as a number range problem:

UInt32 val;
if (input.Length != 6
   || !UInt32.TryParse(input, out val)
   || val > 205012
   || val < 199001
   || val % 100 > 12
   || val % 100 == 0) {
  // Invalid...
}
Richard