2
mnth = DateDiff(DateInterval.Month, 8/30/2012, 10/1/2012) 

gives mnth = 2. But when we look, there is only 32 days between these dates. I am expecting a result mnth=1 as there is only 32 days between these days.

Pls help..

In my scenario i can consider a 15+ days to be a month but if it is less than 15, it should'nt be considered.

8
  • Why? 32 days is 1 month plus an extra day. It's not going to just assume you don't care about that extra month. Commented Oct 2, 2012 at 13:14
  • wht should i do then?? i need to get the number of complete months here.. :( Commented Oct 2, 2012 at 13:16
  • 3
    What you should do is give a specification of what you expect your function to return which is not trivial. E.g. most people would agree that April 1 to May 1 or May 31 to June 30 both span an entire month. But what for April 30 to May 30 or April 15 to May 15? Commented Oct 2, 2012 at 13:47
  • 1
    What is the definition of 'complete month'? 30 days or 31 days (not to mention 28/29 days)? It is a fixed constant or should change depending on the starting/Ending month? Commented Oct 2, 2012 at 14:00
  • 1
    @Hybridzz, if you make a logical specification, it can be written. Edit the question accordingly. Commented Oct 2, 2012 at 14:14

5 Answers 5

4

To get the number of complete months you can do different things depending on your interpretation,

Public Function CompleteMonthsBetweenA( _ ByVal start As DateTime, _ ByVal end As DateTime) As Integer Dim invertor = 1 If (start > end) Then Dim tmp = end end = start start = tmp invertor = -1 End If Dim diff = ((end.Year - start.Year) * 12) + end.Month - start.Month If start.Day > end.Day Then Return (diff - 1) * invertor Else Return diff * invertor End If End Function 

With this function the number of complete months between 31/05/2011 (dd/mm/yy) and 30/06/2011 is 0 but between 30/06/2011 and 31/07/2011 is 1. Which may or may not be what you expect.


Public Function CompleteMonthsBetweenB( _ ByVal start As DateTime, _ ByVal end As DateTime) As Integer Dim invertor = 1 If (start > end) Then Dim tmp = end end = start start = tmp invertor = -1 End If Dim diff = ((end.Year - start.Year) * 12) + end.Month - start.Month Dim startDaysInMonth = DateTime.DaysInMonth(start.Year, start.Month) Dim endDaysInMonth = DateTime.DaysInMonth(end.Year, end.Month) If (start.Day / startDaysInMonth) > (end.Day / endDaysInMonth) Then Return (diff - 1) * invertor Else Return diff * invertor End If End Function 

With this function the ratio Day / DaysInMonth is taken so the relative completion of the two months can be assessed.


Public Function CompleteMonthsBetweenC( _ ByVal start As DateTime, _ ByVal enddate As DateTime) As Integer Dim invertor = 1 If (start > enddate) Then Dim tmp = enddate enddate = start start = tmp invertor = -1 End If Dim diff = ((enddate.Year - start.Year) * 12) + enddate.Month - start.Month Dim remainingDays = _ (DateTime.DaysInMonth(start.Year, start.Month) - start.Day) + enddate.Day If remainingDays < 15 Then Return (diff - 1) * invertor Else Return diff * invertor End If End Function 

This function only rounds down if the surplus days are less than the magic number 15, which I think is what you are asking for in your update.


Public Function CompleteMonthsBetweenD( _ ByVal start As DateTime, _ ByVal end As DateTime) As Integer Return end.Subtract(start).TotalDays \ 30.436875 End Function 

This function takes the simpler approach of dividing the total number of days by the average number of days per month in the Gregorian Calendar.

Sign up to request clarification or add additional context in comments.

7 Comments

@Hybridzz, that should do it.
@Hybridzz, it does of course depend on what you are expecting.
ok.. for me i can take a 15+ days to be a month. I surely appreciate ur effort.
The null checks don't add much value. DateTime is a value type, it cannot be null.
@Hybridzz, so did you get your answer?
|
2

The difference in months is calculated without regard to the day component of the dates.

For example, the difference in months between 8/31/2012 and 9/1/2012 is 1, eventhough it's only one day between the dates.

If you want to consider the day component you have to get the date difference in days instead of months, and calculate how many months you want that to be.

1 Comment

oh ok.. :( so can u give an exact solution that can be applied..??
1

This is the class I use (it's C# but really easy to convert to VB.NET). It is usefull for years, months, days... it is ideal for displaying ages in #Y-#M-#D format.

public class DateDifference { /// <summary> /// defining Number of days in month; index 0=> january and 11=> December /// february contain either 28 or 29 days, that's why here value is -1 /// which wil be calculate later. /// </summary> private int[] monthDay = new int[12] { 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /// <summary> /// contain from date /// </summary> private DateTime fromDate; /// <summary> /// contain To Date /// </summary> private DateTime toDate; /// <summary> /// this three variable for output representation.. /// </summary> private int year; private int month; private int day; public DateDifference(DateTime d1, DateTime d2) { int increment; if (d1 > d2) { this.fromDate = d2; this.toDate = d1; } else { this.fromDate = d1; this.toDate = d2; } /// /// Day Calculation /// increment = 0; if (this.fromDate.Day > this.toDate.Day) { increment = this.monthDay[this.fromDate.Month - 1]; } /// if it is february month /// if it's to day is less then from day if (increment == -1) { if (DateTime.IsLeapYear(this.fromDate.Year)) { // leap year february contain 29 days increment = 29; } else { increment = 28; } } if (increment != 0) { day = (this.toDate.Day + increment) - this.fromDate.Day; increment = 1; } else { day = this.toDate.Day - this.fromDate.Day; } /// ///month calculation /// if ((this.fromDate.Month + increment) > this.toDate.Month) { this.month = (this.toDate.Month + 12) - (this.fromDate.Month + increment); increment = 1; } else { this.month = (this.toDate.Month) - (this.fromDate.Month + increment); increment = 0; } /// /// year calculation /// this.year = this.toDate.Year - (this.fromDate.Year + increment); } public override string ToString() { //return base.ToString(); return this.year + " Year(s), " + this.month + " month(s), " + this.day + " day(s)"; } public int Years { get { return this.year; } } public int Months { get { return this.month; } } public int Days { get { return this.day; } } } 

USAGE:

DateDifference diff = new DateDifference(date1, date2); int months = (diff.Years*12) + diff.Months + diff.Days > 15 ? 1 : 0; 

5 Comments

This doesen't actually answer the question, just tries to recreate the functionality that is present in DateTime.DaysInMonth
@Jodrell, it really answer the question... but I agree with you that some parts of the code could use the DayInMonths. Use it and compare results with other methods.
Well, it is an overkill to the question... it is more helpful in more accurate scenaries.
strAge isn't a number of whole months. You could argue it is a more sensible answer than a bare number but TimeSpan is better still.
There you have a more explicit usage... I think it answer what user wanted. ;)
0

If you want the number of complete month, then you'll need to compare date that starts at the begining of the closet month.

Sub Main() ' mnth = DateDiff(DateInterval.Month, 8/30/2012, 10/1/2012) Console.WriteLine(GetCompleteMonthCount(New DateTime(2012, 8, 30), New DateTime(2012, 10, 1))) Console.ReadLine() End Sub Public Function GetCompleteMonthCount(ByVal d1 As DateTime, ByVal d2 As DateTime) As Integer If d1.Day <> 1 Then d1 = d1.AddMonths(1) d1 = New DateTime(d1.Year, d1.Month, 1) End If If d2.Day <> 1 Then d2 = New DateTime(d2.Year, d2.Month, 1) End If Return DateDiff(DateInterval.Month, d1, d2) End Function 

1 Comment

Is 01/01/1970 to 31/01/1970 a complete month? It all rather depends on your expectation.
-1

The solutions above are all very good but perhaps a little over-complicated, how about

Function wholeMonthsEd(d1, d2) As Integer ' determine the DateDiff function output ' which gives calendar month difference initMonths = DateDiff("m", d1, d2) ' do calcs on the Day of the month to deduct/not a calendar month If Day(d2) < Day(d1) Then initMonths = initMonths - 1 End If wholeMonths = initMonths End Function 

1 Comment

This doesnt work well, please check dotnetfiddle.net/5vFprF

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.