如何在c#中计算两个日期之间的月差?

c#中是否有相当于VB的DateDiff()方法。我需要找出相隔数年的两个日期之间的月差。文档说我可以像这样使用TimeSpan:

TimeSpan ts = date1 - date2;

但这里的数据是以天为单位的。我不想把这个数字除以30,因为不是每个月都是30天,而且两个操作数的值相差很大,所以我担心除以30可能会得到错误的值。

有什么建议吗?


当前回答

假设这个月的日期不相关(即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。

其他回答

您可以使用以下扩展: 代码

public static class Ext
{
    #region Public Methods

    public static int GetAge(this DateTime @this)
    {
        var today = DateTime.Today;
        return ((((today.Year - @this.Year) * 100) + (today.Month - @this.Month)) * 100 + today.Day - @this.Day) / 10000;
    }

    public static int DiffMonths(this DateTime @from, DateTime @to)
    {
        return (((((@to.Year - @from.Year) * 12) + (@to.Month - @from.Month)) * 100 + @to.Day - @from.Day) / 100);
    }

    public static int DiffYears(this DateTime @from, DateTime @to)
    {
        return ((((@to.Year - @from.Year) * 100) + (@to.Month - @from.Month)) * 100 + @to.Day - @from.Day) / 10000;
    }

    #endregion Public Methods
}

实现!

int Age;
int years;
int Months;
//Replace your own date
var d1 = new DateTime(2000, 10, 22);
var d2 = new DateTime(2003, 10, 20);
//Age
Age = d1.GetAge();
Age = d2.GetAge();
//positive
years = d1.DiffYears(d2);
Months = d1.DiffMonths(d2);
//negative
years = d2.DiffYears(d1);
Months = d2.DiffMonths(d1);
//Or
Months = Ext.DiffMonths(d1, d2);
years = Ext.DiffYears(d1, d2); 

这个简单的静态函数计算两个Datetimes之间的月份分数。

1.1. 到31.1。= 1.0 1.4. 到15.4。= 0.5 16.4. 到30.4。= 0.5 1.3. 到1.4。= 1 + 1/30

该函数假设第一个日期比第二个日期小。要处理负时间间隔,可以通过在开始时引入符号和变量交换来轻松地修改函数。

public static double GetDeltaMonths(DateTime t0, DateTime t1)
{
     DateTime t = t0;
     double months = 0;
     while(t<=t1)
     {
         int daysInMonth = DateTime.DaysInMonth(t.Year, t.Month);
         DateTime endOfMonth = new DateTime(t.Year, t.Month, daysInMonth);
         int cutDay = endOfMonth <= t1 ? daysInMonth : t1.Day;
         months += (cutDay - t.Day + 1) / (double) daysInMonth;
         t = new DateTime(t.Year, t.Month, 1).AddMonths(1);
     }
     return Math.Round(months,2);
 }

一定是有人干的))

扩展方法返回给定日期之间的完整月数。无论以什么顺序接收日期,都会返回一个自然数。在“正确”答案中没有近似的计算。

    /// <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)

能够计算以月为单位的两个日期之间的差异是一件非常符合逻辑的事情,并且在许多业务应用程序中都需要它。这里的几个程序员提供了一些评论,比如“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个月(额外的日子也没关系)

在业务应用中,大多数情况下,当您需要计算月份时,是因为您需要根据人类计算时间的方式了解“完整的”月份;而不是基于一些抽象/无关的想法。

这是我自己的库,将返回两个日期之间的月差。

public static int MonthDiff(DateTime d1, DateTime d2)
{
    int retVal = 0;

    // 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;
}