如何在c#中计算两个日期之间的月差?
c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:
TimeSpan ts = date1 - date2;
但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。
有什么建议吗?
如何在c#中计算两个日期之间的月差?
c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:
TimeSpan ts = date1 - date2;
但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。
有什么建议吗?
当前回答
如果您想要完整月份的确切数目,总是正的(2000-01-15,2000-02-14返回0),则考虑完整月份是当您到达下个月的同一天时(类似于年龄计算)
public static int GetMonthsBetween(DateTime from, DateTime to)
{
if (from > to) return GetMonthsBetween(to, from);
var monthDiff = Math.Abs((to.Year * 12 + (to.Month - 1)) - (from.Year * 12 + (from.Month - 1)));
if (from.AddMonths(monthDiff) > to || to.Day < from.Day)
{
return monthDiff - 1;
}
else
{
return monthDiff;
}
}
编辑原因:旧代码在某些情况下不正确,如:
new { From = new DateTime(1900, 8, 31), To = new DateTime(1901, 8, 30), Result = 11 },
Test cases I used to test the function:
var tests = new[]
{
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 1, 1), Result = 0 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 1, 2), Result = 0 },
new { From = new DateTime(1900, 1, 2), To = new DateTime(1900, 1, 1), Result = 0 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 2, 1), Result = 1 },
new { From = new DateTime(1900, 2, 1), To = new DateTime(1900, 1, 1), Result = 1 },
new { From = new DateTime(1900, 1, 31), To = new DateTime(1900, 2, 1), Result = 0 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1900, 9, 30), Result = 0 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1900, 10, 1), Result = 1 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1901, 1, 1), Result = 12 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1911, 1, 1), Result = 132 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1901, 8, 30), Result = 11 },
};
其他回答
Public Class ClassDateOperation
Private prop_DifferenceInDay As Integer
Private prop_DifferenceInMonth As Integer
Private prop_DifferenceInYear As Integer
Public Function DayMonthYearFromTwoDate(ByVal DateStart As Date, ByVal DateEnd As Date) As ClassDateOperation
Dim differenceInDay As Integer
Dim differenceInMonth As Integer
Dim differenceInYear As Integer
Dim myDate As Date
DateEnd = DateEnd.AddDays(1)
differenceInYear = DateEnd.Year - DateStart.Year
If DateStart.Month <= DateEnd.Month Then
differenceInMonth = DateEnd.Month - DateStart.Month
Else
differenceInYear -= 1
differenceInMonth = (12 - DateStart.Month) + DateEnd.Month
End If
If DateStart.Day <= DateEnd.Day Then
differenceInDay = DateEnd.Day - DateStart.Day
Else
myDate = CDate("01/" & DateStart.AddMonths(1).Month & "/" & DateStart.Year).AddDays(-1)
If differenceInMonth <> 0 Then
differenceInMonth -= 1
Else
differenceInMonth = 11
differenceInYear -= 1
End If
differenceInDay = myDate.Day - DateStart.Day + DateEnd.Day
End If
prop_DifferenceInDay = differenceInDay
prop_DifferenceInMonth = differenceInMonth
prop_DifferenceInYear = differenceInYear
Return Me
End Function
Public ReadOnly Property DifferenceInDay() As Integer
Get
Return prop_DifferenceInDay
End Get
End Property
Public ReadOnly Property DifferenceInMonth As Integer
Get
Return prop_DifferenceInMonth
End Get
End Property
Public ReadOnly Property DifferenceInYear As Integer
Get
Return prop_DifferenceInYear
End Get
End Property
End Class
我在VB中检查了这个方法的用法。NET通过MSDN,它似乎有很多用途。c#中没有这样的内置方法。(即使这不是一个好主意)你可以在c#中调用VB。
将Microsoft.VisualBasic.dll添加到 你的项目作为参考 使用 Microsoft.VisualBasic.DateAndTime.DateDiff 在代码中
var dt1 = (DateTime.Now.Year * 12) + DateTime.Now.Month;
var dt2 = (DateTime.Now.AddMonths(-13).Year * 12) + DateTime.Now.AddMonths(-13).Month;
Console.WriteLine(dt1);
Console.WriteLine(dt2);
Console.WriteLine((dt1 - dt2));
在这个问题上没有很多明确的答案,因为你总是在假设事情。
这个解决方案在两个日期之间进行计算,假设您想保存一个月中的某一天进行比较,(这意味着在计算中考虑了这个月中的某一天)
例如,如果你的日期是2012年1月30日,2012年2月29日就不是一个月,但2013年3月1日就不是一个月。
它经过了相当彻底的测试,可能稍后我们会在使用时清理它,但这里:
private static int TotalMonthDifference(DateTime dtThis, DateTime dtOther)
{
int intReturn = 0;
bool sameMonth = false;
if (dtOther.Date < dtThis.Date) //used for an error catch in program, returns -1
intReturn--;
int dayOfMonth = dtThis.Day; //captures the month of day for when it adds a month and doesn't have that many days
int daysinMonth = 0; //used to caputre how many days are in the month
while (dtOther.Date > dtThis.Date) //while Other date is still under the other
{
dtThis = dtThis.AddMonths(1); //as we loop, we just keep adding a month for testing
daysinMonth = DateTime.DaysInMonth(dtThis.Year, dtThis.Month); //grabs the days in the current tested month
if (dtThis.Day != dayOfMonth) //Example 30 Jan 2013 will go to 28 Feb when a month is added, so when it goes to march it will be 28th and not 30th
{
if (daysinMonth < dayOfMonth) // uses day in month max if can't set back to day of month
dtThis.AddDays(daysinMonth - dtThis.Day);
else
dtThis.AddDays(dayOfMonth - dtThis.Day);
}
if (((dtOther.Year == dtThis.Year) && (dtOther.Month == dtThis.Month))) //If the loop puts it in the same month and year
{
if (dtOther.Day >= dayOfMonth) //check to see if it is the same day or later to add one to month
intReturn++;
sameMonth = true; //sets this to cancel out of the normal counting of month
}
if ((!sameMonth)&&(dtOther.Date > dtThis.Date))//so as long as it didn't reach the same month (or if i started in the same month, one month ahead, add a month)
intReturn++;
}
return intReturn; //return month
}
除了所有给出的答案,我发现这段代码非常简单。DateTime。MinValue是1/1/1,我们必须从月,年和日减去1。
var timespan = endDate.Subtract(startDate);
var tempdate = DateTime.MinValue + timespan;
var totalMonths = (tempdate.Year - 1) * 12 + tempdate.Month - 1;
var totalDays = tempdate.Day - 1;
if (totalDays > 0)
{
totalMonths = totalMonths + 1;
}