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

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

TimeSpan ts = date1 - date2;

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

有什么建议吗?


当前回答

你可以在。net中使用Time Period Library的DateDiff类:

// ----------------------------------------------------------------------
public void DateDiffSample()
{
  DateTime date1 = new DateTime( 2009, 11, 8, 7, 13, 59 );
  DateTime date2 = new DateTime( 2011, 3, 20, 19, 55, 28 );
  DateDiff dateDiff = new DateDiff( date1, date2 );

  // differences
  Console.WriteLine( "DateDiff.Months: {0}", dateDiff.Months );
  // > DateDiff.Months: 16

  // elapsed
  Console.WriteLine( "DateDiff.ElapsedMonths: {0}", dateDiff.ElapsedMonths );
  // > DateDiff.ElapsedMonths: 4

  // description
  Console.WriteLine( "DateDiff.GetDescription(6): {0}", dateDiff.GetDescription( 6 ) );
  // > DateDiff.GetDescription(6): 1 Year 4 Months 12 Days 12 Hours 41 Mins 29 Secs
} // DateDiffSample

其他回答

public static int PayableMonthsInDuration(DateTime StartDate, DateTime EndDate)
{
    int sy = StartDate.Year; int sm = StartDate.Month; int count = 0;
    do
    {
        count++;if ((sy == EndDate.Year) && (sm >= EndDate.Month)) { break; }
        sm++;if (sm == 13) { sm = 1; sy++; }
    } while ((EndDate.Year >= sy) || (EndDate.Month >= sm));
    return (count);
}

这个解决方案是用于租金/订阅计算的,其中的差异并不意味着减法,它意味着这两个日期之间的跨度。

这个简单的静态函数计算两个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);
 }

疯狂的方法,计算所有的日子,超级精确

Helper类:

public class DaysInMonth
{
    public int Days { get; set; }
    public int Month { get; set; }
    public int Year { get; set; }
    public bool Full { get; set; }
}

功能:

    public static List<DaysInMonth> MonthsDelta(DateTime start, DateTime end)
    {
        
        var dates = Enumerable.Range(0, 1 + end.Subtract(start).Days)
          .Select(offset => start.AddDays(offset))
          .ToArray();

        DateTime? prev = null;
        int days = 0;

        List < DaysInMonth > list = new List<DaysInMonth>();

        foreach (DateTime date in dates)
        {
            if (prev != null)
            {
                if(date.Month!=prev.GetValueOrDefault().Month)
                {
                    DaysInMonth daysInMonth = new DaysInMonth();
                    daysInMonth.Days = days;
                    daysInMonth.Month = prev.GetValueOrDefault().Month;
                    daysInMonth.Year = prev.GetValueOrDefault().Year;
                    daysInMonth.Full = DateTime.DaysInMonth(daysInMonth.Year, daysInMonth.Month) == daysInMonth.Days;
                    list.Add(daysInMonth);
                    days = 0;
                }
            }
            days++;
            prev = date;
        }

        //------------------ add last
        if (days > 0)
        {
            DaysInMonth daysInMonth = new DaysInMonth();
            daysInMonth.Days = days;
            daysInMonth.Month = prev.GetValueOrDefault().Month;
            daysInMonth.Year = prev.GetValueOrDefault().Year;
            daysInMonth.Full = DateTime.DaysInMonth(daysInMonth.Year, daysInMonth.Month) == daysInMonth.Days;
            list.Add(daysInMonth);
        }

        return list;
    }

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