需求:给定任意一个月,如何按照中国周的习惯,把一个月分成四个时间段

(1)以自然周为划分依据

(2)不能跨月

(3)把首尾自然周,天数较少的合并到其最近的自然周里面

(4)最后结果应该是吧一个月分成四个时间段,并给出每段的起止日期

大概需求就如上所述,不废话,上代码:(以封装好在main()函数里,直接copy即可,记得导相应的包和新建实体类)

public class one_month_four_week {

    public static void main(String[] args) {

    int year = 2017;
int month = 10;//改成你要的年月,运行即可查看结果
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1);// -1才正确
int days = cal.getActualMaximum(Calendar.DATE);// Calendar.DAY_OF_MONTH也对
System.out.println("首先,计算这个月有" + days + "天"); String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };// 国外一周起始
int[] chinaWeek = { 7, 1, 2, 3, 4, 5, 6 };// 对应成中国一周的第几天 SimpleDateFormat str_date_format = new SimpleDateFormat("yyyy-MM-dd"); List<EachDayAttr> monthDay = new ArrayList<>();
int week_of_month = 1;
for (int i = 1; i <= days; i++) {
EachDayAttr oneDay = new EachDayAttr();
oneDay.setWhich(i);
// 计算这个月的每一天,对应星期几
String dayStr = year + "-" + month + "-" + i;
Date daysDate = null;
try {
daysDate = str_date_format.parse(dayStr);
} catch (ParseException e) {
e.printStackTrace();
}
cal.setTime(daysDate);
int w1 = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的第几天
int which_day_chinaWeek = chinaWeek[w1];
System.out.println("该月的第"+ i +"天,该星期(外国习惯)的第"+ w1 +"天:"+ weekDays[w1] +">>对应中国周的第"+ which_day_chinaWeek +"天!");
//关键:该月每一天对应,中国周里面的第几周
if (which_day_chinaWeek == 1) {// 星期一,中国习惯里新的一周的开始
week_of_month++;
oneDay.setWeek(week_of_month);
} else {
oneDay.setWeek(week_of_month);
}
monthDay.add(oneDay);
} // 分组:按中国习惯分组
Map<Integer, List<EachDayAttr>> weekGroup = new TreeMap<>(); for (EachDayAttr oneDay : monthDay) {
if (weekGroup.containsKey(oneDay.getWeek())) {
weekGroup.get(oneDay.getWeek()).add(oneDay);
} else {
List<EachDayAttr> addGroup = new ArrayList<>();
addGroup.add(oneDay);
weekGroup.put(oneDay.getWeek(), addGroup);
}
} // 再分组:合并成四周
if (weekGroup.size() == 4) {
// weekGroup不做处理
} else if (weekGroup.size() == 5) {
if (weekGroup.get(1).size() < weekGroup.get(5).size()) {
weekGroup.get(2).addAll(weekGroup.get(1));
weekGroup.remove(1);
} else {
weekGroup.get(4).addAll(weekGroup.get(5));
weekGroup.remove(5);
}
} else if (weekGroup.size() == 6) {
weekGroup.get(2).addAll(weekGroup.get(1));
weekGroup.get(5).addAll(weekGroup.get(6));
weekGroup.remove(1);
weekGroup.remove(6);
} // 吧weekGroup按天数排序,取最小为开始日期,最大为结束日期即可
for (Entry<Integer, List<EachDayAttr>> entry : weekGroup.entrySet()) {
Collections.sort(entry.getValue(), new Comparator<EachDayAttr>() {
public int compare(EachDayAttr day1, EachDayAttr day2) {
return day1.getWhich() - day2.getWhich();
}
});
}
// 最后从分好组、排好序的weekGroup中取值封装
// weekGroup-->entry中健为整数,而值为list<?>集合
Map<Integer, String[]> rtResult = new HashMap<>();
int signWeek = 1;
for (Entry<Integer, List<EachDayAttr>> entry : weekGroup.entrySet()) {
String[] addResult = new String[2];
int firstDay = entry.getValue().get(0).getWhich();
int lastDay = entry.getValue().get(entry.getValue().size() - 1).getWhich();
addResult[0] = year + "-" + month + "-" + firstDay;
addResult[1] = year + "-" + month + "-" + lastDay;
rtResult.put(signWeek, addResult);
signWeek++;
} // 至此,输出看下结果
for (Entry<Integer, String[]> entry : rtResult.entrySet()) {
System.out.println("----该月第"+ entry.getKey() +"周-----");
System.out.println("开始日期:" + entry.getValue()[0]);
System.out.println("结束日期:" + entry.getValue()[1]);
} }
}

总结:上面方法。涉及知识点其实挺多,也是日常项目中遇到的比较多的,比如Calendar这个出来日期的类,还有分组排序、map的遍历等;

加上自定义的实体类,强迫症的小伙伴可以看下:

public class EachDayAttr {
private int which; private int week; private int flag; //get和set方法省略
}

最后。附上SQL大神直接用sql是怎么把一个月按中国周分的(这里一个月最多会有六周,为了更清楚,笔者有改动,但该sql精华不变)

select min(dt) 一周开始, max(dt) 一周结束, count(flag) 该周天数, ROW_NUMBER() over(order by 1) as 周数
from (
select level rn,
trunc(to_date(201707,'yyyymm'), 'mm') + level - 1 dt,
max(decode (to_char(trunc(to_date(201707,'yyyymm'), 'mm') + level - 1, 'd'), 2, level, 0)) over(order by level) flag
from dual
connect by level <= last_day(trunc(to_date(201707,'yyyymm'))) - trunc(to_date(201707,'yyyymm'), 'mm') + 1
)
group by flag
order by min(rn)

这是在mybatis里面实现的,传入的参数是整形的年月,比如int yyyymm = 201707;

一月分四周的JAVA实现方法的更多相关文章

  1. 几种任务调度的 Java 实现方法与比较

    综观目前的 Web 应用,多数应用都具备任务调度的功能.本文由浅入深介绍了几种任务调度的 Java 实现方法,包括 Timer,Scheduler, Quartz 以及 JCron Tab,并对其优缺 ...

  2. 几种任务调度的 Java 实现方法与比较Timer,ScheduledExecutor,Quartz,JCronTab

    几种任务调度的 Java 实现方法与比较 综观目前的 Web 应用,多数应用都具备任务调度的功能.本文由浅入深介绍了几种任务调度的 Java 实现方法,包括 Timer,Scheduler, Quar ...

  3. 几种任务调度的 Java 实现方法与比较--转载

    前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz ...

  4. java native方法及JNI实例 (转)

    转自:http://blog.csdn.net/xw13106209/article/details/6989415 1.参考文献: http://blog.csdn.net/youjianbo_ha ...

  5. java native方法与JNI实现

    native方法定义: 简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如 ...

  6. 几种任务调度的 Java 实现方法与比较 mark

    任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz 开源工 ...

  7. 任务调度TimerTask&Quartz的 Java 实现方法与比较

    文章引自--https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/ 前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自 ...

  8. 深入理解Java中方法的参数传递机制

    形参和实参 我们知道,在Java中定义方法时,是可以定义参数的,比如: public static void main(String[] args){ } 这里的args就是一个字符串数组类型的参数. ...

  9. PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。

    PySpark 的背后原理 Spark主要是由Scala语言开发,为了方便和其他系统集成而不引入scala相关依赖,部分实现使用Java语言开发,例如External Shuffle Service等 ...

随机推荐

  1. ASP.net MVC5 Code First填充测试数据到数据库

    问题的产生  最近在看Adam Freeman的“Pro ASP.NET MVC5”,于是在工作机上面搭建了相应的运行环境,但是在自己的机器上面只有代码,没有数据库.记得在code first中可以新 ...

  2. Kubernetes应用健康检查

    目录贴:Kubernetes学习系列 在实际生产环境中,想要使得开发的应用程序完全没有bug,在任何时候都运行正常,几乎 是不可能的任务.因此,我们需要一套管理系统,来对用户的应用程序执行周期性的健康 ...

  3. python selenium基于显示等待封装的一些常用方法

    import os import time from PIL import Image from selenium import webdriver from appium import webdri ...

  4. 线程同步——lock锁

    线程同步即解决线程安全问题的第三种方式——使用lock锁 代码实现: 其中,ReentrantLock是lock接口的实现类,这边是使用多态创建,访问成员方法时,编译看左,运行看右: Reentran ...

  5. Linux 高级文件管理

    1.标准输出(ls -l /dev/stdin 0 ),标准输入(ls -l /dev/stdout 1 ),错误输出(ls -l /dev/stderr 2 ). 2.ls /etc/passwd  ...

  6. inotify+rsync架构实现实时同步

    前序 使用inotify+rsync架构实现(文件夹/文件)实时同步, 双机之间需要ssh免密码配置(两步完成ssh免密码登录) 环境 客户端:192.168.137.176 (rsync + ino ...

  7. 结构体(struct)

    结构体 结构体是将不同类型的数据按照一定的功能需求进行整体封装,封装的数据类型与大小均可以由用户指定. 1 结构体的声明.定义及初始化 1.1 声明结构体类型 struct 结构体名 { 成员列表: ...

  8. hadoop MR的一些文件归属(包括临时文件存储情况)

    https://blog.csdn.net/bxyz1203/article/details/8057810

  9. Bootstrap3基础 table-striped 表格实现隔行换色(浅灰色与白色交替)

      内容 参数   OS   Windows 10 x64   browser   Firefox 65.0.2   framework     Bootstrap 3.3.7   editor    ...

  10. Learning-Python【补充篇】:Python之可变类型与不可变类型

    可变类型 值变了,但是id没有变,证明没有生成新的值而是在改变原值,原值是可变类型 不可变类型 值变了,id也跟着变,证明是重新开辟一块内存空间生成了新的值,而不是在改变原值,原值是不可变类型