`
pure1202
  • 浏览: 60038 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

怎样求2个日期间隔的工作日数?解决

阅读更多
还有很多要完善的地方,还有简单的实现没?希望各位帮我提提意见。。。。。
/*步骤: 类CountDaysByDate
 * 1、中间天数处理
 * 2、开始时间处理
 * 3、结束时间处理
*/
    private static int[] val = new int[] { 1, 7 };// 默认休息日为 六,日
	
	private static double WORK_DAY_COUNT = 7.5;	//定义一天的有几个小时
	
	//设置上下班时间、中午休息时间
	private static int AM_START_HOUR = 9; 
	private static int AM_START_MINUTE = 0;
	private static int AM_END_HOUR = 12; 
	private static int AM_END_MINUTE = 0; 
	private static int PM_START_HOUR = 13; 
	private static int PM_START_MINUTE = 0; 
	private static int PM_END_HOUR = 17; 
	private static int PM_END_MINUTE = 30; 
	private static double NOON_REST = 1; 
	
	/**
	 * 计算2个日期相差天数(排除休息日)
	 * @param beginDateStr
	 * @param endDateStr
	 * @return
	 * 步骤:
	 * 1、中间天数处理
	 * 2、开始时间处理
	 * 3、结束时间处理
	 */
	@SuppressWarnings("deprecation")
	public static double getDaysByDate(String beginDateStr,String endDateStr){
		double result = 0;
		double restTime = NOON_REST;//中午休息时间
		Calendar beginCalendar = getCalendar(beginDateStr);
		Calendar endCalendar = getCalendar(endDateStr);
		/**1、中间天数处理**/
		int days = getMargin(beginDateStr, endDateStr);
		/**2、开始时间处理**/
		if(days>0){//不是同一天
			//开始天上午工作开始-结束时间
			Calendar amStartWork1 = setHourAndMinute(getCalendar(beginDateStr),AM_START_HOUR,AM_START_MINUTE);
			Calendar amEndWork1 = setHourAndMinute(getCalendar(beginDateStr),AM_END_HOUR,AM_END_MINUTE);
			//开始天下午工作开始-结束时间
			//Calendar pmStartWork1 = setHourAndMinute(getCalendar(beginDateStr),PM_START_HOUR,PM_START_MINUTE);
			Calendar pmEndWork1 = setHourAndMinute(getCalendar(beginDateStr),PM_END_HOUR,PM_END_MINUTE);
			beginCalendar = setOverTime(beginDateStr);
			//计算开始天还有多少分钟
			int bvalue = 0;
			if(beginCalendar.compareTo(amStartWork1)>=0 && beginCalendar.compareTo(pmEndWork1)<=0){//beginCalendar<=pmEndWork1
				bvalue = ((int)(pmEndWork1.getTimeInMillis() - beginCalendar.getTimeInMillis()))/(60*1000) ;
				if(beginCalendar.compareTo(amEndWork1)<0){//beginCalendar<amEndWork1
					bvalue -= (int)(restTime*60);
				}
			}
			/**3、结束时间处理**/
			//末尾天上午工作开始-结束时间
			Calendar amStartWork2 = setHourAndMinute(getCalendar(endDateStr),AM_START_HOUR,AM_START_MINUTE);
			Calendar amEndWork2 = setHourAndMinute(getCalendar(endDateStr),AM_END_HOUR,AM_END_MINUTE);
			//末尾天下午工作开始-结束时间
			//Calendar pmStartWork2 = setHourAndMinute(getCalendar(endDateStr),PM_START_HOUR,PM_START_MINUTE);
			Calendar pmEndWork2 = setHourAndMinute(getCalendar(endDateStr),PM_END_HOUR,PM_END_MINUTE);
			endCalendar = setOverTime(endDateStr);
			//计算末尾天还有多少分钟
			int evalue = 0;
			if(endCalendar.compareTo(amStartWork2)>=0 && endCalendar.compareTo(pmEndWork2)<=0){//endCalendar<=pmEndWork2
				evalue = ((int)(pmEndWork2.getTimeInMillis() - endCalendar.getTimeInMillis()))/(60*1000) ;
				if(endCalendar.compareTo(amEndWork2)<0){//endCalendar<amEndWork2
					evalue -= (int)(restTime*60);
				}
			}
			double total = (bvalue - evalue)/((double)WORK_DAY_COUNT*60);
			result = days + total;
			result = ((int)(result*100))/(double)100;
		}else{//同一天
			int bvalue = 0;
			if(endCalendar.compareTo(beginCalendar)>0 ){//endCalendar>beginCalendar
				//上午工作开始-结束时间
				//Calendar amStartWork1 = setHourAndMinute(getCalendar(beginDateStr),AM_START_HOUR,AM_START_MINUTE);
				Calendar amEndWork1 = setHourAndMinute(getCalendar(beginDateStr),AM_END_HOUR,AM_END_MINUTE);
				//下午工作开始-结束时间
				Calendar pmStartWork1 = setHourAndMinute(getCalendar(beginDateStr),PM_START_HOUR,PM_START_MINUTE);
				//Calendar pmEndWork1 = setHourAndMinute(getCalendar(beginDateStr),PM_END_HOUR,PM_END_MINUTE);
				beginCalendar = setOverTime(beginDateStr);
				endCalendar = setOverTime(endDateStr);
				/**2中情况:特殊的->《9:00~17:00》; 普通的->《9:00~12:00》《13:00~17:00》;**/
				bvalue = ((int)(endCalendar.getTimeInMillis() - beginCalendar.getTimeInMillis()))/(60*1000) ;
				if(beginCalendar.compareTo(amEndWork1)<0 && endCalendar.compareTo(pmStartWork1)>0){//beginCalendar<amEndWork1
					bvalue -= (int)(restTime*60);
				}
				double total = (bvalue)/((double)WORK_DAY_COUNT*60);
				result = ((int)(total*100))/(double)100;
			}else{
				result = 0;
			}
		}
		return result;
	}
	
	/**
	 * 设置时间在工作时间范围内
	 * @param base
	 * @param amSw
	 * @param amEw
	 * @param pmSw
	 * @param pmEw
	 * @return
	 */
	public static Calendar setOverTime(String base){
		Calendar cal = getCalendar(base);
		//上午工作开始-结束时间
		Calendar amSw = setHourAndMinute(getCalendar(base),AM_START_HOUR,AM_START_MINUTE);
		Calendar amEw = setHourAndMinute(getCalendar(base),AM_END_HOUR,AM_END_MINUTE);
		//下午工作开始-结束时间
		Calendar pmSw = setHourAndMinute(getCalendar(base),PM_START_HOUR,PM_START_MINUTE);
		Calendar pmEw = setHourAndMinute(getCalendar(base),PM_END_HOUR,PM_END_MINUTE);
		if(cal.before(amSw)){//如果操作日期为上午工作开始时间之前,指定一个默认值
			cal = setHourAndMinute(cal,AM_START_HOUR,AM_START_MINUTE);
		}else if(cal.after(amEw) && cal.before(pmSw)){//如果操作日期为12:00~13:00,指定一个默认值
			cal = setHourAndMinute(cal,PM_START_HOUR,PM_START_MINUTE);
		}else if(cal.after(pmEw) ){//如果操作日期为17:30后			cal = setHourAndMinute(cal,PM_END_HOUR,PM_END_MINUTE);
		}else if(cal.compareTo(amEw)==0 || cal.compareTo(pmSw)==0){
			cal = setHourAndMinute(cal,PM_START_HOUR,PM_START_MINUTE);//如果操作日期为12:00/13:00
		}
		return cal;
	}
	
	/**
	 * 取得2个日期之间的休息日数目
	 * @param sDate
	 * @param eDate
	 * @return
	 */
	@SuppressWarnings("static-access")
	public static int getRestDays(String bDateStr,String eDateStr){
		int days = 0;
		Calendar bDate = getCalendar(bDateStr);
		Calendar eDate = getCalendar(eDateStr);
		while(eDate.after(bDate)){
			//判断是否有休息日
			for (int i = 0; i < val.length; i++) {
				if (bDate.get(bDate.DAY_OF_WEEK) == val[i]) {
					days ++;
				}
			}
			bDate.add(bDate.DATE,1);
		}
		return days;
	}
	
	/**
	 * 计算2个日期之间的天数(排除休息日),例如:2009-04-07 15:00:00 ~ 2009-04-09 15:00:00之间只有2009-04-08一天,则返回1,此处可加入排除节假日的方法。。。。。。
	 * @param bDateStr
	 * @param eDateStr
	 * @return
	 */
	@SuppressWarnings("static-access")
	public static int getMargin(String bDateStr, String eDateStr) {
		int margin;
		int resDays = 0;
		try {
			Calendar bDate = getCalendar(bDateStr);
			Calendar eDate = getCalendar(eDateStr);
			long l = eDate.getTimeInMillis() - bDate.getTimeInMillis();
			margin = (int) (l /(24 * 60 * 60 * 1000));
			while(eDate.after(bDate)){//判断是否有休息日
				for (int i = 0; i < val.length; i++) {
					if (bDate.get(bDate.DAY_OF_WEEK) == val[i]) {
						resDays ++;
					}
				}
				bDate.add(bDate.DATE,1);
			}
			return (int)(margin-resDays);
		} catch (Exception e) {
			return 0;
		}
	}
	
	/**
	 * 根据日期字符串得到它的Calendar对象
	 * 
	 * @param date
	 * @param df
	 * @return
	 */
	public static Calendar getCalendar(String date) {
		Calendar da = Calendar.getInstance();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");// 定义时间格式
		SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");// 定义时间格式
		try {
			
			try{
				da.setTime(df.parse(date));
			}catch(Exception ex){
				da.setTime(df1.parse(date));
			}			
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return da;
	}
	
	/**
	 * Calendar时分设置辅助方法
	 * @param cal
	 * @param hour
	 * @param minute
	 * @return
	 */
	public static Calendar setHourAndMinute(Calendar cal,int hour,int minute){
		cal.set(Calendar.HOUR_OF_DAY,hour);
		cal.set(Calendar.MINUTE,minute);
		return cal;
	}

public static void main(String[] args) {
		String str1 = "2009-04-07 12:00:00";
		String str2 = "2009-04-08 13:45:00";
		double days = CountDaysByDate.getDaysByDate(str1, str2);
		System.out.println(str1+"-》"+str2+"=="+days);
}
分享到:
评论

相关推荐

    SQL语句计算两个日期之间有多少个工作日的方法

    2. 如果两个日期跨越了多个周,首先计算跨越的完整周数乘以5(因为一周工作5天),然后加上第一周的工作日数,再加最后一周的工作日数。 以下是一个自定义函数`dbo.CalcWorkHours`,它接收两个日期参数`@bdate`...

    Access日期间隔查询

    在Access数据库中,日期间隔查询是一项常见的操作,它涉及到如何从日期字段中筛选出满足特定时间范围的数据...通过深入学习和实践,你可以进一步提升在Access中的日期处理能力,解决实际工作中的各种日期间隔查询问题。

    Java计算工作日

    通过以上步骤,我们可以编写一个高效的Java程序来计算给定时间段内按照特定间隔的工作日。这个程序可以根据实际情况进行扩展,例如考虑不同的工作日定义(比如某些国家周日不休息)或添加动态获取节假日的接口(如...

    计算两个时间相差多少年月日的sql算法

    - **DATEDIFF** 函数可以用来计算两个日期之间的差值,但默认返回的是间隔的总数量(如总天数、总月数等),而不是具体的年、月、日。 ### 三、具体算法详解 接下来,我们将详细分析提供的代码片段,这是一个存储...

    时间间隔计算器1.0

    这就是“时间间隔计算器1.0”所要解决的问题,一个简单而实用的小软件,帮助我们在日常生活中轻松计算两个日期之间相隔的天数。 这款软件的设计初衷十分人性化,它以直观的方式展示了两个日期之间的天数差异,无论...

    日期时间计算工具 时间间隔计算工具

    传统的计算方式可能涉及复杂的公式或者手动计算,而此工具则提供了一个直观且高效的解决方案,只需输入起始和结束时间,即可得到精确的小时数。 在"谢永乐"的标签下,我们可以推测这个工具可能与某个开发者的个人...

    SQL Server各种日期计算

    例如,计算两个日期间的工作日数量、确定一个日期所在的季度或者判断某个特定的日期是否存在(如情人节)。这些操作在编写涉及日期的SQL查询时非常常见,并且有助于完成各种复杂的业务逻辑。 最后,文章还提到了在...

    2日期相隔天数计算

    例如,你可以计算两个日期之间的完整工作日数,这需要考虑周末和节假日。这通常需要更复杂的逻辑,可能需要借助专门的日历库,如Python的`pandas`库或者`workalendar`库。 在实际应用中,日期计算可能涉及到时区...

    一个JAVA应用程序的 日期控件

    "一个JAVA应用程序的日期控件"就是一个专门解决此类问题的组件,它允许用户通过图形化界面来选择日期,而不是手动输入,从而提高用户体验并减少输入错误。 Java作为跨平台的编程语言,提供了丰富的库和API来创建...

    计算两个时间相差年月日时分秒.zip

    在这个名为"计算两个时间相差年月日时分秒.zip"的项目中,开发者创建了一个工具,能够精确地计算出两个日期之间的差值,以年、月、日、小时、分钟和秒的形式呈现。这个功能在多种场景下都非常实用,比如人力资源管理...

    vba事件日期.rar_NBH_VBA事件日期_VBa_vba日期_vba时间事件

    它们可以进行算术运算,如加减,以计算日期间隔。 2. **VBA日期函数**:VBA提供了一系列的内置函数来处理日期,例如`Date`返回当前系统日期,`Time`返回当前系统时间,`Now`返回当前系统日期和时间,`DateValue`从...

    移动端酒店入住日期选择.zip

    酒店入住日期选择功能通常需要具备以下特点:用户友好的界面、日期范围限制(如最短入住天数、最长可预订日期等)、日期间隔检查(避免用户选择连续的日期)以及节假日或特殊活动的标记。这个插件可能内置了这些功能...

    日期函数.rar

    在编程和数据分析中,日期函数扮演着至关重要的角色。它们帮助我们处理与日期和时间相关...在开发中,可能会用到日期函数来判断是否过期、计算工作日等。通过学习和实践这些日期函数,可以提升编程效率,解决实际问题。

    Excel日期函数应用教程.pdf

    这些日期函数的组合使用可以解决各种复杂的日期计算问题,比如计算年龄、确定两个日期间的间隔、调整日期到特定的月份等。在实际应用中,了解和熟练掌握这些函数能大大提高工作效率,特别是在处理大量日期数据时。

    Oracle日期函数

    在实际工作中,我们经常需要结合这些函数来解决各种日期时间问题,例如计算两个日期之间的天数、找出特定日期前一周的所有记录、或者根据业务需求格式化日期显示等。通过熟练掌握这些日期函数,我们可以更高效地处理...

    好用的日期选择器-js插件

    在IT行业中,前端开发经常会遇到需要用户输入日期或时间的情况,这时一个易用且功能强大的日期选择器就显得尤为重要。"好用的日期选择器-js插件"正是为解决这一需求而诞生的工具,它专注于提供高效、灵活的日期和...

    模拟携程、艺龙订房日期插件

    6. 时间日期处理:插件可能包含了对日期时间的处理函数,如计算日期间隔、检查日期合法性等。 7. AJAX:用于异步更新页面内容,比如在选择日期后立即显示可用房间或价格信息,无需刷新整个页面。 8. 测试与调试:...

    oracle日期函数全面总结

    本篇文章将全面总结Oracle中的日期函数,帮助你解决日常工作中遇到的各种日期处理问题。 1. **SYSDATE**: 这是最常用的内置常量,返回当前系统的日期和时间。例如: ```sql SELECT SYSDATE FROM DUAL; ``` 2. ...

    get-working-days:在php中计算工作日

    5. **计算工作日**:在两个日期间遍历,检查每个日期是否为工作日,如果是,则累加。同时,考虑到中国的节假日,可能需要引入一个包含节假日的数组或者使用第三方API来排除这些日期。 ```php function ...

    EXCEL VBA函数精选

    7. DateDiff函数:返回两个日期之间的时间间隔数。其语法为DateDiff(interval, date1, date2, [firstdayofweek], [firstweekofyear])。 8. DatePart函数:返回日期中的指定部分,如年、月或日。其语法为DatePart...

Global site tag (gtag.js) - Google Analytics