优化抽取实现接口
This commit is contained in:
parent
a5887fb1fb
commit
03eabb1b81
36
src/main/java/com/lxyer/timer/AbstractTask.java
Normal file
36
src/main/java/com/lxyer/timer/AbstractTask.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package com.lxyer.timer;
|
||||||
|
|
||||||
|
import com.lxyer.timer.scheduled.Scheduled;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by liangxianyou at 2018/7/23 14:33.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractTask implements Task {
|
||||||
|
protected String name;
|
||||||
|
private long theTime;
|
||||||
|
private Scheduled scheduled;
|
||||||
|
|
||||||
|
public AbstractTask(String name, Scheduled scheduled) {
|
||||||
|
this.name = name;
|
||||||
|
this.scheduled = scheduled;
|
||||||
|
this.theTime = scheduled.theTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long nextTime(){
|
||||||
|
LocalDateTime next = scheduled.nextTime();
|
||||||
|
this.theTime = next.toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||||||
|
|
||||||
|
/*SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
System.out.println("下次执行:"+ sdf.format(next.toInstant(ZoneOffset.of("+8")).toEpochMilli()));*/
|
||||||
|
return theTime;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public long theTime(){
|
||||||
|
return theTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,497 +1,10 @@
|
|||||||
package com.lxyer.timer;
|
package com.lxyer.timer;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZoneOffset;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by liangxianyou at 2018/7/23 14:33.
|
* @author: liangxianyou at 2018/8/5 19:32.
|
||||||
*/
|
*/
|
||||||
public abstract class Task implements Runnable {
|
public interface Task extends Runnable{
|
||||||
protected String name;
|
|
||||||
protected long nextTime;
|
|
||||||
private TimerScheduled timerScheduled;
|
|
||||||
public abstract void run();
|
|
||||||
|
|
||||||
public Task(String name, String cfg){
|
|
||||||
this.name = name;
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
timerScheduled = new TimerScheduled(now.getYear(), now.getMonthValue(), cfg);
|
|
||||||
nextTime = timerScheduled.nextTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long nextTime(){
|
|
||||||
LocalDateTime next = timerScheduled.nextTime();
|
|
||||||
this.nextTime = next.toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
|
||||||
return nextTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 时间解析器
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("Duplicates")
|
|
||||||
class TimerScheduled {
|
|
||||||
private int year;
|
|
||||||
private int month;
|
|
||||||
private int[] minutes;
|
|
||||||
private int[] hours;
|
|
||||||
private int[] days;
|
|
||||||
private int[] monthes;
|
|
||||||
private int[] weeks;
|
|
||||||
String[] cfgArr;
|
|
||||||
|
|
||||||
LocalDateTime nextTime;
|
|
||||||
private int _y,_M,_d,_H,_m;
|
|
||||||
|
|
||||||
public TimerScheduled(int year, int month, String cfg) {
|
|
||||||
this.year = year;
|
|
||||||
this.month = month;
|
|
||||||
this.cfgArr = cfg.split(" ");
|
|
||||||
|
|
||||||
setWeeks();
|
|
||||||
setMonthes();
|
|
||||||
setDays();
|
|
||||||
setHours();
|
|
||||||
setMinutes();
|
|
||||||
|
|
||||||
//寻找初始合法时间
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
_y = now.getYear();
|
|
||||||
_M= now.getMonthValue();
|
|
||||||
_d= now.getDayOfMonth();
|
|
||||||
_H= now.getHour();
|
|
||||||
_m= now.getMinute();
|
|
||||||
|
|
||||||
String cmd = "";//y M d H m
|
|
||||||
if (days.length == 0) cmd = "M";
|
|
||||||
do {
|
|
||||||
carry(cmd);
|
|
||||||
int inx;
|
|
||||||
if ((inx = nowOk(monthes, _M)) < 0){
|
|
||||||
cmd = "y";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_M = monthes[inx];
|
|
||||||
|
|
||||||
if ((inx = nowOk(days, _d)) < 0){
|
|
||||||
cmd = "M";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_d = days[inx];
|
|
||||||
|
|
||||||
if ((inx = nowOk(hours, _H)) < 0){
|
|
||||||
cmd = "d";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_H = hours[inx];
|
|
||||||
|
|
||||||
if ((inx = nowOk(minutes, _m)) < 0){
|
|
||||||
cmd = "H";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_m = minutes[inx];
|
|
||||||
break;
|
|
||||||
}while (true);
|
|
||||||
|
|
||||||
if (_y == now.getYear() && _M == now.getMonthValue() && _d == now.getDayOfMonth()
|
|
||||||
&& _H == now.getHour() && _m == now.getMinute()){
|
|
||||||
carry("m");
|
|
||||||
}
|
|
||||||
|
|
||||||
nextTime = LocalDateTime.of(_y, _M, _d, _H, _m);
|
|
||||||
System.out.println(cfg);
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
System.out.println("init:"+ sdf.format(nextTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下一次执行的时间
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected LocalDateTime nextTime(){
|
|
||||||
|
|
||||||
String cmd = "m";
|
|
||||||
carry(cmd);
|
|
||||||
nextTime = LocalDateTime.of(year, month
|
|
||||||
, _d == -1? nextTime.getDayOfMonth() : _d
|
|
||||||
, _H == -1? nextTime.getHour() : _H
|
|
||||||
, _m == -1? nextTime.getMinute() : _m);
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
System.out.println("下次执行:"+ sdf.format(nextTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()));
|
|
||||||
return nextTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过发送指令进行进位
|
|
||||||
* @param cmd 进位指令
|
|
||||||
*/
|
|
||||||
private void carry(String cmd){
|
|
||||||
int inx;
|
|
||||||
while (!"".equals(cmd)){
|
|
||||||
switch (cmd) {
|
|
||||||
case "y":
|
|
||||||
_y = this.year = ++_y;
|
|
||||||
_M = this.month = monthes[0];
|
|
||||||
setDays();
|
|
||||||
if (days.length == 0){
|
|
||||||
cmd = "M";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_d = days[0];
|
|
||||||
_H = hours[0];
|
|
||||||
_m = minutes[0];
|
|
||||||
break;
|
|
||||||
case "M":
|
|
||||||
if (_M < monthes[0]){
|
|
||||||
_M = monthes[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
inx = Arrays.binarySearch(monthes, _M);
|
|
||||||
if (inx < 0 || inx >= monthes.length-1) {
|
|
||||||
cmd = "y";
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
_M = this.month = monthes[inx+1];
|
|
||||||
setDays();
|
|
||||||
if (days.length == 0){
|
|
||||||
cmd = "M";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_d = days[0];
|
|
||||||
_H = hours[0];
|
|
||||||
_m = minutes[0];
|
|
||||||
break;
|
|
||||||
case "d":
|
|
||||||
if (_d < days[0]){
|
|
||||||
_d = days[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
inx = Arrays.binarySearch(days, _d);
|
|
||||||
if (inx < 0 || inx >= days.length-1) {
|
|
||||||
cmd = "M";
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
_d = days[inx+1];
|
|
||||||
_H = hours[0];
|
|
||||||
_m = minutes[0];
|
|
||||||
break;
|
|
||||||
case "H":
|
|
||||||
if (_H < hours[0]){
|
|
||||||
_H = hours[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
inx = Arrays.binarySearch(hours, _H);
|
|
||||||
if (inx < 0 || inx >= hours.length -1) {
|
|
||||||
cmd = "d";
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
_H = hours[inx+1];
|
|
||||||
_m = minutes[0];
|
|
||||||
break;
|
|
||||||
case "m":
|
|
||||||
if (_m < minutes[0]){
|
|
||||||
_m = minutes[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
inx = Arrays.binarySearch(minutes, _m);
|
|
||||||
if (inx < 0 || inx >= minutes.length -1) {
|
|
||||||
cmd = "H";
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
_m = minutes[inx+1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cmd = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到初始合法时间的索引
|
|
||||||
* @param arr 合法时间序列
|
|
||||||
* @param n 初始选中值
|
|
||||||
* @return 合法时间的索引
|
|
||||||
*/
|
|
||||||
private int nowOk(int[] arr, int n){
|
|
||||||
if (arr == null || arr.length == 0) return -1;
|
|
||||||
if (arr[0] > n)
|
|
||||||
return 0;
|
|
||||||
if (arr[arr.length-1] < n)
|
|
||||||
return -1;
|
|
||||||
if (arr[arr.length-1] == n)
|
|
||||||
return arr.length-1;
|
|
||||||
|
|
||||||
for (int i = 0; i < arr.length-1; i++) {
|
|
||||||
if ((arr[i] < n && arr[i+1] > n) || arr[i] == n){
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 以下为 初始化合法时间 weeks,monthes,days,hour,minutes 序列 */
|
|
||||||
private void setMinutes(){
|
|
||||||
String cfg = cfgArr[0];
|
|
||||||
if ("*".equals(cfg)){//*
|
|
||||||
minutes = new int[60];
|
|
||||||
for (int i = 0; i < 60; i++) {
|
|
||||||
minutes[i] = i;
|
|
||||||
}
|
|
||||||
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
|
||||||
minutes = new int[1];
|
|
||||||
minutes[0] = Integer.parseInt(cfg);
|
|
||||||
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
minutes = new int[60/p];
|
|
||||||
for (int i = 0; i < minutes.length; i++) {
|
|
||||||
minutes[i] = i*p;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
|
||||||
String[] strings = cfg.split(",");
|
|
||||||
minutes = new int[strings.length];
|
|
||||||
for (int i = 0; i < strings.length; i++) {
|
|
||||||
minutes[i] = Integer.parseInt(strings[i]);
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
|
||||||
String[] split = cfg.split("-");
|
|
||||||
int s = Integer.parseInt(split[0]);
|
|
||||||
int e = Integer.parseInt(split[1]);
|
|
||||||
|
|
||||||
minutes = new int[e-s +1];
|
|
||||||
for (int i = 0; i < minutes.length; i++) {
|
|
||||||
minutes[i] = s+i;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
String[] str2Arr = strArr[0].split("-");
|
|
||||||
int s = Integer.parseInt(str2Arr[0]);
|
|
||||||
int e = Integer.parseInt(str2Arr[1]);
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
|
|
||||||
minutes = new int[(e-s)/p];
|
|
||||||
for (int i = 0; i < minutes.length; i++) {
|
|
||||||
minutes[i] = s + i*p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setHours(){
|
|
||||||
String cfg = cfgArr[1];
|
|
||||||
if ("*".equals(cfg)){//*
|
|
||||||
hours = new int[24];
|
|
||||||
for (int i = 0; i < hours.length; i++) {
|
|
||||||
hours[i] = i;
|
|
||||||
}
|
|
||||||
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
|
||||||
hours = new int[1];
|
|
||||||
hours[0] = Integer.parseInt(cfg);
|
|
||||||
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
hours = new int[24/p];
|
|
||||||
for (int i = 0; i < hours.length; i++) {
|
|
||||||
hours[i] = i*p;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
|
||||||
String[] strArr = cfg.split(",");
|
|
||||||
hours = new int[strArr.length];
|
|
||||||
for (int i = 0; i < strArr.length; i++) {
|
|
||||||
hours[i] = Integer.parseInt(strArr[i]);
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
|
||||||
String[] split = cfg.split("-");
|
|
||||||
int s = Integer.parseInt(split[0]);
|
|
||||||
int e = Integer.parseInt(split[1]);
|
|
||||||
|
|
||||||
hours = new int[e-s +1];
|
|
||||||
for (int i = 0; i < hours.length; i++) {
|
|
||||||
hours[i] = s+i;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
String[] str2Arr = strArr[0].split("-");
|
|
||||||
int s = Integer.parseInt(str2Arr[0]);
|
|
||||||
int e = Integer.parseInt(str2Arr[1]);
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
|
|
||||||
hours = new int[(e-s)/p];
|
|
||||||
for (int i = 0; i < hours.length; i++) {
|
|
||||||
hours[i] = s + i*p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setWeeks(){
|
|
||||||
String cfg = cfgArr[4];
|
|
||||||
if ("*".equals(cfg)){//*
|
|
||||||
weeks = new int[7];
|
|
||||||
for (int i = 0; i < weeks.length; i++) {
|
|
||||||
weeks[i] = i+1;
|
|
||||||
}
|
|
||||||
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
|
||||||
weeks = new int[1];
|
|
||||||
weeks[0] = Integer.parseInt(cfg);
|
|
||||||
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
weeks = new int[7/p];
|
|
||||||
for (int i = 0; i < weeks.length; i++) {
|
|
||||||
weeks[i] = i*p;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
|
||||||
String[] strArr = cfg.split(",");
|
|
||||||
weeks = new int[strArr.length];
|
|
||||||
for (int i = 0; i < strArr.length; i++) {
|
|
||||||
weeks[i] = Integer.parseInt(strArr[i]);
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
|
||||||
String[] split = cfg.split("-");
|
|
||||||
int s = Integer.parseInt(split[0]);
|
|
||||||
int e = Integer.parseInt(split[1]);
|
|
||||||
|
|
||||||
weeks = new int[e-s +1];
|
|
||||||
for (int i = 0; i < weeks.length; i++) {
|
|
||||||
weeks[i] = s+i;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
String[] str2Arr = strArr[0].split("-");
|
|
||||||
int s = Integer.parseInt(str2Arr[0]);
|
|
||||||
int e = Integer.parseInt(str2Arr[1]);
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
|
|
||||||
weeks = new int[(e-s)/p];
|
|
||||||
for (int i = 0; i < weeks.length; i++) {
|
|
||||||
weeks[i] = s + i*p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setMonthes(){
|
|
||||||
String cfg = cfgArr[3];
|
|
||||||
if ("*".equals(cfg)){//*
|
|
||||||
monthes = new int[12];
|
|
||||||
for (int i = 0; i < monthes.length; i++) {
|
|
||||||
monthes[i] = i+1;
|
|
||||||
}
|
|
||||||
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
|
||||||
monthes = new int[1];
|
|
||||||
monthes[0] = Integer.parseInt(cfg);
|
|
||||||
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
monthes = new int[12/p];
|
|
||||||
for (int i = 0; i < monthes.length; i++) {
|
|
||||||
monthes[i] = i*p;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
|
||||||
String[] strArr = cfg.split(",");
|
|
||||||
monthes = new int[strArr.length];
|
|
||||||
for (int i = 0; i < strArr.length; i++) {
|
|
||||||
monthes[i] = Integer.parseInt(strArr[i]);
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
|
||||||
String[] split = cfg.split("-");
|
|
||||||
int s = Integer.parseInt(split[0]);
|
|
||||||
int e = Integer.parseInt(split[1]);
|
|
||||||
|
|
||||||
monthes = new int[e-s +1];
|
|
||||||
for (int i = 0; i < monthes.length; i++) {
|
|
||||||
monthes[i] = s+i;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
String[] str2Arr = strArr[0].split("-");
|
|
||||||
int s = Integer.parseInt(str2Arr[0]);
|
|
||||||
int e = Integer.parseInt(str2Arr[1]);
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
|
|
||||||
monthes = new int[(e-s)/p];
|
|
||||||
for (int i = 0; i < monthes.length; i++) {
|
|
||||||
monthes[i] = s + i*p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setDays(){
|
|
||||||
String cfg = cfgArr[2];
|
|
||||||
//当前月份总天数,
|
|
||||||
LocalDate firstDay = LocalDate.of(year, month, 1);
|
|
||||||
int lengthOfMonth = firstDay.lengthOfMonth();
|
|
||||||
|
|
||||||
if ("*".equals(cfg)){//*
|
|
||||||
days = new int[lengthOfMonth];
|
|
||||||
for (int i = 0; i < days.length; i++) {
|
|
||||||
days[i] = i+1;
|
|
||||||
}
|
|
||||||
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
|
||||||
days = new int[1];
|
|
||||||
days[0] = Integer.parseInt(cfg);
|
|
||||||
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
days = new int[lengthOfMonth/p];
|
|
||||||
for (int i = 0; i < days.length; i++) {
|
|
||||||
days[i] = i*p;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
|
||||||
String[] strArr = cfg.split(",");
|
|
||||||
days = new int[strArr.length];
|
|
||||||
for (int i = 0; i < strArr.length; i++) {
|
|
||||||
days[i] = Integer.parseInt(strArr[i]);
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
|
||||||
String[] split = cfg.split("-");
|
|
||||||
int s = Integer.parseInt(split[0]);
|
|
||||||
int e = Integer.parseInt(split[1]);
|
|
||||||
|
|
||||||
days = new int[e-s +1];
|
|
||||||
for (int i = 0; i < days.length; i++) {
|
|
||||||
days[i] = s+i;
|
|
||||||
}
|
|
||||||
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
|
||||||
String[] strArr = cfg.split("/");
|
|
||||||
String[] str2Arr = strArr[0].split("-");
|
|
||||||
int s = Integer.parseInt(str2Arr[0]);
|
|
||||||
int e = Integer.parseInt(str2Arr[1]);
|
|
||||||
int p = Integer.parseInt(strArr[1]);
|
|
||||||
|
|
||||||
days = new int[(e-s)/p];
|
|
||||||
for (int i = 0; i < days.length; i++) {
|
|
||||||
days[i] = s + i*p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int firstWeek = firstDay.getDayOfWeek().getValue();
|
|
||||||
List<Integer> allDay = new ArrayList<>();
|
|
||||||
for (int i = 0; i < days.length; i++) {
|
|
||||||
//int week = 7 - Math.abs(i - firstWeek) % 7;//当前星期X
|
|
||||||
int week;
|
|
||||||
int d = days[i];
|
|
||||||
if (d + firstWeek <= 8){
|
|
||||||
week = firstWeek + d - 1;
|
|
||||||
}else {
|
|
||||||
week = (d - (8-firstWeek))%7;
|
|
||||||
if (week == 0) week = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
//System.out.printf("M:%s,d:%s,w:%s%n", month, d, week);
|
|
||||||
|
|
||||||
if (Arrays.binarySearch(weeks, week) > -1){
|
|
||||||
allDay.add(d);//加入日期
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
days = new int[allDay.size()];
|
|
||||||
for (int i = 0; i < allDay.size(); i++) {
|
|
||||||
days[i] = allDay.get(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
long nextTime();
|
||||||
|
long theTime();
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,33 @@
|
|||||||
package com.lxyer.timer;
|
package com.lxyer.timer;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by liangxianyou at 2018/7/23 14:07.
|
* @author: liangxianyou
|
||||||
*/
|
*/
|
||||||
public class TimerExecutor {
|
public class TimerExecutor {
|
||||||
private TimerQueue queue = new TimerQueue();
|
private TimerQueue queue = new TimerQueue();
|
||||||
private ExecutorService executor;
|
private ExecutorService executor;
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建定时调度器
|
|
||||||
* @param n 调度线程数
|
|
||||||
*/
|
|
||||||
public TimerExecutor(int n) {
|
public TimerExecutor(int n) {
|
||||||
executor = Executors.newFixedThreadPool(n);
|
executor = Executors.newFixedThreadPool(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Task task){
|
public void add(AbstractTask task){
|
||||||
queue.put(task);
|
queue.put(task);
|
||||||
}
|
}
|
||||||
private void add(Task task, boolean upTime){
|
private void add(AbstractTask task, boolean upTime){
|
||||||
if (upTime) task.nextTime();
|
if (upTime) task.nextTime();
|
||||||
queue.put(task);
|
queue.put(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 启动定时调度
|
|
||||||
*/
|
|
||||||
public void start() {
|
public void start() {
|
||||||
new Thread(()->{
|
new Thread(()->{
|
||||||
while (true){
|
while (true){
|
||||||
try{
|
try{
|
||||||
Task take = null;
|
AbstractTask take = null;
|
||||||
try {
|
try {
|
||||||
take = queue.take();
|
take = queue.take();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -52,75 +43,3 @@ public class TimerExecutor {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimerQueue{
|
|
||||||
Object lock = new Object();
|
|
||||||
Task[] queue = new Task[128];
|
|
||||||
Set<String> names = new HashSet<>();
|
|
||||||
int size=0;
|
|
||||||
|
|
||||||
void put(Task task) {
|
|
||||||
remove(task.name);
|
|
||||||
synchronized (lock){
|
|
||||||
int inx = size;//目标坐标
|
|
||||||
while (inx > 0 && queue[inx-1].nextTime > task.nextTime ){
|
|
||||||
inx--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queue.length == size+1)
|
|
||||||
queue = Arrays.copyOf(queue, size * 2);
|
|
||||||
|
|
||||||
for (int i = size+1; i > inx; i--) {
|
|
||||||
queue[i] = queue[i-1];
|
|
||||||
queue[i-1] = null;
|
|
||||||
}
|
|
||||||
queue[inx] = task;
|
|
||||||
|
|
||||||
size++;
|
|
||||||
names.add(task.name);
|
|
||||||
lock.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Task take() throws InterruptedException {
|
|
||||||
synchronized (lock){
|
|
||||||
if (size == 0) lock.wait();
|
|
||||||
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
long nextTime = queue[0].nextTime;
|
|
||||||
|
|
||||||
if (currentTime >= nextTime){
|
|
||||||
Task task = queue[0];
|
|
||||||
for (int i = 0; i < size;i++) {
|
|
||||||
queue[i] = queue[i+1];
|
|
||||||
}
|
|
||||||
queue[size-1] = null;
|
|
||||||
size--;
|
|
||||||
return task;
|
|
||||||
}else {
|
|
||||||
lock.wait(nextTime - currentTime);
|
|
||||||
return take();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Task remove(String name){
|
|
||||||
synchronized (lock){
|
|
||||||
if(!names.contains(name)) return null;
|
|
||||||
|
|
||||||
Task take = null;
|
|
||||||
for (int i = 0; i < size-1; i++) {
|
|
||||||
if (name.equals(queue[i].name)){
|
|
||||||
take = queue[i];
|
|
||||||
while (i < size+1){
|
|
||||||
queue[i] = queue[i+1];
|
|
||||||
queue[i+1] = null;
|
|
||||||
}
|
|
||||||
names.remove(name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return take;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
80
src/main/java/com/lxyer/timer/TimerQueue.java
Normal file
80
src/main/java/com/lxyer/timer/TimerQueue.java
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package com.lxyer.timer;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by liangxianyou at 2018/7/23 14:07.
|
||||||
|
*/
|
||||||
|
class TimerQueue{
|
||||||
|
Object lock = new Object();
|
||||||
|
AbstractTask[] queue = new AbstractTask[128];
|
||||||
|
Set<String> names = new HashSet<>();
|
||||||
|
int size=0;
|
||||||
|
|
||||||
|
void put(AbstractTask task) {
|
||||||
|
remove(task.name);
|
||||||
|
synchronized (lock){
|
||||||
|
int inx = size;//目标坐标
|
||||||
|
while (inx > 0 && queue[inx-1].theTime() > task.theTime()){
|
||||||
|
inx--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queue.length == size+1)
|
||||||
|
queue = Arrays.copyOf(queue, size * 2);
|
||||||
|
|
||||||
|
for (int i = size+1; i > inx; i--) {
|
||||||
|
queue[i] = queue[i-1];
|
||||||
|
queue[i-1] = null;
|
||||||
|
}
|
||||||
|
queue[inx] = task;
|
||||||
|
|
||||||
|
size++;
|
||||||
|
names.add(task.name);
|
||||||
|
lock.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractTask take() throws InterruptedException {
|
||||||
|
synchronized (lock){
|
||||||
|
if (size == 0) lock.wait();
|
||||||
|
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
long nextTime = queue[0].theTime();
|
||||||
|
|
||||||
|
if (currentTime >= nextTime){
|
||||||
|
AbstractTask task = queue[0];
|
||||||
|
for (int i = 0; i < size;i++) {
|
||||||
|
queue[i] = queue[i+1];
|
||||||
|
}
|
||||||
|
queue[size-1] = null;
|
||||||
|
size--;
|
||||||
|
return task;
|
||||||
|
}else {
|
||||||
|
lock.wait(nextTime - currentTime);
|
||||||
|
return take();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractTask remove(String name){
|
||||||
|
synchronized (lock){
|
||||||
|
if(!names.contains(name)) return null;
|
||||||
|
|
||||||
|
AbstractTask take = null;
|
||||||
|
for (int i = 0; i < size-1; i++) {
|
||||||
|
if (name.equals(queue[i].name)){
|
||||||
|
take = queue[i];
|
||||||
|
while (i < size+1){
|
||||||
|
queue[i] = queue[i+1];
|
||||||
|
queue[i+1] = null;
|
||||||
|
}
|
||||||
|
names.remove(name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return take;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
src/main/java/com/lxyer/timer/scheduled/Scheduled.java
Normal file
21
src/main/java/com/lxyer/timer/scheduled/Scheduled.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.lxyer.timer.scheduled;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liangxianyou at 2018/8/5 17:35.
|
||||||
|
*/
|
||||||
|
public interface Scheduled {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下次执行时间
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LocalDateTime nextTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前执行时间
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LocalDateTime theTime();
|
||||||
|
}
|
35
src/main/java/com/lxyer/timer/scheduled/ScheduledCycle.java
Normal file
35
src/main/java/com/lxyer/timer/scheduled/ScheduledCycle.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package com.lxyer.timer.scheduled;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.time.temporal.TemporalUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liangxianyou at 2018/8/5 18:05.
|
||||||
|
*/
|
||||||
|
public class ScheduledCycle implements Scheduled {
|
||||||
|
|
||||||
|
private LocalDateTime theTime;
|
||||||
|
private long period;
|
||||||
|
private TemporalUnit unit = ChronoUnit.SECONDS;
|
||||||
|
|
||||||
|
public ScheduledCycle(LocalDateTime startTime, long period) {
|
||||||
|
this.theTime = startTime;
|
||||||
|
this.period = period;
|
||||||
|
}
|
||||||
|
public ScheduledCycle(LocalDateTime startTime, long period, TemporalUnit unit) {
|
||||||
|
this.theTime = startTime;
|
||||||
|
this.period = period;
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime nextTime() {
|
||||||
|
return theTime.plus(period, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime theTime() {
|
||||||
|
return theTime;
|
||||||
|
}
|
||||||
|
}
|
483
src/main/java/com/lxyer/timer/scheduled/ScheduledExpres.java
Normal file
483
src/main/java/com/lxyer/timer/scheduled/ScheduledExpres.java
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
package com.lxyer.timer.scheduled;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间解析器
|
||||||
|
* @author: liangxianyou
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public class ScheduledExpres implements Scheduled{
|
||||||
|
private int year;
|
||||||
|
private int month;
|
||||||
|
private int[] minutes;
|
||||||
|
private int[] hours;
|
||||||
|
private int[] days;
|
||||||
|
private int[] monthes;
|
||||||
|
private int[] weeks;
|
||||||
|
private String[] cfgArr;
|
||||||
|
|
||||||
|
private LocalDateTime theTime;
|
||||||
|
private int _y,_M,_d,_H,_m;
|
||||||
|
|
||||||
|
public ScheduledExpres(String cfg){
|
||||||
|
this.theTime = LocalDateTime.now();
|
||||||
|
initTheTime(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduledExpres(final LocalDateTime startTime, String cfg){
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
this.theTime = now.isAfter(startTime)? now : startTime;
|
||||||
|
initTheTime(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//寻找初始合法时间
|
||||||
|
public void initTheTime( String cfg) {
|
||||||
|
year = theTime.getYear();
|
||||||
|
month = theTime.getMonthValue();
|
||||||
|
cfgArr = cfg.split(" ");
|
||||||
|
|
||||||
|
setWeeks();
|
||||||
|
setMonthes();
|
||||||
|
setDays();
|
||||||
|
setHours();
|
||||||
|
setMinutes();
|
||||||
|
|
||||||
|
_y = theTime.getYear();
|
||||||
|
_M= theTime.getMonthValue();
|
||||||
|
_d= theTime.getDayOfMonth();
|
||||||
|
_H= theTime.getHour();
|
||||||
|
_m= theTime.getMinute();
|
||||||
|
|
||||||
|
String cmd = "";//y M d H m
|
||||||
|
if (days.length == 0) cmd = "M";
|
||||||
|
do {
|
||||||
|
carry(cmd);
|
||||||
|
int inx;
|
||||||
|
if ((inx = nowOk(monthes, _M)) < 0){
|
||||||
|
cmd = "y";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_M = monthes[inx];
|
||||||
|
|
||||||
|
if ((inx = nowOk(days, _d)) < 0){
|
||||||
|
cmd = "M";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_d = days[inx];
|
||||||
|
|
||||||
|
if ((inx = nowOk(hours, _H)) < 0){
|
||||||
|
cmd = "d";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_H = hours[inx];
|
||||||
|
|
||||||
|
if ((inx = nowOk(minutes, _m)) < 0){
|
||||||
|
cmd = "H";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_m = minutes[inx];
|
||||||
|
break;
|
||||||
|
}while (true);
|
||||||
|
|
||||||
|
theTime = LocalDateTime.of(_y, _M, _d, _H, _m);
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
while (theTime.isBefore(now)){
|
||||||
|
theTime = carry("m");
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(cfg);
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
System.out.println("init:"+ sdf.format(this.theTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下一次执行的时间
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public LocalDateTime nextTime(){
|
||||||
|
return carry("m");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime theTime() {
|
||||||
|
return theTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过发送指令进行进位
|
||||||
|
* @param cmd 进位指令
|
||||||
|
*/
|
||||||
|
private LocalDateTime carry(String cmd){
|
||||||
|
int inx;
|
||||||
|
while (!"".equals(cmd)){
|
||||||
|
switch (cmd) {
|
||||||
|
case "y":
|
||||||
|
_y = this.year = ++_y;
|
||||||
|
_M = this.month = monthes[0];
|
||||||
|
setDays();
|
||||||
|
if (days.length == 0){
|
||||||
|
cmd = "M";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_d = days[0];
|
||||||
|
_H = hours[0];
|
||||||
|
_m = minutes[0];
|
||||||
|
break;
|
||||||
|
case "M":
|
||||||
|
if (_M < monthes[0]){
|
||||||
|
_M = monthes[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inx = Arrays.binarySearch(monthes, _M);
|
||||||
|
if (inx < 0 || inx >= monthes.length-1) {
|
||||||
|
cmd = "y";
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
_M = this.month = monthes[inx+1];
|
||||||
|
setDays();
|
||||||
|
if (days.length == 0){
|
||||||
|
cmd = "M";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_d = days[0];
|
||||||
|
_H = hours[0];
|
||||||
|
_m = minutes[0];
|
||||||
|
break;
|
||||||
|
case "d":
|
||||||
|
if (_d < days[0]){
|
||||||
|
_d = days[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inx = Arrays.binarySearch(days, _d);
|
||||||
|
if (inx < 0 || inx >= days.length-1) {
|
||||||
|
cmd = "M";
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
_d = days[inx+1];
|
||||||
|
_H = hours[0];
|
||||||
|
_m = minutes[0];
|
||||||
|
break;
|
||||||
|
case "H":
|
||||||
|
if (_H < hours[0]){
|
||||||
|
_H = hours[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inx = Arrays.binarySearch(hours, _H);
|
||||||
|
if (inx < 0 || inx >= hours.length -1) {
|
||||||
|
cmd = "d";
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
_H = hours[inx+1];
|
||||||
|
_m = minutes[0];
|
||||||
|
break;
|
||||||
|
case "m":
|
||||||
|
if (_m < minutes[0]){
|
||||||
|
_m = minutes[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inx = Arrays.binarySearch(minutes, _m);
|
||||||
|
if (inx < 0 || inx >= minutes.length -1) {
|
||||||
|
cmd = "H";
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
_m = minutes[inx+1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cmd = "";
|
||||||
|
}
|
||||||
|
return LocalDateTime.of(_y, _M, _d, _H, _m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到初始合法时间的索引
|
||||||
|
* @param arr 合法时间序列
|
||||||
|
* @param n 初始选中值
|
||||||
|
* @return 合法时间的索引
|
||||||
|
*/
|
||||||
|
private int nowOk(int[] arr, int n){
|
||||||
|
if (arr == null || arr.length == 0) return -1;
|
||||||
|
if (arr[0] > n)
|
||||||
|
return 0;
|
||||||
|
if (arr[arr.length-1] < n)
|
||||||
|
return 0;
|
||||||
|
if (arr[arr.length-1] == n)
|
||||||
|
return arr.length-1;
|
||||||
|
|
||||||
|
for (int i = 0; i < arr.length-1; i++) {
|
||||||
|
if ((arr[i] < n && arr[i+1] > n) || arr[i] == n){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 以下为 初始化合法时间 weeks,monthes,days,hour,minutes 序列 */
|
||||||
|
private void setMinutes(){
|
||||||
|
String cfg = cfgArr[0];
|
||||||
|
if ("*".equals(cfg)){//*
|
||||||
|
minutes = new int[60];
|
||||||
|
for (int i = 0; i < 60; i++) {
|
||||||
|
minutes[i] = i;
|
||||||
|
}
|
||||||
|
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
||||||
|
minutes = new int[1];
|
||||||
|
minutes[0] = Integer.parseInt(cfg);
|
||||||
|
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
minutes = new int[60/p];
|
||||||
|
for (int i = 0; i < minutes.length; i++) {
|
||||||
|
minutes[i] = i*p;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
||||||
|
String[] strings = cfg.split(",");
|
||||||
|
minutes = new int[strings.length];
|
||||||
|
for (int i = 0; i < strings.length; i++) {
|
||||||
|
minutes[i] = Integer.parseInt(strings[i]);
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
||||||
|
String[] split = cfg.split("-");
|
||||||
|
int s = Integer.parseInt(split[0]);
|
||||||
|
int e = Integer.parseInt(split[1]);
|
||||||
|
|
||||||
|
minutes = new int[e-s +1];
|
||||||
|
for (int i = 0; i < minutes.length; i++) {
|
||||||
|
minutes[i] = s+i;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
String[] str2Arr = strArr[0].split("-");
|
||||||
|
int s = Integer.parseInt(str2Arr[0]);
|
||||||
|
int e = Integer.parseInt(str2Arr[1]);
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
|
||||||
|
minutes = new int[(e-s)/p];
|
||||||
|
for (int i = 0; i < minutes.length; i++) {
|
||||||
|
minutes[i] = s + i*p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setHours(){
|
||||||
|
String cfg = cfgArr[1];
|
||||||
|
if ("*".equals(cfg)){//*
|
||||||
|
hours = new int[24];
|
||||||
|
for (int i = 0; i < hours.length; i++) {
|
||||||
|
hours[i] = i;
|
||||||
|
}
|
||||||
|
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
||||||
|
hours = new int[1];
|
||||||
|
hours[0] = Integer.parseInt(cfg);
|
||||||
|
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
hours = new int[24/p];
|
||||||
|
for (int i = 0; i < hours.length; i++) {
|
||||||
|
hours[i] = i*p;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
||||||
|
String[] strArr = cfg.split(",");
|
||||||
|
hours = new int[strArr.length];
|
||||||
|
for (int i = 0; i < strArr.length; i++) {
|
||||||
|
hours[i] = Integer.parseInt(strArr[i]);
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
||||||
|
String[] split = cfg.split("-");
|
||||||
|
int s = Integer.parseInt(split[0]);
|
||||||
|
int e = Integer.parseInt(split[1]);
|
||||||
|
|
||||||
|
hours = new int[e-s +1];
|
||||||
|
for (int i = 0; i < hours.length; i++) {
|
||||||
|
hours[i] = s+i;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
String[] str2Arr = strArr[0].split("-");
|
||||||
|
int s = Integer.parseInt(str2Arr[0]);
|
||||||
|
int e = Integer.parseInt(str2Arr[1]);
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
|
||||||
|
hours = new int[(e-s)/p];
|
||||||
|
for (int i = 0; i < hours.length; i++) {
|
||||||
|
hours[i] = s + i*p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setWeeks(){
|
||||||
|
String cfg = cfgArr[4];
|
||||||
|
if ("*".equals(cfg)){//*
|
||||||
|
weeks = new int[7];
|
||||||
|
for (int i = 0; i < weeks.length; i++) {
|
||||||
|
weeks[i] = i+1;
|
||||||
|
}
|
||||||
|
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
||||||
|
weeks = new int[1];
|
||||||
|
weeks[0] = Integer.parseInt(cfg);
|
||||||
|
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
weeks = new int[7/p];
|
||||||
|
for (int i = 0; i < weeks.length; i++) {
|
||||||
|
weeks[i] = i*p;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
||||||
|
String[] strArr = cfg.split(",");
|
||||||
|
weeks = new int[strArr.length];
|
||||||
|
for (int i = 0; i < strArr.length; i++) {
|
||||||
|
weeks[i] = Integer.parseInt(strArr[i]);
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
||||||
|
String[] split = cfg.split("-");
|
||||||
|
int s = Integer.parseInt(split[0]);
|
||||||
|
int e = Integer.parseInt(split[1]);
|
||||||
|
|
||||||
|
weeks = new int[e-s +1];
|
||||||
|
for (int i = 0; i < weeks.length; i++) {
|
||||||
|
weeks[i] = s+i;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
String[] str2Arr = strArr[0].split("-");
|
||||||
|
int s = Integer.parseInt(str2Arr[0]);
|
||||||
|
int e = Integer.parseInt(str2Arr[1]);
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
|
||||||
|
weeks = new int[(e-s)/p];
|
||||||
|
for (int i = 0; i < weeks.length; i++) {
|
||||||
|
weeks[i] = s + i*p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMonthes(){
|
||||||
|
String cfg = cfgArr[3];
|
||||||
|
if ("*".equals(cfg)){//*
|
||||||
|
monthes = new int[12];
|
||||||
|
for (int i = 0; i < monthes.length; i++) {
|
||||||
|
monthes[i] = i+1;
|
||||||
|
}
|
||||||
|
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
||||||
|
monthes = new int[1];
|
||||||
|
monthes[0] = Integer.parseInt(cfg);
|
||||||
|
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
monthes = new int[12/p];
|
||||||
|
for (int i = 0; i < monthes.length; i++) {
|
||||||
|
monthes[i] = i*p;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
||||||
|
String[] strArr = cfg.split(",");
|
||||||
|
monthes = new int[strArr.length];
|
||||||
|
for (int i = 0; i < strArr.length; i++) {
|
||||||
|
monthes[i] = Integer.parseInt(strArr[i]);
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
||||||
|
String[] split = cfg.split("-");
|
||||||
|
int s = Integer.parseInt(split[0]);
|
||||||
|
int e = Integer.parseInt(split[1]);
|
||||||
|
|
||||||
|
monthes = new int[e-s +1];
|
||||||
|
for (int i = 0; i < monthes.length; i++) {
|
||||||
|
monthes[i] = s+i;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
String[] str2Arr = strArr[0].split("-");
|
||||||
|
int s = Integer.parseInt(str2Arr[0]);
|
||||||
|
int e = Integer.parseInt(str2Arr[1]);
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
|
||||||
|
monthes = new int[(e-s)/p];
|
||||||
|
for (int i = 0; i < monthes.length; i++) {
|
||||||
|
monthes[i] = s + i*p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDays(){
|
||||||
|
String cfg = cfgArr[2];
|
||||||
|
//当前月份总天数,
|
||||||
|
LocalDate firstDay = LocalDate.of(year, month, 1);
|
||||||
|
int lengthOfMonth = firstDay.lengthOfMonth();
|
||||||
|
|
||||||
|
if ("*".equals(cfg)){//*
|
||||||
|
days = new int[lengthOfMonth];
|
||||||
|
for (int i = 0; i < days.length; i++) {
|
||||||
|
days[i] = i+1;
|
||||||
|
}
|
||||||
|
} else if (cfg.matches("^[0-5]??[0-9]??$")){//n
|
||||||
|
days = new int[1];
|
||||||
|
days[0] = Integer.parseInt(cfg);
|
||||||
|
}else if (cfg.matches("^[*]/[0-9]+$")){// */5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
days = new int[lengthOfMonth/p];
|
||||||
|
for (int i = 0; i < days.length; i++) {
|
||||||
|
days[i] = i*p;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^([0-5]??[0-9]??,)+([0-5]??[0-9]??)?$")){//1,3
|
||||||
|
String[] strArr = cfg.split(",");
|
||||||
|
days = new int[strArr.length];
|
||||||
|
for (int i = 0; i < strArr.length; i++) {
|
||||||
|
days[i] = Integer.parseInt(strArr[i]);
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??$")){//1-3
|
||||||
|
String[] split = cfg.split("-");
|
||||||
|
int s = Integer.parseInt(split[0]);
|
||||||
|
int e = Integer.parseInt(split[1]);
|
||||||
|
|
||||||
|
days = new int[e-s +1];
|
||||||
|
for (int i = 0; i < days.length; i++) {
|
||||||
|
days[i] = s+i;
|
||||||
|
}
|
||||||
|
}else if (cfg.matches("^[0-5]??[0-9]??\\-[0-5]??[0-9]??/[0-5]??[0-9]??$")){//3-18/5
|
||||||
|
String[] strArr = cfg.split("/");
|
||||||
|
String[] str2Arr = strArr[0].split("-");
|
||||||
|
int s = Integer.parseInt(str2Arr[0]);
|
||||||
|
int e = Integer.parseInt(str2Arr[1]);
|
||||||
|
int p = Integer.parseInt(strArr[1]);
|
||||||
|
|
||||||
|
days = new int[(e-s)/p];
|
||||||
|
for (int i = 0; i < days.length; i++) {
|
||||||
|
days[i] = s + i*p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstWeek = firstDay.getDayOfWeek().getValue();
|
||||||
|
List<Integer> allDay = new ArrayList<>();
|
||||||
|
for (int i = 0; i < days.length; i++) {
|
||||||
|
//int week = 7 - Math.abs(i - firstWeek) % 7;//当前星期X
|
||||||
|
int week;
|
||||||
|
int d = days[i];
|
||||||
|
if (d + firstWeek <= 8){
|
||||||
|
week = firstWeek + d - 1;
|
||||||
|
}else {
|
||||||
|
week = (d - (8-firstWeek))%7;
|
||||||
|
if (week == 0) week = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
//System.out.printf("M:%s,d:%s,w:%s%n", month, d, week);
|
||||||
|
|
||||||
|
if (Arrays.binarySearch(weeks, week) > -1){
|
||||||
|
allDay.add(d);//加入日期
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
days = new int[allDay.size()];
|
||||||
|
for (int i = 0; i < allDay.size(); i++) {
|
||||||
|
days[i] = allDay.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
src/test/java/com/lxyer/timer/TaskImpl.java
Normal file
34
src/test/java/com/lxyer/timer/TaskImpl.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package com.lxyer.timer;
|
||||||
|
|
||||||
|
import com.lxyer.timer.scheduled.Scheduled;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liangxianyou
|
||||||
|
* @createtime: 2018/8/5 20:39.
|
||||||
|
*/
|
||||||
|
public class TaskImpl extends AbstractTask {
|
||||||
|
public TaskImpl(String name, Scheduled scheduled) {
|
||||||
|
super(name, scheduled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.out.println("----");
|
||||||
|
System.out.println(new SimpleDateFormat("0: yyyy-MM-dd HH:mm:ss").format(theTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("1: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("2: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("3: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("4: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("5: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("6: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("7: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("8: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("9: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("10: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("11: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("12: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
System.out.println(new SimpleDateFormat("13: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.lxyer.timer;
|
package com.lxyer.timer;
|
||||||
|
|
||||||
|
import com.lxyer.timer.scheduled.ScheduledExpres;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@ -21,7 +22,7 @@ public class TimerTest {
|
|||||||
public void t2(){
|
public void t2(){
|
||||||
TimerExecutor timerExecutor = new TimerExecutor(1);
|
TimerExecutor timerExecutor = new TimerExecutor(1);
|
||||||
|
|
||||||
timerExecutor.add(new Task("a1", "1-40 * * * *") {
|
timerExecutor.add(new TaskImpl("a1", new ScheduledExpres(LocalDateTime.now(), "1-40 * * * *")) {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ThreadLocal<SimpleDateFormat> local = new ThreadLocal<>();
|
ThreadLocal<SimpleDateFormat> local = new ThreadLocal<>();
|
||||||
@ -132,55 +133,20 @@ public class TimerTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* LocalDateTime的一些api测试
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void t5(){
|
|
||||||
//Minute * 1,3 1-3 */5 3-15/5
|
|
||||||
String cfg = "* * * * *";
|
|
||||||
LocalDateTime time = LocalDateTime.of(2018, 7, 18, 11, 11);
|
|
||||||
|
|
||||||
int minute = time.getMinute();
|
|
||||||
int hour = time.getHour();
|
|
||||||
int day = time.getDayOfMonth();
|
|
||||||
int month = time.getMonthValue();
|
|
||||||
int week = time.getDayOfWeek().getValue();
|
|
||||||
|
|
||||||
//checkCfg
|
|
||||||
//if (month)
|
|
||||||
System.out.println(week);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试配置的表达式
|
* 测试配置的表达式
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void t6(){
|
public void t6(){
|
||||||
//分 时 日 月 周
|
//分 时 日 月 周
|
||||||
|
TimerExecutor executor = new TimerExecutor(10);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
08 18 * 7,8 4
|
08 18 * 7,8 4
|
||||||
|
"task1", "1 22-23 * * 7"
|
||||||
*/
|
*/
|
||||||
new Task("task1", "1 22-23 * * 7") {
|
Task task = new TaskImpl("task1", new ScheduledExpres("1 22-23 * * 7"));
|
||||||
@Override
|
task.run();
|
||||||
public void run() {
|
|
||||||
System.out.println("----");
|
|
||||||
System.out.println(new SimpleDateFormat("0: yyyy-MM-dd HH:mm:ss").format(nextTime));
|
|
||||||
System.out.println(new SimpleDateFormat("1: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("2: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("3: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("4: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("5: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("6: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("7: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("8: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("9: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("10: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("11: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("12: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
System.out.println(new SimpleDateFormat("13: yyyy-MM-dd HH:mm:ss").format(nextTime()));
|
|
||||||
}
|
|
||||||
}.run();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user