最近负责一个目标管理模块,需要实现一个让用户选择目标的时间维度功能。实现周目标的时候,本来应该根据这一周在哪个月所占的天数多就归属哪个月,结果让AI实现怎么写都有问题,明明告诉AI周四在哪个月就算哪个月但还是不行,记录一下。项目是jdk7,所以使用Calendar类。
package com.caikw.tsaicy.common.util;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
public class DateRangeUtil {
private static final DateFormat DF = new SimpleDateFormat("yyyy-MM-dd");
public static final class Target {
public final String weekText;
public final String monthText;
public final String quarterText;
public final String yearText;
private Target(String w, String m, String q, String y) {
this.weekText = w; this.monthText = m;
this.quarterText = q; this.yearText = y;
}
}
/**
* @param date 当前日期
* @param type 0=周;1=月,2=季度……
* @return Object[0]=weekText;Object[1]=startDate;Object[2]=endDate;
*/
public static Object[] get(Date date,int type){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
String text;
Date start,end;
switch(type){ //周
case 0: {
Calendar mon = (Calendar) cal.clone();
mon.setFirstDayOfWeek(Calendar.MONDAY);
mon.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
Calendar sun = (Calendar) mon.clone();
sun.add(Calendar.DATE, 6);
text = buildWeekText(cal);
start = mon.getTime();
end = sun.getTime();
break;
}
case 1: { //月
Calendar c1 = (Calendar) cal.clone();
c1.set(Calendar.DAY_OF_MONTH, 1);
Calendar c2 = (Calendar) c1.clone();
c2.set(Calendar.DAY_OF_MONTH, c1.getActualMaximum(Calendar.DAY_OF_MONTH));
text = buildMonthText(cal);
start = c1.getTime();
end = c2.getTime();
break;
}
case 2: { //季度
int quarter = cal.get(Calendar.MONTH) / 3 + 1;
int year = cal.get(Calendar.YEAR);
Calendar c1 = new GregorianCalendar(year, 3 * quarter - 3, 1);
Calendar c2 = new GregorianCalendar(year, 3 * quarter - 1, 1);
c2.set(Calendar.DAY_OF_MONTH, c2.getActualMaximum(Calendar.DAY_OF_MONTH));
text = buildQuarterText(cal);
start = c1.getTime();
end = c2.getTime();
break;
}
case 3: { //年
int year = cal.get(Calendar.YEAR);
Calendar c1 = new GregorianCalendar(year, Calendar.JANUARY, 1);
Calendar c2 = new GregorianCalendar(year, Calendar.DECEMBER, 31);
text = buildYearText(cal);
start = c1.getTime();
end = c2.getTime();
break;
}
default:
throw new IllegalArgumentException("type只支持0-3");
}
return new Object[]{text,DF.format(start),DF.format(end)};
}
/**
* 获取当前日期,前后各maxnum个周的日期表述&起止日期
* @param date 当前日期
* @param type 0=周;1=月,2=季度……
* @param maxnum 前后各几个
* @return list[0]=weekText;list[1]=startDate;list[2]=endDate;
*/
public static List<Object[]> getDateList(Date date,int type,int maxnum){
List<Object[]> list = new ArrayList<>(maxnum *2 +1);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int field;
switch(type){
case 0: field = Calendar.WEEK_OF_YEAR; break;
case 1: field = Calendar.MONTH; break;
case 2: field = Calendar.QUARTER; break;
case 3: field = Calendar.YEAR; break;
default: throw new IllegalArgumentException("type只支持0-3");
}
cal.add(field,-maxnum);
for(int i = 0; i < maxnum *2 +1; i++){
list.add(get(cal.getTime(),type));
cal.add(field,1);
}
return list;
}
/**
* 返回Object[0]的内容,某年某月第某周(非今年) 或某月第某周(今年)
*
* @return
*/
/* ---------------- 周 ---------------- */
private static String buildWeekText(Calendar cal) {
Calendar now = Calendar.getInstance();
int currentYear = now.get(Calendar.YEAR);
/* ---- 当前周的周四 ---- */
Calendar thu = (Calendar) cal.clone();
thu.setFirstDayOfWeek(Calendar.MONDAY);
thu.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
/* ---- 本周判断 ---- */
if (thu.get(Calendar.YEAR) == currentYear &&
thu.get(Calendar.WEEK_OF_YEAR) == now.get(Calendar.WEEK_OF_YEAR)) {
return "本周";
}
int targetYear = thu.get(Calendar.YEAR);
int targetMonth = thu.get(Calendar.MONTH);
/* ---- 1~4 号里有没有周四? ---- */
boolean thuIn1_4 = false;
for (int d = 1; d <= 4; d++) {
Calendar c = new GregorianCalendar(targetYear, targetMonth, d);
if (c.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY) {
thuIn1_4 = true;
break;
}
}
Calendar firstMon; // 本月第一周的起始周一
int weekCount = 1; // 默认从第 1 周开始数
if (thuIn1_4) {
/* 情况1:1~4 号出现周四 → 本月第 1 周就是 1~7 号 */
firstMon = new GregorianCalendar(targetYear, targetMonth, 1);
// 把 1 号调成周一(可能要去上个月)
while (firstMon.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
firstMon.add(Calendar.DATE, -1);
}
} else {
/* 情况2:1~4 号没有周四 → 1 号属于上月最后一周,
本月第 1 周是“本月第一个周四”所在周 */
Calendar firstThu = new GregorianCalendar(targetYear, targetMonth, 1);
while (firstThu.get(Calendar.DAY_OF_WEEK) != Calendar.THURSDAY) {
firstThu.add(Calendar.DATE, 1);
}
firstMon = (Calendar) firstThu.clone();
firstMon.add(Calendar.DATE, -3); // 推到周一
}
/* ---- 当前周一(用来数周)---- */
Calendar mon = (Calendar) thu.clone();
mon.add(Calendar.DATE, -3);
/* ---- 从 firstMon 开始数周 ---- */
while (firstMon.before(mon)) {
firstMon.add(Calendar.DATE, 7);
weekCount++;
}
return (targetYear == currentYear)
? String.format("%d月第%d周", targetMonth + 1, weekCount)
: String.format("%d年%d月第%d周", targetYear, targetMonth + 1, weekCount);
}
/* ---------------- 月 ---------------- */
private static String buildMonthText(Calendar cal) {
int tarYear = cal.get(Calendar.YEAR);
int tarMonth = cal.get(Calendar.MONTH);
int nowYear = Calendar.getInstance().get(Calendar.YEAR);
int nowMonth = Calendar.getInstance().get(Calendar.MONTH);
if(tarYear == nowYear && tarMonth == nowMonth){
return "本月";
}
return (tarYear == nowYear)
?String.format("%d月", tarMonth + 1)
: String.format("%d年%d月", tarYear, tarMonth + 1);
}
/* ---------------- 季 ---------------- */
private static String buildQuarterText(Calendar cal) {
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH); // 0-based
int quarter = month / 3 + 1;
int nowYear = Calendar.getInstance().get(Calendar.YEAR);
int nowMonth = Calendar.getInstance().get(Calendar.MONTH);
int nowQuarter = nowMonth / 3 + 1;
if (year == nowYear && quarter == nowQuarter){
return "本季";
}
return String.format("%d年第%d季度", year, quarter);
}
/* ---------------- 年 ---------------- */
private static String buildYearText(Calendar cal) {
int year = cal.get(Calendar.YEAR);
int nowYear = Calendar.getInstance().get(Calendar.YEAR);
return (year == nowYear) ? "本年" : String.format("%d年", year);
}
private DateRangeUtil() {}
}

1万+

被折叠的 条评论
为什么被折叠?



