- 代码比较长,300+行,核心逻辑倒不复杂
- 参考了java time库的LocalDateTime源码设计
- 还有一个有趣的数学函数是直接根据年、月、日求解出星期几
3 201711170032 201711222352
0 7 * * 1,3-5 get_up
30 23 * * Sat,Sun go_to_bed
15 12,18 * * * have_dinner
201711170700 get_up
201711171215 have_dinner
201711171815 have_dinner
201711181215 have_dinner
201711181815 have_dinner
201711182330 go_to_bed
201711191215 have_dinner
201711191815 have_dinner
201711192330 go_to_bed
201711200700 get_up
201711201215 have_dinner
201711201815 have_dinner
201711211215 have_dinner
201711211815 have_dinner
201711220700 get_up
201711221215 have_dinner
201711221815 have_dinner
import java.io.*;
import java.util.*;
class Crontab
{
private static Map<String, Integer> map = new HashMap<String, Integer>() {
{
put("jan", 1);
put("feb", 2);
put("mar", 3);
put("apr", 4);
put("may", 5);
put("jun", 6);
put("jul", 7);
put("aug", 8);
put("sep", 9);
put("oct", 10);
put("nov", 11);
put("dec", 12);
put("sun", 0);
put("mon", 1);
put("tue", 2);
put("wed", 3);
put("thu", 4);
put("fri", 5);
put("sat", 6);
}
};
private Set<Integer> min = new HashSet<>();
private Set<Integer> h = new HashSet<>();
private Set<Integer> dm = new HashSet<>();
private Set<Integer> mon = new HashSet<>();
private Set<Integer> dw = new HashSet<>();
private String command;
private void dealMinusSign(Set<Integer> set, String str)
{
int idx = str.indexOf('-');
String start = str.substring(0, idx);
String end = str.substring(idx + 1);
int i = map.containsKey(start) ? map.get(start) : Integer.parseInt(start);
int j = map.containsKey(end) ? map.get(end) : Integer.parseInt(end);
while (i <= j) {
set.add(i++);
}
}
private void initial(Set<Integer> set, String str)
{
if (str.contains(",")) {
String[] arr_set = str.split(",");
for (String s : arr_set) {
if (s.contains("-")) {
dealMinusSign(set, s);
}
else {
set.add(map.containsKey(s) ? map.get(s) : Integer.parseInt(s));
}
}
}
else if (str.contains("-")) {
dealMinusSign(set, str);
}
else {
set.add(map.containsKey(str) ? map.get(str) : Integer.parseInt(str));
}
}
public Crontab(String config)
{
String[] arr = config.split(" ");
String minutes = arr[0];
String hours = arr[1];
String dayOfMonth = arr[2];
String month = arr[3].toLowerCase();
String dayOfWeek = arr[4].toLowerCase();
this.command = arr[5];
if (minutes.equals("*")) {
for (int i = 0; i < 60; i++) {
min.add(i);
}
}
else {
initial(min, minutes);
}
if (hours.equals("*")) {
for (int i = 0; i < 24; i++) {
h.add(i);
}
}
else {
initial(h, hours);
}
if (dayOfMonth.equals("*")) {
for (int i = 1; i < 32; i++) {
dm.add(i);
}
}
else {
initial(dm, dayOfMonth);
}
if (month.equals("*")) {
for (int i = 1; i < 13; i++) {
mon.add(i);
}
}
else {
initial(mon, month);
}
if (dayOfWeek.equals("*")) {
for (int i = 0; i < 7; i++) {
dw.add(i);
}
}
else {
initial(dw, dayOfWeek);
}
}
public boolean fitTheTime(MyTime currentTime)
{
if (!dw.contains(currentTime.getDayOfWeek())) {
return false;
}
if (!min.contains(currentTime.getMinute())) {
return false;
}
if (!h.contains(currentTime.getHour())) {
return false;
}
if (!dm.contains(currentTime.getDayOfMonth())) {
return false;
}
if (!mon.contains(currentTime.getMonth())) {
return false;
}
return true;
}
public String getCommand() {
return command;
}
}
class MyTime {
private int year;
private int month;
private int dayOfMonth;
private int hour;
private int minute;
private int dayOfWeek;
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDayOfMonth() {
return dayOfMonth;
}
public int getHour() {
return hour;
}
public int getMinute() {
return minute;
}
public int getDayOfWeek() {
return dayOfWeek;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + year;
result = prime * result + month;
result = prime * result + dayOfMonth;
result = prime * result + hour;
result = prime * result + minute;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyTime other = (MyTime) obj;
if (year != other.year)
return false;
if (month != other.month)
return false;
if (dayOfMonth != other.dayOfMonth)
return false;
if (hour != other.hour)
return false;
if (minute != other.minute)
return false;
return true;
}
public MyTime(String str) {
this.year = Integer.parseInt(str.substring(0, 4));
this.month = Integer.parseInt(str.substring(4, 6));
this.dayOfMonth = Integer.parseInt(str.substring(6, 8));
this.hour = Integer.parseInt(str.substring(8, 10));
this.minute = Integer.parseInt(str.substring(10, 12));
this.dayOfWeek = initialDayOfWeek();
}
private int initialDayOfWeek() {
int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
int y = year;
if (month < 3) {
y--;
}
return (y + y/4 - y/100 + y/400 + t[month - 1] + dayOfMonth) % 7;
}
@Override
public String toString() {
return "" + year + String.format("%02d%02d%02d%02d", month, dayOfMonth, hour, minute);
}
public void plusMinute() {
minute++;
if (minute == 60) {
minute = 0;
hour++;
if (hour == 24) {
hour = 0;
dayOfMonth++;
dayOfWeek = (dayOfWeek + 1) % 7;
switch (month)
{
case 2:
if (isLeapYear() && dayOfMonth == 30) {
dayOfMonth = 1;
month++;
}
else if (!isLeapYear() && dayOfMonth == 29) {
dayOfMonth = 1;
month++;
}
break;
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (dayOfMonth == 32) {
dayOfMonth = 1;
month++;
}
break;
case 4:
case 6:
case 9:
case 11:
if (dayOfMonth == 31) {
dayOfMonth = 1;
month++;
}
break;
}
if (month == 13) {
month = 1;
year++;
}
}
}
}
private boolean isLeapYear() {
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
StringTokenizer st = new StringTokenizer(f.readLine());
int n = Integer.parseInt(st.nextToken());
MyTime currentTime = new MyTime(st.nextToken());
MyTime endTime = new MyTime(st.nextToken());
Crontab[] crontabs = new Crontab[n];
for (int i = 0; i < n; i++)
{
String config = f.readLine();
crontabs[i] = new Crontab(config);
}
while (!currentTime.equals(endTime)) {
for (int i = 0; i < n; i++) {
if (crontabs[i].fitTheTime(currentTime)) {
out.println(currentTime + " " + crontabs[i].getCommand());
}
}
currentTime.plusMinute();
}
out.close();
f.close();
}
}
|