Share via


count complete month between two dates vb

Question

Thursday, January 11, 2018 9:56 AM

    Dim a As new DateTime = 16/10/2017
    Dim b As new DateTime = 10/11/2017

Label38.Text = DateDiff(DateInterval.Month, a, b).ToString & " months"

result 1month

but i want 0 unless one complete month

All replies (12)

Thursday, January 11, 2018 10:56 AM

but i want 0 unless one complete month

The rule for the DateDiff is "the return value for DateInterval.Month is calculated purely from the year and month parts of the arguments".  So if the months differ by 1 then the return value is 1.  If you want to implement a different rule then you need to consider the day of the month.  For instance, if the day of the month for the end date is less than the day of the month for the start date, then subtract 1 from the return value.


Thursday, January 11, 2018 12:10 PM | 1 vote

What is in your case the difference between 

the 29th of  February and the 30th of  March?

To show you, that telling that you want someting, does not mean it is possible without a well described rule. 

Success Cor


Thursday, January 11, 2018 1:41 PM

Hello,

Here is an example to try. What's missing is knowing how many days there are in a month when crossing months. It could be cleaned up a bit but what is here gets a point across.

The math is a tad off below which I noticed after posting but need to head off to work yet there are parts there to work from.

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim a As DateTime = New DateTime(2017, 10, 16)
        Dim b As DateTime = New DateTime(2017, 11, 10)

        Dim daysList As New List(Of Integer) From {28, 30, 31}
        Dim diffResult As Integer = DateDiff(DateInterval.Month, a, b)

        If diffResult > 1 Then
            Console.WriteLine($"{diffResult} months")
        Else
            If daysList.Contains(diffResult) Then
                Console.WriteLine($"{diffResult} month")
            Else
                Console.WriteLine("Less than a month")
            End If
        End If
    End Sub
End Class

You could also work off from

Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
VB Forums - moderator


Thursday, January 11, 2018 1:48 PM

Hello,

Here is an example to try. What's missing is knowing how many days there are in a month when crossing months. It could be cleaned up a bit but what is here gets a point across.

Karen,

Why you hide my reply with this. Now the real problem is never solved. It does not give the number of months exactly in the way the OP ask between the 29th of februari 2004 and 28 march 2012. That needs a rule and that is not available in your code  and also not given by the OP because then an answer is of course possible whatever it is. 

Success Cor


Thursday, January 11, 2018 1:57 PM

Hello,

Here is an example to try. What's missing is knowing how many days there are in a month when crossing months. It could be cleaned up a bit but what is here gets a point across.

Karen,

Why you hide my reply with this. Now the real problem is never solved. It does not give the number of months exactly in the way the OP ask between the 29th of februari 2004 and 28 march 2012. That needs a rule and that is not available in your code  and also not given by the OP because then an answer is of course possible whatever it is. 

Success Cor

Cor, I had no intent to do anything with your reply. Any ways I'm off to work so can't respond for a while.

Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
VB Forums - moderator


Thursday, January 11, 2018 2:00 PM

 but i want 0 unless one complete month

You must define a "complete month" (30 days ? 31 ?)

Then you can use TimeSpan to get the number of days and divide by 30 or 31 or ...

Dim a As New DateTime(2017, 10, 16)
Dim b As New DateTime(2017, 11, 10)

Dim ts As TimeSpan = b.Subtract(a)
Dim nNbDays As Integer = ts.TotalDays

Thursday, January 11, 2018 3:14 PM

Sorry for the mark/unmark, Castorix31, I mean you are right but the requirement was for number of months and you can't necessarily just divide total days...

I suspect that it would probably be sufficient to just assume the number of days in the month of the start date and use that as the initial minimum to check, only returning the normal result of DateDiff() when the check passes.  Something like:

    Public Function GetMonthsBetween(startDate As Date, endDate As Date) As Integer
        Dim daysInMonth As Integer = Date.DaysInMonth(startDate.Year, startDate.Month)
        Dim timeDiff = endDate.Subtract(startDate)
        If timeDiff.TotalDays >= daysInMonth Then Return DateDiff(DateInterval.Month, startDate, endDate)
        Return 0
    End Function

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Thursday, January 11, 2018 3:55 PM

Ajit,

Culture plays into this so if I have the dates correct then I have a class which will do what you want (let me know and I'll post it):

Public Class Form1
    Private Sub _
        Form1_Load(sender As System.Object, _
                   e As System.EventArgs) _
                   Handles MyBase.Load

        Dim date1 As New DateTime(2017, 10, 16)
        Dim date2 As New DateTime(2017, 11, 10)

        MessageBox.Show(New Age(date1, date2).ToString, "Result")

        Stop

    End Sub
End Class

"A problem well stated is a problem half solved.” - Charles F. Kettering


Thursday, January 11, 2018 5:58 PM

Try this fragment too:

Dim result As Integer = 0

While a.AddMonths(result + 1) <= b
   result += 1
End While

Friday, January 12, 2018 1:18 AM

Could not do this at work:

Well here is yet another version, take note of the array -> private monthDay.

Public Class CalculateDateDifference

    Private monthDay() As Integer = {31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

    Private fromDate As Date
    Private toDate As Date
    Private year As Integer
    Private month As Integer
    Private day As Integer
    Public Sub New(ByVal d1 As Date, ByVal d2 As Date)
        Dim increment As Integer

        If d1 > d2 Then
            fromDate = d2
            toDate = d1
        Else
            fromDate = d1
            toDate = d2
        End If

        increment = 0

        If fromDate.Day > toDate.Day Then
            increment = monthDay(fromDate.Month - 1)
        End If

        If increment = -1 Then
            If Date.IsLeapYear(Me.fromDate.Year) Then
                ' leap year february contain 29 days
                increment = 29
            Else
                increment = 28
            End If
        End If

        If increment <> 0 Then
            day = (toDate.Day + increment) - fromDate.Day
            increment = 1
        Else
            day = toDate.Day - fromDate.Day
        End If

        If (fromDate.Month + increment) > toDate.Month Then
            month = (toDate.Month + 12) - (fromDate.Month + increment)
            increment = 1
        Else
            month = (Me.toDate.Month) - (fromDate.Month + increment)
            increment = 0
        End If

        year = toDate.Year - (fromDate.Year + increment)

    End Sub
    Public Overrides Function ToString() As String
        Return year & " Year(s), " & month & " month(s), " & day & " day(s)"
    End Function
    Public ReadOnly Property Years() As Integer
        Get
            Return year
        End Get
    End Property
    Public ReadOnly Property Months() As Integer
        Get
            Return month
        End Get
    End Property
    Public ReadOnly Property Days() As Integer
        Get
            Return day
        End Get
    End Property
End Class

Use it

Dim startDate As DateTime = New DateTime(2017, 10, 16)
Dim endDate As DateTime = New DateTime(2017, 11, 10)

Dim dOps As New CalculateDateDifference(startDate, endDate)
Console.WriteLine($"Months between: {dOps.Months} The full monty: {dOps.ToString}")

Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
VB Forums - moderator


Friday, January 12, 2018 2:37 AM

@Karen,

A lot of work and still there is not first taken a decision. Because the length of a month in days can be based on:

  1. The first month
  2. The Second month
  3. The total days of both month's/2
  4. 30 days

And then a kind of Viorel solution can be done. 

:-)

Success Cor


Friday, January 12, 2018 3:19 AM | 1 vote

Hi AJIT,

I recommend you to use NodaTime library to do this. Firstly you install NodaTime library using NuGet Packages.., then take a look the following:

Dim start As LocalDate = New LocalDate(2009, 10, 6)
        Dim [end] As LocalDate = New LocalDate(2009, 12, 5)
        Dim period As Period = Period.Between(start, [end])
        Dim months As Integer = period.Months

You will get complete month between two dates.

Best Regards,

Cherry

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].