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 > && Weeks > && Days > )
{
return string.Format("{0}月,{1}周,{2}天", Months,Weeks, Days);
} if (Months == && Weeks == && Days == )
{
return "相同日期";
} if (Months == && Weeks == && Days > )
{
return string.Format("{0}天", Days);
} if (Months == && Weeks > && Days == )
{
return string.Format("{0}周", Weeks);
} if (Months > && Weeks == && Days == )
{
return string.Format("{0}月", Months);
} if (Months > && Weeks > && Days == )
{
return string.Format("{0}月,{1}周", Months, Weeks);
} if (Months > && Weeks == && Days > )
{
return string.Format("{0}月,{1}天", Months, Days);
} if (Months == && Weeks > && Days > )
{
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 = , dayCount = ;
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();
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 / ;
result.Days = dayCount % ; return result;
} /// <summary>
/// 获取指定时间所在月份的最后一天的日期
/// </summary>
/// <param name="date">指定时间</param>
/// <returns>最后一天的日期</returns>
private static DateTime GetLastDateInMonth(DateTime date)
{
DateTime tmp = new DateTime(date.Year, date.Month, ).AddMonths();
DateTime tmp2 = new DateTime(tmp.Year, tmp.Month, ); return tmp2.AddDays(-);
} /// <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, );
}
}

调用如下

            var toTime = DateTime.Now;
var beginTime = new DateTime(, , , , , );
for (int i = ; i < ; 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();
}

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

这是因为11月没有31号

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

仿window系统自带的日期差计算器类的更多相关文章

  1. “canvas画布仿window系统自带画图软件"项目的思考

    "canvas画布仿window系统自带画图软件"项目的思考 首先贴上DEMO图,并没有美化效果.对UI有要求的,请自带补脑技术. 思考一 在做项目的过程中,我发现"工具 ...

  2. ShareIntentUtil【调用系统自带的分享的工具类】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 根据参考资料的文章,整理了调用系统自带分享的工具类(实现了适配7.0FileProvider的功能),需要搭配<Android ...

  3. android系统自带的日期、时间对话框的用法

    代码: package com.test; import java.util.Calendar; import android.app.Activity; import android.app.Dat ...

  4. php调用window系统自带的命令,比如计算器

    1.在cmd命令行输入calc.exe 2.

  5. 完全参照系统自带的DatePickerDialog、TimePickerDialog的源代码仿写的DateTimePickerDialog

    完全参照系统自带的DatePickerDialog.TimePickerDialog的源代码仿写的DateTimePickerDialog.具有同时选择日期.时间的功能.在2.2.2.3平台,显示的效 ...

  6. 应用程序间跳转 (友盟SSO 授权 与系统自带的分享)

    应用程序间跳转的应用场景 使用第三方用户登录,如微信登录,返回用户名和密码 需要用户授权,返回到调用程序,同时返回授权的用户名 应用程序推广,跳转到itunes并显示指定app下载页 第三方支付,跳转 ...

  7. Android manifest之系统自带的permission

    Android manifest之系统自带的permission 本文描述Android系统自带的permission.点击查看:“关于permission的原始定义和说明”.点击查看:“Androi ...

  8. PresentViewController切换界面(一些系统自带的页面切换动画)

    视图切换,没有NavigationController的情况下,一般会使用presentViewController来切换视图并携带切换时的动画, 其中切换方法如下: – presentViewCon ...

  9. 关于自定义tabBar时修改系统自带tabBarItem属性造成的按钮顺序错乱的问题相关探究

      关于自定义tabBar时修改系统自带tabBarItem属性造成的按钮顺序错乱的问题相关探究 测试代码:http://git.oschina.net/Xiyue/TabBarItem_TEST 简 ...

随机推荐

  1. Android中webView和网页的交互

     Android中webView和网页的交互 Android中webView跟网页的交互式通过JavaScript进行的.具体步骤: 1.创建JavaScript,在点击的时候调用JavaScript ...

  2. Allocators与Criterion的相同点及区别

    C++98: 1.相同点: Allocators having the same type were assumed to be equal so that memory allocated by o ...

  3. 如何升级PowerShell

    背景: 开发的PowerShell 脚本需要使用Invoke-RestMethod命令,发现在老的服务器上不支持这一命令,经过查询得知由于PS版本的问题.涉及到了PS的升级,需要介绍下PowerShe ...

  4. 1-安装kvm及虚拟机

    安装KVM及虚拟机 1.       创建lvm 2.       安装kvm相关的包 需要安装的包 安装好后,进入系统,发现没有eth0 然后重启网络 然后就看到了eth0,以及ip 挂载光盘 ' ...

  5. linux hosts文件详+mac主机名被莫名其妙修改

    1.名词解析 主机名: 无论是在局域网还是在INTERNET上,每台主机都有一个IP地址,用来区分当前是那一台机器(其实底层是使用机器的物理地址),也就是说IP地址就是一个主机的门牌号,唯一的标示这一 ...

  6. 关于java的递归写法,经典的Fibonacci数的问题

    经典的Fibonacci数的问题 主要想展示一下迭代与递归,以及尾递归的三种写法,以及他们各自的时间性能. public class Fibonacci { /*迭代*/ public static ...

  7. sql

    http://www.cnblogs.com/ASPNET2008/archive/2012/06/30/2570737.html

  8. orcle函数

    一.字符函数1.chr给出整数,返回对应的字符:SQL>select chr(54740) zhao,chr(65) chr65 from dual;ZHAO CHR65---- -----赵 ...

  9. [LeetCode] Pascal's Triangle II 杨辉三角之二

    Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3,Return [1,3, ...

  10. 【6年开源路】FineUI家族今日全部更新(FineUI + FineUI3to4 + FineUI.Design + AppBox)!

    刚才询问博客园团队: [6年开源路]三石今日送福利,AppBox4.0源码免费拿!FineUI家族今日全部更新(FineUI + FineUI3to4 + FineUI.Design + AppBox ...