最近开发项目的时候,遇到了一个需求:有很多个订单日期信息,我取消了其中的一个订单日期,需要根据原来的订单日期规则在最后追加一个新的订单日期。想了一下就整理了一个下面的算法,代码复制就可使用,请各路大神大神指点。
package cn.co.com;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class Test {
public static void main(String[] args) {
// 取得集合日期集合
List<String> headList = new ArrayList<>();
headList.add("2017-09-05");
headList.add("2017-09-06");
headList.add("2017-09-08");
headList.add("2017-09-09");
headList.add("2017-09-12");
headList.add("2017-09-13");
// headList.add("2017-09-19");
// headList.add("2017-09-20");
// headList.add("2017-09-22");
// headList.add("2017-09-26");
// headList.add("2017-09-27");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date a = getNewRuleDay(headList);
System.out.println(sdf.format(a));
}
/**
* 如果订单日期全部过期了,就按当前时间的期限内计算
* @param parameterList 日期集合
* @return 新的日期
*/
public static Date getNewRuleDay(List<String> parameterList) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date ruleday = getNewRuleDays(parameterList);
// 当前时间
Date nowDate = new Date();
// 得到日历
Calendar calendar = Calendar.getInstance();
// 把当前时间赋给日历
calendar.setTime(nowDate);
// 把时间设置到有效期内
calendar.add(Calendar.DAY_OF_MONTH, +2);
nowDate = calendar.getTime();
do {
ruleday = getNewRuleDays(parameterList);
parameterList.add(sdf.format(ruleday));
} while (ruleday.compareTo(nowDate) < 0);
return ruleday;
}
/**
* 计算正常的日期
* @param parameterList 日期集合
* @return 正常的日期
*/
private static Date getNewRuleDays(List<String> parameterList){
// 取得日期集合List
if (parameterList == null || parameterList.isEmpty()) {
return null;
}
/********************创建规则list开始******************************************************/
// 这段代码是在日期的规则没有存储在DB里面的时候使用的。
// 如果存储在DB里面了就可以把下面的代码省略。
// 建议存DB的格式为 【0,1,2,3,4,5,6】
// 对应的星期是 【0:周日、1:周一、2:周二、3:周三、4:周四、5:周五、6:周六】
/*************************************************************************************/
// 把取得的日期集合转换成临时星期List
List<String> tempWeekList = new ArrayList<>();
int tempWeekSize = parameterList.size();
for (int i = 0; i < tempWeekSize; i++) {
String forKey = parameterList.get(i);
tempWeekList.add(getWeekByNowDate(parseDateToString(forKey,"yyyy-MM-dd")));
}
// 新建规则星期List
List<String> weekList = new ArrayList<>();
int weekListSize = tempWeekList.size();
for (int i = 0; i < weekListSize; i++) {
String forKey = tempWeekList.get(i);
if (!weekList.contains(forKey)) {
weekList.add(forKey);
}
}
/********************创建规则list结束***********************/
// 最新的日期
String newDay = "";
// 日期集合List最后一条【取得最后的日期】
String lastDate = parameterList.get(parameterList.size()-1);
for (int i = 0; i < weekList.size(); i++) {
String key1 = getWeekByNowDate(parseDateToString(lastDate, "yyyy-MM-dd"));
String key2 = weekList.get(i);
if (key1.equals(key2)) {
if ((i+1) == weekList.size()) {
newDay = weekList.get(0);
}else{
newDay = weekList.get(i+1);
}
break;
}
}
return nextWeekdate(lastDate, newDay);
}
/**
* 根据传入的时间判断当前时间是星期几
* @param dt 当前时间
* @return 时间对应的星期【0:周日、1:周一、2:周二、3:周三、4:周四、5:周五、6:周六】
*/
private static String getWeekByNowDate(Date dt) {
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
int w = cal.get(Calendar.DAY_OF_WEEK)-1;
if (w < 0)
w = 0;
return String.valueOf(w);
}
/**
* 把String类型的转换为Date
* @param strDate 要转换的日期
* @param formatter 需要转换成的格式
* @return 转换后的日期
*/
private static Date parseDateToString(String strDate, String formatter) {
Date date = null;
SimpleDateFormat sdf = new SimpleDateFormat(formatter);
try {
sdf.setLenient(false);
date = sdf.parse(strDate);
} catch (ParseException e) {
return null;
}
return date;
}
/**
* 根据最后日计算需要追加的日期
* @param date 最后日期
* @param date 最新日期
* @return 新追加的预约日
*/
private static Date nextWeekdate(String lastDate, String newDay) {
Date lastAppointmentDate = parseDateToString(lastDate, "yyyy-MM-dd");
LocalDate date = UDateToLocalDate(lastAppointmentDate);
for (int i = 0; i < 7; i++) {
Date aDate = LocalDateToUdate(date.plusDays(i));
if (getWeekByNowDate(aDate).equals(newDay)) {
return aDate;
}
}
return null;
}
/**
* java.time.Date --> java.util.LocalDate
* @param date Date
* @return 日期类型变换
*/
private static LocalDate UDateToLocalDate(Date date) {
Instant instant = date.toInstant();
ZoneId zone = ZoneId.systemDefault();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
return localDateTime.toLocalDate();
}
/**
* java.time.LocalDate --> java.util.Date
* @param localDate LocalDate
* @return 日期类型变换
*/
private static Date LocalDateToUdate(LocalDate localDate) {
ZoneId zone = ZoneId.systemDefault();
Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
return Date.from(instant);
}
}