如何在c#中计算两个日期之间的月差?
c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:
TimeSpan ts = date1 - date2;
但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。
有什么建议吗?
如何在c#中计算两个日期之间的月差?
c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:
TimeSpan ts = date1 - date2;
但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。
有什么建议吗?
当前回答
扩展的Kirks结构与ToString(格式)和持续时间(长ms)
public struct DateTimeSpan
{
private readonly int years;
private readonly int months;
private readonly int days;
private readonly int hours;
private readonly int minutes;
private readonly int seconds;
private readonly int milliseconds;
public DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
{
this.years = years;
this.months = months;
this.days = days;
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
this.milliseconds = milliseconds;
}
public int Years { get { return years; } }
public int Months { get { return months; } }
public int Days { get { return days; } }
public int Hours { get { return hours; } }
public int Minutes { get { return minutes; } }
public int Seconds { get { return seconds; } }
public int Milliseconds { get { return milliseconds; } }
enum Phase { Years, Months, Days, Done }
public string ToString(string format)
{
format = format.Replace("YYYY", Years.ToString());
format = format.Replace("MM", Months.ToString());
format = format.Replace("DD", Days.ToString());
format = format.Replace("hh", Hours.ToString());
format = format.Replace("mm", Minutes.ToString());
format = format.Replace("ss", Seconds.ToString());
format = format.Replace("ms", Milliseconds.ToString());
return format;
}
public static DateTimeSpan Duration(long ms)
{
DateTime dt = new DateTime();
return CompareDates(dt, dt.AddMilliseconds(ms));
}
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();
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);
}
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;
}
}
其他回答
一定是有人干的))
扩展方法返回给定日期之间的完整月数。无论以什么顺序接收日期,都会返回一个自然数。在“正确”答案中没有近似的计算。
/// <summary>
/// Returns the difference between dates in months.
/// </summary>
/// <param name="current">First considered date.</param>
/// <param name="another">Second considered date.</param>
/// <returns>The number of full months between the given dates.</returns>
public static int DifferenceInMonths(this DateTime current, DateTime another)
{
DateTime previous, next;
if (current > another)
{
previous = another;
next = current;
}
else
{
previous = current;
next = another;
}
return
(next.Year - previous.Year) * 12 // multiply the difference in years by 12 months
+ next.Month - previous.Month // add difference in months
+ (previous.Day <= next.Day ? 0 : -1); // if the day of the next date has not reached the day of the previous one, then the last month has not yet ended
}
但如果你仍然想要得到月份的小数部分,你只需要在回报中再加一项:
+(下一个。Day - previous.Day) / DateTime.DaysInMonth(previous. Day)年,previous.Month)
这是我所需要的。对我来说,一个月的哪一天并不重要,因为它总是碰巧是一个月的最后一天。
public static int MonthDiff(DateTime d1, DateTime d2){
int retVal = 0;
if (d1.Month<d2.Month)
{
retVal = (d1.Month + 12) - d2.Month;
retVal += ((d1.Year - 1) - d2.Year)*12;
}
else
{
retVal = d1.Month - d2.Month;
retVal += (d1.Year - d2.Year)*12;
}
//// Calculate the number of years represented and multiply by 12
//// Substract the month number from the total
//// Substract the difference of the second month and 12 from the total
//retVal = (d1.Year - d2.Year) * 12;
//retVal = retVal - d1.Month;
//retVal = retVal - (12 - d2.Month);
return retVal;
}
你可以这样做
if ( date1.AddMonths(x) > date2 )
扩展的Kirks结构与ToString(格式)和持续时间(长ms)
public struct DateTimeSpan
{
private readonly int years;
private readonly int months;
private readonly int days;
private readonly int hours;
private readonly int minutes;
private readonly int seconds;
private readonly int milliseconds;
public DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
{
this.years = years;
this.months = months;
this.days = days;
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
this.milliseconds = milliseconds;
}
public int Years { get { return years; } }
public int Months { get { return months; } }
public int Days { get { return days; } }
public int Hours { get { return hours; } }
public int Minutes { get { return minutes; } }
public int Seconds { get { return seconds; } }
public int Milliseconds { get { return milliseconds; } }
enum Phase { Years, Months, Days, Done }
public string ToString(string format)
{
format = format.Replace("YYYY", Years.ToString());
format = format.Replace("MM", Months.ToString());
format = format.Replace("DD", Days.ToString());
format = format.Replace("hh", Hours.ToString());
format = format.Replace("mm", Minutes.ToString());
format = format.Replace("ss", Seconds.ToString());
format = format.Replace("ms", Milliseconds.ToString());
return format;
}
public static DateTimeSpan Duration(long ms)
{
DateTime dt = new DateTime();
return CompareDates(dt, dt.AddMilliseconds(ms));
}
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();
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);
}
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;
}
}
下面是一个使用VB的更简洁的解决方案。只适用于年、月、日的净日期。你也可以在c#中加载DateDiff库。
Date1必须<= date2
VB。网
Dim date1 = Now.AddDays(-2000)
Dim date2 = Now
Dim diffYears = DateDiff(DateInterval.Year, date1, date2) - If(date1.DayOfYear > date2.DayOfYear, 1, 0)
Dim diffMonths = DateDiff(DateInterval.Month, date1, date2) - diffYears * 12 - If(date1.Day > date2.Day, 1, 0)
Dim diffDays = If(date2.Day >= date1.Day, date2.Day - date1.Day, date2.Day + (Date.DaysInMonth(date1.Year, date1.Month) - date1.Day))
C#
DateTime date1 = Now.AddDays(-2000);
DateTime date2 = Now;
int diffYears = DateDiff(DateInterval.Year, date1, date2) - date1.DayOfYear > date2.DayOfYear ? 1 : 0;
int diffMonths = DateDiff(DateInterval.Month, date1, date2) - diffYears * 12 - date1.Day > date2.Day ? 1 : 0;
int diffDays = date2.Day >= date1.Day ? date2.Day - date1.Day : date2.Day + (System.DateTime.DaysInMonth(date1.Year, date1.Month) - date1.Day);