如何在c#中计算两个日期之间的月差?
c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:
TimeSpan ts = date1 - date2;
但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。
有什么建议吗?
如何在c#中计算两个日期之间的月差?
c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:
TimeSpan ts = date1 - date2;
但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。
有什么建议吗?
当前回答
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
其他回答
简单快速的解决方案,计算2个日期之间的总月份。 如果你只想得到不同的月份,而不计算From date中的月份-只需从代码中删除+1。
public static int GetTotalMonths(DateTime From, DateTime Till)
{
int MonthDiff = 0;
for (int i = 0; i < 12; i++)
{
if (From.AddMonths(i).Month == Till.Month)
{
MonthDiff = i + 1;
break;
}
}
return MonthDiff;
}
我写了一个函数来完成这个,因为其他的方法都不适合我。
public string getEndDate (DateTime startDate,decimal monthCount)
{
int y = startDate.Year;
int m = startDate.Month;
for (decimal i = monthCount; i > 1; i--)
{
m++;
if (m == 12)
{ y++;
m = 1;
}
}
return string.Format("{0}-{1}-{2}", y.ToString(), m.ToString(), startDate.Day.ToString());
}
下面是一个返回DateTimeSpan的综合解决方案,它与TimeSpan类似,不同之处是它除了时间组件之外还包括所有的日期组件。
用法:
void Main()
{
DateTime compareTo = DateTime.Parse("8/13/2010 8:33:21 AM");
DateTime now = DateTime.Parse("2/9/2012 10:10:11 AM");
var dateSpan = DateTimeSpan.CompareDates(compareTo, now);
Console.WriteLine("Years: " + dateSpan.Years);
Console.WriteLine("Months: " + dateSpan.Months);
Console.WriteLine("Days: " + dateSpan.Days);
Console.WriteLine("Hours: " + dateSpan.Hours);
Console.WriteLine("Minutes: " + dateSpan.Minutes);
Console.WriteLine("Seconds: " + dateSpan.Seconds);
Console.WriteLine("Milliseconds: " + dateSpan.Milliseconds);
}
输出:
年:1 第五个月: 天:27 时间:1 分钟:36 50秒: 毫秒:0
为了方便起见,我将逻辑集中到DateTimeSpan结构体中,但是您可以将方法CompareDates移动到任何您认为合适的地方。还要注意,哪个日期在另一个日期之前并不重要。
public struct DateTimeSpan
{
public int Years { get; }
public int Months { get; }
public int Days { get; }
public int Hours { get; }
public int Minutes { get; }
public int Seconds { get; }
public int Milliseconds { get; }
public DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
{
Years = years;
Months = months;
Days = days;
Hours = hours;
Minutes = minutes;
Seconds = seconds;
Milliseconds = milliseconds;
}
enum Phase { Years, Months, Days, Done }
public static DateTimeSpan CompareDates(DateTime date1, DateTime date2)
{
if (date2 < date1)
{
var sub = date1;
date1 = date2;
date2 = sub;
}
DateTime current = date1;
int years = 0;
int months = 0;
int days = 0;
Phase phase = Phase.Years;
DateTimeSpan span = new DateTimeSpan();
int officialDay = current.Day;
while (phase != Phase.Done)
{
switch (phase)
{
case Phase.Years:
if (current.AddYears(years + 1) > date2)
{
phase = Phase.Months;
current = current.AddYears(years);
}
else
{
years++;
}
break;
case Phase.Months:
if (current.AddMonths(months + 1) > date2)
{
phase = Phase.Days;
current = current.AddMonths(months);
if (current.Day < officialDay && officialDay <= DateTime.DaysInMonth(current.Year, current.Month))
current = current.AddDays(officialDay - current.Day);
}
else
{
months++;
}
break;
case Phase.Days:
if (current.AddDays(days + 1) > date2)
{
current = current.AddDays(days);
var timespan = date2 - current;
span = new DateTimeSpan(years, months, days, timespan.Hours, timespan.Minutes, timespan.Seconds, timespan.Milliseconds);
phase = Phase.Done;
}
else
{
days++;
}
break;
}
}
return span;
}
}
你可以这样做
if ( date1.AddMonths(x) > date2 )
除了所有给出的答案,我发现这段代码非常简单。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;
}