`
远去的渡口
  • 浏览: 467498 次
  • 性别: Icon_minigender_2
  • 来自: 上海转北京
社区版块
存档分类
最新评论

已知起始日期,求两日期之间共有多少自然周

阅读更多

今天对于日期这个问题花的时间比较多,在这里总结一下,由于考虑到自然周问题,还有时间跨度的问题,两个年份之间的临界条件上的考虑,还要考虑到一个年份共有多个周,比较复杂了。这里写了一个完整的Demo版本,贴出来分享一下。

package com.inventec.singular.service.blog;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateDiff {

	public static String formatDate(Date date) {
		String formDate = "";
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		formDate = format.format(date);

		return formDate;
	}

	public static Date formatDate(String date) throws ParseException {
		Date time = new Date();

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		time = format.parse(date);

		return time;

	}

	/**
	 * 计算指定年度共有多少个周。
	 * 
	 * @param year
	 *            格式 yyyy ,必须大于1900年度 小于9999年
	 * @return
	 */
	public static int getWeekNumByYear(final int year) {
		if (year < 1900 || year > 9999) {
			throw new NullPointerException("年度必须大于等于1900年小于等于9999年");
		}
		int result = 52;// 每年至少有52个周 ,最多有53个周。
		String date = getYearWeekFirstDay(year, 53);

		if (date.substring(0, 4).equals(year + "")) { // 判断年度是否相符,如果相符说明有53个周。
			// System.out.println(date);
			result = 53;
		}
		return result;
	}

	/**
	 * 计算某年某周的开始日期
	 * 
	 * 
	 * @param yearNum
	 *            格式 yyyy ,必须大于1900年度 小于9999年
	 * 
	 * @param weekNum
	 *            1到52或者53
	 * @return 日期,格式为yyyy-MM-dd
	 */
	public static String getYearWeekFirstDay(int yearNum, int weekNum) {

		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.SUNDAY); // 设置每周的第一天为星期日
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);// 每周从周日开始

		// 上面两句代码配合,才能实现,每年度的第一个周,是包含第一个星期日的那个周。

		cal.setMinimalDaysInFirstWeek(7); // 设置每周最少为7天

		cal.set(Calendar.YEAR, yearNum);
		cal.set(Calendar.WEEK_OF_YEAR, weekNum);

		// 分别取得当前日期的年、月、日
		return formatDate(cal.getTime());
	}

	public static int weeksBetweenDays(String start, String end) {
		int counts = 1;
		Calendar c = Calendar.getInstance();
		Calendar c1 = Calendar.getInstance();
		try {
			Date startDate = formatDate(start);
			Date endDate = formatDate(end);
			c.setTime(startDate);
			c1.setTime(endDate);

			int weekofYear = c.get(Calendar.WEEK_OF_YEAR);
			int weekofYear1 = c1.get(Calendar.WEEK_OF_YEAR);

			System.out.println("start:" + weekofYear + " end week:"
					+ weekofYear1);

			if (c.get(Calendar.YEAR) == c1.get(Calendar.YEAR)) {
				counts = weekofYear1 - weekofYear + 1;

			} else {

				int difyear = c1.get(Calendar.YEAR) - c.get(Calendar.YEAR);
				//				

				System.out.println("year diff =" + difyear + " starty="
						+ c.get(Calendar.YEAR));
				if (difyear == 1) {// 年份相差一年
					int startyearWeeks = getWeekNumByYear(c.get(Calendar.YEAR));
					String date = getYearWeekFirstDay(c.get(Calendar.YEAR),
							startyearWeeks);

					System.out.println(date);
					int ds = java.sql.Date.valueOf(date).compareTo(
							java.sql.Date.valueOf(start));
					System.out.println(ds);

					if (ds <= 0) { // 这一年最后一周的开始一天小于用户选择的开始日期,比如,2009年最后一周的开始日期是2009-12-27号,所以开始日期大于或等于2009-12-27号的特殊处理。
						counts = weekofYear1 - weekofYear + 1;
					} else {
						counts = getWeekNumByYear(c.get(Calendar.YEAR))
								- weekofYear + weekofYear1 + 1;
					}

				} else if (difyear > 1) {// 年份相差大于一年时,要考虑到
					for (int i = 0; i <= difyear; i++) {
						int startAllWeeks = getWeekNumByYear(c
								.get(Calendar.YEAR)
								+ i); // 开始日期的年份+i,如2007-12-22到2011-01-09,这里是遍历出07年,08年,09年分别有多少个周

						if (i == 0) {//开始日期这一年的周差,如果07-12-22是第51周,07年共有52个周,那么,这里得到1.
							counts = startAllWeeks - weekofYear;
						} else if (i < difyear) {//除开始日期与结束日期所在一年的年份的周差。也就是08年共有多少周
							counts += startAllWeeks;
						} else if (i == difyear) { //加上09年所在的周
							counts += weekofYear1;
						}

					}
					counts += 1;
				}

			}
			// }

		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return counts;
	}

	public static void main(String[] args) {
		int days = weeksBetweenDays("2009-12-28", "2010-11-03");
		// String date="2010-01-06";
		// String date1="2010-01-04";
		// int
		// ds=java.sql.Date.valueOf(date).compareTo(java.sql.Date.valueOf(date1));
		// System.out.println(ds);
		System.out.println("the weeks of this period is :" + days);
	}
}

 

 

分享到:
评论
4 楼 fendou123321 2017-02-13  
又仔细看了下,如果设置周日为每周的第一天,应该是正确的,如果把每周的第一天改为其他值,就需要调整代码了
3 楼 fendou123321 2017-02-13  
开始日期2016-12-19
结束日期2017-02-05
只用博主代码运行出来 相差周次是8
其实应该是7
中间有一个周是跨年的2016-12-26  2017-01-01
2 楼 远去的渡口 2010-01-28  
@老抛,
  没想到大牛人物还看了我这种算法,激动一下
当初也考虑过这么计算,但是感觉时间跨度为几年的话就要循环很多次,我这里算是避开了几整年的自然周之和,因为一年有多少周可以一步到位,只是我这样考虑的因素就复杂了点
1 楼 抛出异常的爱 2010-01-28  
先找到star日的指定周日
再一周一周加过去
当时间大于结束时间时\
就得出了周数.
效率没你的高
但看起来会更清楚一些

相关推荐

Global site tag (gtag.js) - Google Analytics