user2225988
user2225988

Reputation: 41

Check the number of days is right for each month

Hey guys I currently have a sub routine that I had hoped would take the day and the month of a date. Then check to see which month it is and if the number of days is right for that month

Here is what i currently have: Month and day are the input month and day respectively

        If Month = 4 Or 6 Or 9 Or 11 Then
            If (1 <= Day) AndAlso (Day <= 30) Then
                DateOkay= True
            End If
        End If


        If Month = 2 Then
            If (1 <= Day) AndAlso (Day <= 28) Then
                DateOkay = True
            End If
        End If


        If Month = 1 Or 3 Or 5 Or 7 Or 8 Or 10 Or 12 Then
            If (1 <= Day) AndAlso (Day <= 31) Then
                DateOkay = True
            End If
        End If

At the moment the dateOkay returns okay for any month as long as the input for days is <=31. Is there a simpler way of doing this?

Thanks in advance

Upvotes: 2

Views: 2086

Answers (3)

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67217

This method let you to check the whole date, and it removes the neccessity to split the whole date in to day,month,year. You can try this,

  Dim xdate As String = "20-02-2013"
  DateOkay = if(IsDate(xdate),true,false) 'This will return true

  xdate = "30-02-2013"
  DateOkay = if(IsDate(xdate),true,false) 'This will return false

EDIT:

If you want to display a generic validation message to the users like 'Invalid date.!', you can follow this method, else if you want to display unique message like 'Invalid Day.!', then you can use DaysInMonth as LarsTech suggested.

Upvotes: 0

Tim
Tim

Reputation: 28530

I feel that Larstech's answer is the best (assuming you're using a DateTime initially, not just integers for month and day, or have some other way of getting the year as well).

I'm posting an answer to explain why your code isn't working the way you expect. The reason youre code is giving you problems is that you're conditional tests on Month are incorrect and will always return true, which means your inner IF statement executes.

If Month = 4 Or 6 Or 9 Or 11 Then

6, 9, and 11 will all evaluate to true, making the whole if check true (I believe any non-zero integer value will evaluate to true in VB.NET, but haven't been able to dig up a link to substantiate it. Testing on my machine in VS 2012 supports that, as well as some other discussions I've seen, however).

So what is happening is that the last if block (as you have it written) for the month will always evaluate to True, and as long as the day is 1 to 31 dateOkay will evaluate to true, no matter what the actual month is.

What you should do is this:

If Month = 4 Or Month = 6 Or Month = 9 Or Month = 11 Then

This will evaluate as you expect it to, and the rest or your code will work as expected.

I would recommend using OrElse instead of Or, which will enable you to perform short-circuit evaluation similar to the AndAlso you used. In other words, as soon as one of the conditional tests in the if statement using OrElse evaluates to true, the rest of the conditional tests will be ignored. AndAlso will not evaluate any additional conditional tests once it encounters a False result.

In comparison, And and Or will evaluate all the tests, regardless of outcome. For example, If Month = 1 Or Month = 3 Or Month = 4 Then will run each of the individual tests, even if Month is 1.

Finally, if you're not setting dateOkay before evaluating the date, I would set it explicitly to False before the evaluation. Putting it altogether you'd get something like this:

dateOkay = False

If Month = 4 OrElse Month = 6 OrElse Month = 9 OrElse Month = 11 Then
    If (1 <= Day) AndAlso (Day <= 30) Then
        DateOkay= True
    End If
End If

If Month = 2 Then
    If (1 <= Day) AndAlso (Day <= 28) Then
        DateOkay = True
    End If
End If

If Month = 1 OrElse Month = 3 OrElse Month = 5 OrElse Month = 7 OrElse Month = 8 OrElse Month = 10 OrElse Month = 12 Then
    If (1 <= Day) AndAlso (Day <= 31) Then
        DateOkay = True
    End If
End If

Again, however, Larstech's answer is the best to your question " Is there a simpler way of doing this?".

Upvotes: 0

LarsTech
LarsTech

Reputation: 81675

Because of Leap Year, you really need the year, too. There is a built in function to provide that:

Dim numDays As Integer = DateTime.DaysInMonth(Now.Year, Now.Month)

dateOkay = (day <= numDays)

Upvotes: 4

Related Questions