Is there a faster way then to simply catch an exception like below?
try
{
date = new DateTime(model_.Date.Year, model_.Date.Month, (7 * multiplier) + (7 - dow) + 2);
}
catch (Exception)
{
// This is an invalid date
}
Is there a faster way then to simply catch an exception like below?
try
{
date = new DateTime(model_.Date.Year, model_.Date.Month, (7 * multiplier) + (7 - dow) + 2);
}
catch (Exception)
{
// This is an invalid date
}
String DateString = String.Format("{0}/{1}/{2}", model_.Date.Month, (7 * multiplier) + (7 - dow) + 2),model_.Date.Year);
DateTime dateTime;
if(DateTime.TryParse(DateString, out dateTime))
{
// valid
}
As the comment pointed out by GenericTypeTea, this code will not run any faster than what you have now. However, I believe you gain in readability.
I don't know about faster, but
DateTime.TryParse()
Should do the same thing.
I'd be interested if anyone can tell me if this is faster (in terms of processor time) than way described in the question.
you mean something like this? http://stackoverflow.com/questions/371987/validate-a-datetime-in-c
If the parsing mechanism is not any faster, then you can use the slightly more verbose method of checking the properties of your model object for valid values directly.
If your goal is to avoid using exceptions, you could write a custom validation method:
public bool IsValidDate(int year, int month, int multiplier, int dow)
{
if (year < 1 | year > 9999) { return false; }
if (month < 1 | month > 12) { return false; }
int day = 7 * multiplier + 7 - dow;
if (day < 1 | day > DateTime.DaysInMonth(year, month)) { return false; }
return true;
}
This performs most of the same validations as the DateTime constructor you're using - it only omits the check to see if the resulting DateTime would be less than DateTime.MinValue or greater than DateTime.MaxValue.
If you mostly get good values, this would probably be slower overall: DateTime.DaysInMonth has to do a lot of the same things the DateTime constructor does, so it would add overhead to all the good dates.
EDIT: Woops! DateTime.TryParse doesn't throw an exception internally. I was talking out my buttocks! Anyway...
If speed is imporant, you'll have to write your own method.DateTime.TryParse()
will throw an exception internally and will cause a result identical to your code in your question.
This may seem like more code, but I think it'll be faster if you're expecting a large volume of errors:
public bool GetDate(int year, int month, int day, out DateTime dateTime)
{
if (month > 0 && month <= 12)
{
int daysInMonth = DateTime.DaysInMonth(year, month);
if (day <= daysInMonth)
{
dateTime = new DateTime(year, month, day);
return true;
}
}
dateTime = new DateTime();
return false;
}
My above example won't handle all cases (i.e. I'm not handling years), but it'll point you in the right direction.
One thing though: Exceptions are for exceptional cases. Bogoformatted strings are not exceptional but expected, so TryParse is more appropriate.
Using try/catch for checking validness is misuse and misconception of exceptions, especially with a catch-all catch (the latter already caused me searching for hours for why something doesn't work, and that many times).
Hmm... think of it this way: the model_ class has a DateTime property
model_.Date
, so no need to validate the year & month. The only tricky part is the day of the month:
(7 * multiplier) + (7 - dow) + 2
So a very quick and efficient way to validate this (which is better than throwing and catching) is to use the DateTime.DaysInMonth method:
if ((multiplier <= 4) &&
(DateTime.DaysInMonth(model_.Date.Year, model_.Date.Month) <
(7 * multiplier) + (7 - dow) + 2))
{
// error: invalid days for the month/year combo...
}
Another benefit is that you don't need to instantiate a new DateTime just to validate this information.
P.S. Updated the code to ensure that multiplier is <= 4. That only makes sense, since any value >=5 will fail the DaysInMonth test...