仿window系统自带的日期差计算器类

public class MonthSubstract
    {
        /// <summary>
        /// 日期差之月份
        /// </summary>
        public int Months { get; set; }

        /// <summary>
        /// 日期差之总天数
        /// </summary>
        public int TotalDays { get; set; }

        /// <summary>
        /// 日期差之除去月份剩余天数
        /// </summary>
        public int Days { get; set; }

        /// <summary>
        /// 日期差之除去月份剩余周数
        /// </summary>
        public int Weeks { get; set; }

        /// <summary>
        /// ToString
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            if (Months > 0 && Weeks > 0 && Days > 0)
            {
                return string.Format("{0}月,{1}周,{2}天", Months,Weeks, Days);
            }

            if (Months == 0 && Weeks == 0 && Days == 0)
            {
                return "相同日期";
            }

            if (Months == 0 && Weeks == 0 && Days > 0)
            {
                return string.Format("{0}天",  Days);
            }

            if (Months == 0 && Weeks > 0 && Days == 0)
            {
                return string.Format("{0}周", Weeks);
            }

            if (Months > 0 && Weeks == 0 && Days == 0)
            {
                return string.Format("{0}月", Months);
            }

            if (Months > 0 && Weeks > 0 && Days == 0)
            {
                return string.Format("{0}月,{1}周", Months, Weeks);
            }

            if (Months > 0 && Weeks == 0 && Days > 0)
            {
                return string.Format("{0}月,{1}天", Months, Days);
            }

            if (Months == 0 && Weeks > 0 && Days > 0)
            {
                return string.Format("{0}周,{1}天", Weeks, Days);
            }

            return string.Format("{0}月,{1}周,{2}天", Months, Weeks, Days);
        }

        /// <summary>
        /// 计算月份差
        /// </summary>
        /// <param name="from">开始时间</param>
        /// <param name="to">结束时间</param>
        /// <returns>MonthSubstract实例</returns>
        public static MonthSubstract Substract(DateTime from, DateTime to)
        {
            var result = new MonthSubstract();
            int monthCount = 0, dayCount = 0;
            var beginTime = from.Date;
            var lastTime = beginTime;
            var endTime = to.Date;
            if (beginTime > endTime)
            {
                //交换时间
                var tmp = beginTime;
                beginTime = endTime;
                endTime = tmp;
            }

            result.TotalDays = (int)((endTime - beginTime).TotalDays);
            while (beginTime < endTime)
            {
                lastTime = beginTime;

                beginTime = beginTime.AddMonths(1);
                if (GetLastDayInMonth(lastTime) == lastTime.Day)
                {
                    beginTime = GetLastDateInMonth(beginTime);
                }

                if (endTime > beginTime)
                    monthCount++;
            }

            dayCount = (endTime - lastTime).Days;
            result.Months = monthCount;
            ////result.Days = dayCount;
            result.Weeks = dayCount / 7;
            result.Days = dayCount % 7;

            return result;
        }

        /// <summary>
        /// 获取指定时间所在月份的最后一天的日期
        /// </summary>
        /// <param name="date">指定时间</param>
        /// <returns>最后一天的日期</returns>
        private static DateTime GetLastDateInMonth(DateTime date)
        {
            DateTime tmp = new DateTime(date.Year, date.Month, 1).AddMonths(1);
            DateTime tmp2 = new DateTime(tmp.Year, tmp.Month, 1);

            return tmp2.AddDays(-1);
        }

        /// <summary>
        /// 获取指定时间所在月份的最后一天的日期数值
        /// </summary>
        /// <param name="date">指定时间</param>
        /// <returns>最后一天的日期数值</returns>
        private static int GetLastDayInMonth(DateTime date)
        {
            return GetLastDateInMonth(date).Day;
        }

        /// <summary>
        /// 获取指定时间所在月份的第1天
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private static DateTime GetFirstDayInMonth(DateTime date)
        {
            return new DateTime(date.Year, date.Month, 1);
        }
    }

调用如下

            var toTime = DateTime.Now;
            var beginTime = new DateTime(2016, 1, 28, 19, 05, 0);
            for (int i = 0; i < 400; i++)
            {
                var rsult = MonthSubstract.Substract(beginTime, toTime);
                Console.WriteLine(string.Format("日期{0}与日期{1}的差值为{2}", beginTime.ToString("yyyy-MM-dd"), toTime.ToString("yyyy-MM-dd"), rsult.ToString()));
                beginTime = beginTime.AddDays(1);
            }

有意思的是假如:当前日期是 2016.12.29日,起始日期是2016.7.30 得到的结果与 起始日期是 2016.7.31号一样,都是 "4 月, 4 周, 1 天"

这是因为11月没有31号

为了避免出现 1.31号加1个月变成2.28,而2.28加1个月变成 3.28这种狗血事情,只能用 特殊的方式来相加,最后一天加一个月,永远是下个月最后一天

原文地址:https://www.cnblogs.com/zhshlimi/p/6232815.html