一月分四周的JAVA实现方法
需求:给定任意一个月,如何按照中国周的习惯,把一个月分成四个时间段
(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实现方法的更多相关文章
- 几种任务调度的 Java 实现方法与比较
综观目前的 Web 应用,多数应用都具备任务调度的功能.本文由浅入深介绍了几种任务调度的 Java 实现方法,包括 Timer,Scheduler, Quartz 以及 JCron Tab,并对其优缺 ...
- 几种任务调度的 Java 实现方法与比较Timer,ScheduledExecutor,Quartz,JCronTab
几种任务调度的 Java 实现方法与比较 综观目前的 Web 应用,多数应用都具备任务调度的功能.本文由浅入深介绍了几种任务调度的 Java 实现方法,包括 Timer,Scheduler, Quar ...
- 几种任务调度的 Java 实现方法与比较--转载
前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz ...
- java native方法及JNI实例 (转)
转自:http://blog.csdn.net/xw13106209/article/details/6989415 1.参考文献: http://blog.csdn.net/youjianbo_ha ...
- java native方法与JNI实现
native方法定义: 简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如 ...
- 几种任务调度的 Java 实现方法与比较 mark
任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz 开源工 ...
- 任务调度TimerTask&Quartz的 Java 实现方法与比较
文章引自--https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/ 前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自 ...
- 深入理解Java中方法的参数传递机制
形参和实参 我们知道,在Java中定义方法时,是可以定义参数的,比如: public static void main(String[] args){ } 这里的args就是一个字符串数组类型的参数. ...
- PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。
PySpark 的背后原理 Spark主要是由Scala语言开发,为了方便和其他系统集成而不引入scala相关依赖,部分实现使用Java语言开发,例如External Shuffle Service等 ...
随机推荐
- JS数据类型及函数的预编译
1.JS总体上分为:原始值和引用值 原始值分为:Number.Boolean.String.undefined.null;原始值不可改变的值,存储在栈[stack]的,先进后出! 引用值:array. ...
- HP Jack介绍
转载:https://www.cnblogs.com/Peter-Chen/p/3999212.html 目前市场上耳机分为4环耳机(图1所示,iphone型)和3环耳机(图2所示).4环耳机称为he ...
- spring 的web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java ...
- _map_char_stats
可以控制玩家进入地图后进行属性平衡. `comment` 备注 `map` 地图ID `vip`vip等级 `shengming`生命 `liliang` 力量 `minjie` 敏捷 `zhili` ...
- beyond compare 免费版
链接:https://pan.baidu.com/s/10lPUEpFPZU76HRbJfbZ2ZA 提取码:r2go
- 基于腾讯云CentOS7.4+MySQL5.7+Python3+uwsgi+nginx的Django项目部署
准备知识 1.django一个基于python的开源web框架,请确保自己熟悉它的框架目录结构. 2.uWSGI一个基于自有的uwsgi协议.wsgi协议和http服务协议的web网关 3.nginx ...
- C# Cache 设定过期时间的方法
1. 设定绝对过期时间 /// <summary> /// 设定绝对的过期时间 /// </summary> /// <param name="CacheKey ...
- SpringBoot mybatis配置
首先pom.xml <!-- mybatis 配置 --> <dependency> <groupId>org.mybatis.spring.boot</gr ...
- 雷林鹏分享:jQuery EasyUI 数据网格 - 合并单元格
jQuery EasyUI 数据网格 - 合并单元格 数据网格(datagrid)经常需要合并一些单元格.本教程将向您展示如何在数据网格(datagrid)中合并单元格. 为了合并数据网格(datag ...
- ionicAPP打开第三方APP
近来,碰到一个问题,需要在ionicAPP中打开第三方APP 然后,就找资料,发现了个比较好的解决方案 可以参考:https://blog.csdn.net/a727911438/article/de ...