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. UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning

    #import "ModelAnimationDelegate.h" #import <UIKit/UIKit.h> #import "MapVC.h&quo ...

  2. 非RootLayer的隐式动画

    非RootLayer都有隐式动画,默认0.25秒. // 1.开启 [CATransaction begin]; // 2.设置关闭 YES-关闭:NO-开启 [CATransaction setDi ...

  3. Android中隐藏顶部状态栏的那些坑——Android开发之路3

    Android中隐藏顶部状态栏的那些坑 先看看常规的隐藏状态栏的方法: 方法一: @Override protected void onCreate(Bundle savedInstanceState ...

  4. UDAD 用户故事驱动的敏捷开发 – 演讲实录

    敏捷发展到今天已经在软件行业得到了广泛认可,但大多数敏捷方法都是为了解决某一特定问题而总结出来的特定方法或实践,一直缺乏一个可以将整个开发过程串接起来的成体系的方法.用户故事驱动的敏捷开发(User ...

  5. 自动将指定目录下面的文件转换为UTF-8

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...

  6. Linux Shell脚本逻辑操作符简介

    在写程序时,会用到条件判断,测试条件是否成立.很多时候,判断条件是多个的,这个时候需要用到逻辑操作符.shell脚本中常用的有哪些逻辑操作符呢? 1.逻辑与: -a 格式: conditon1 -a ...

  7. Linux shell脚本编程(一)

    Linux shell脚本编程: 守护进程,服务进程:启动?开机时自动启动: 交互式进程:shell应用程序 广义:GUI,CLI GUI: CLI: 词法分析:命令,选项,参数 内建命令: 外部命令 ...

  8. android OnTouchListener 按下与抬起

    写法一: private OnTouchListener pressOnTouchListener = new OnTouchListener(){ @Override public boolean ...

  9. UNITY 移动到指定位置的写法

    //move towards a target at a set speed. private void MoveTowardsTarget() { //the speed, in units per ...

  10. [poj1741][tree] (树/点分治)

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...