如何在c#中计算两个日期之间的月差?
c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:
TimeSpan ts = date1 - date2;
但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。
有什么建议吗?
如何在c#中计算两个日期之间的月差?
c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:
TimeSpan ts = date1 - date2;
但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。
有什么建议吗?
当前回答
在我的情况下,需要计算从开始日期到下个月这一天的前一天或从月初到月底的完整月份。
例如:从1/1/2018到31/1/2018是一个完整的月 例2:从5/1/2018到4/2/2018是一个完整的月
基于此,我的解决方案如下:
public static DateTime GetMonthEnd(DateTime StartDate, int MonthsCount = 1)
{
return StartDate.AddMonths(MonthsCount).AddDays(-1);
}
public static Tuple<int, int> CalcPeriod(DateTime StartDate, DateTime EndDate)
{
int MonthsCount = 0;
Tuple<int, int> Period;
while (true)
{
if (GetMonthEnd(StartDate) > EndDate)
break;
else
{
MonthsCount += 1;
StartDate = StartDate.AddMonths(1);
}
}
int RemainingDays = (EndDate - StartDate).Days + 1;
Period = new Tuple<int, int>(MonthsCount, RemainingDays);
return Period;
}
用法:
Tuple<int, int> Period = CalcPeriod(FromDate, ToDate);
注意:在我的情况下,需要计算完整月份之后的剩余天数,所以如果不是你的情况,你可以忽略天数结果,甚至可以将方法返回值从元组更改为整数。
其他回答
能够计算以月为单位的两个日期之间的差异是一件非常符合逻辑的事情,并且在许多业务应用程序中都需要它。这里的几个程序员提供了一些评论,比如“2010年5月1日”和“2010年6月16日”之间的月份有什么不同,2010年12月31日和2011年1月1日之间的月份有什么不同?——无法理解商业应用的基本知识。
以下是以上2条评论的答案——2010年5月1日至2010年6月16日之间的月数为1个月,2010年12月31日至2011年1月1日之间的月数为0。如上面的程序员所建议的那样,将它们计算为1.5个月零1秒是非常愚蠢的。
从事过信用卡、抵押贷款处理、税务处理、租金处理、每月利息计算和其他各种业务解决方案的人会同意这一点。
问题是c#或VB中不包含这样的函数。NET。Datediff只考虑年份或月份组件,因此实际上是无用的。
下面是一些现实生活中的例子,你需要正确地计算月份:
你从2月18日到8月23日住在短租公寓里。你在那里呆了几个月?答案很简单——6个月
你有一个银行账户,每月月底计算并支付利息。您在6月10日存入,同年10月29日取出。你有多少个月的利息?非常简单的答案——4个月(额外的日子也没关系)
在业务应用中,大多数情况下,当您需要计算月份时,是因为您需要根据人类计算时间的方式了解“完整的”月份;而不是基于一些抽象/无关的想法。
单线解决方案
首先,检查两个日期是否都在当前年份,如果不是,则获取全年的月份,然后从年初和年末添加月份。
DateTime dateFrom = new DateTime(2019, 2, 1);
DateTime dateTo = new DateTime(2021, 5, 25);
第一个月
var monthCount = dateFrom.Year != dateTo.Year ? ((dateTo.Year - dateFrom.Year - 1) * 12) + (13 - dateFrom.Month + dateTo.Month) : dateTo.Month - dateFrom.Month + 1;
结果= 28
没有第一个月
monthCount = dateFrom.Year != dateTo.Year ? ((dateTo.Year - dateFrom.Year - 1) * 12) + (12 - dateFrom.Month + dateTo.Month) : dateTo.Month - dateFrom.Month;
结果= 27
假设这个月的日期不相关(即2011.1.1和2010.12.31之间的差为1),date1 > date2为正值,date2 > date1为负值
((date1.Year - date2.Year) * 12) + date1.Month - date2.Month
或者,假设你想要两个日期之间的“平均月”的大致数字,下面的方法应该适用于所有日期,但日期差异非常大。
date1.Subtract(date2).Days / (365.25 / 12)
注意,如果您要使用后一种解决方案,那么您的单元测试应该声明应用程序设计使用的最宽日期范围,并相应地验证计算结果。
更新(感谢Gary)
如果使用“平均月份”方法,“每年平均天数”的更准确数字是365.2425。
如果你只关心月份和年份,想要触及两个日期(例如你想要从JAN/2021到AGO/2022),你可以使用这个:
int numberOfMonths= (Year2 > Year1 ? ( Year2 - Year1 - 1) * 12 + (12 - Month1) + Month2 + 1 : Month2 - Month1 + 1);
例子:
Year1/Month1: 2021/10
Year2/Month2: 2022/08
numberOfMonths = 11;
或者同年:
Year1/Month1: 2021/10
Year2/Month2: 2021/12
numberOfMonths = 3;
如果你只想触碰其中一个,就去掉两个+ 1。
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