提交 6b4d044a 编写于 作者: B Boris

JENKINS-9283 - Allow timezone definition in scheduler

上级 e44e1544
......@@ -27,6 +27,7 @@ import antlr.ANTLRException;
import java.io.StringReader;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.regex.Matcher;
......@@ -58,6 +59,11 @@ public final class CronTab {
*/
private String spec;
/**
* Optional timezone string for calendar
*/
private @CheckForNull String specTimezone;
public CronTab(String format) throws ANTLRException {
this(format,null);
}
......@@ -81,15 +87,29 @@ public final class CronTab {
* of not spreading it out at all.
*/
public CronTab(String format, int line, Hash hash) throws ANTLRException {
set(format, line, hash);
this(format, line, hash, null);
}
/**
* @param timezone
* Used to schedule cron in a differnt timezone. Null to use the default system
* timezone
*/
public CronTab(String format, int line, Hash hash, String timezone) throws ANTLRException {
set(format, line, hash, timezone);
}
private void set(String format, int line, Hash hash) throws ANTLRException {
set(format, line, hash, null);
}
private void set(String format, int line, Hash hash, String timezone) throws ANTLRException {
CrontabLexer lexer = new CrontabLexer(new StringReader(format));
lexer.setLine(line);
CrontabParser parser = new CrontabParser(lexer);
parser.setHash(hash);
spec = format;
specTimezone = timezone;
parser.startRule(this);
if((dayOfWeek&(1<<7))!=0) {
......@@ -103,15 +123,24 @@ public final class CronTab {
* Returns true if the given calendar matches
*/
boolean check(Calendar cal) {
if(!checkBits(bits[0],cal.get(MINUTE)))
Calendar checkCal = cal;
if(specTimezone != null && !specTimezone.isEmpty()) {
Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone(specTimezone));
tzCal.setTime(cal.getTime());
checkCal = tzCal;
}
if(!checkBits(bits[0],checkCal.get(MINUTE)))
return false;
if(!checkBits(bits[1],cal.get(HOUR_OF_DAY)))
if(!checkBits(bits[1],checkCal.get(HOUR_OF_DAY)))
return false;
if(!checkBits(bits[2],cal.get(DAY_OF_MONTH)))
if(!checkBits(bits[2],checkCal.get(DAY_OF_MONTH)))
return false;
if(!checkBits(bits[3],cal.get(MONTH)+1))
if(!checkBits(bits[3],checkCal.get(MONTH)+1))
return false;
if(!checkBits(dayOfWeek,cal.get(Calendar.DAY_OF_WEEK)-1))
if(!checkBits(dayOfWeek,checkCal.get(Calendar.DAY_OF_WEEK)-1))
return false;
return true;
......
......@@ -25,12 +25,16 @@ package hudson.scheduler;
import antlr.ANTLRException;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Collection;
import java.util.Vector;
import javax.annotation.CheckForNull;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* {@link CronTab} list (logically OR-ed).
*
......@@ -71,6 +75,20 @@ public final class CronTabList {
return null;
}
/**
* Checks if given timezone string is supported by TimeZone and returns
* the same string if valid, null otherwise
*/
public static @CheckForNull String getValidTimezone(String timezone) {
String[] validIDs = TimeZone.getAvailableIDs();
for (String str : validIDs) {
if (str != null && str.equals(timezone)) {
return timezone;
}
}
return null;
}
public static CronTabList create(String format) throws ANTLRException {
return create(format,null);
}
......@@ -78,17 +96,31 @@ public final class CronTabList {
public static CronTabList create(String format, Hash hash) throws ANTLRException {
Vector<CronTab> r = new Vector<CronTab>();
int lineNumber = 0;
String timezone = null;
for (String line : format.split("\\r?\\n")) {
lineNumber++;
line = line.trim();
if(lineNumber == 1 && line.startsWith("TZ=")) {
timezone = getValidTimezone(line.replace("TZ=",""));
if(timezone != null) {
LOGGER.log(Level.CONFIG, "cron with timezone {0}", timezone);
} else {
LOGGER.log(Level.CONFIG, "invalid timezone {0}", line);
}
continue;
}
if(line.length()==0 || line.startsWith("#"))
continue; // ignorable line
try {
r.add(new CronTab(line,lineNumber,hash));
r.add(new CronTab(line,lineNumber,hash,timezone));
} catch (ANTLRException e) {
throw new ANTLRException(Messages.CronTabList_InvalidInput(line,e.toString()),e);
}
}
return new CronTabList(r);
}
......@@ -115,5 +147,6 @@ public final class CronTabList {
}
return nearest;
}
private static final Logger LOGGER = Logger.getLogger(CronTabList.class.getName());
}
......@@ -27,6 +27,7 @@ import antlr.ANTLRException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.GregorianCalendar;
import java.util.Locale;
......@@ -301,4 +302,17 @@ public class CronTabTest {
// ok
}
}
@Issue("JENKINS-9283")
@Test public void testTimezone() throws Exception {
CronTabList tabs = CronTabList.create("TZ=Australia/Sydney\nH * * * *\nH * * * *", Hash.from("seed"));
List<Integer> times = new ArrayList<Integer>();
for (int i = 0; i < 60; i++) {
if (tabs.check(new GregorianCalendar(2013, 3, 3, 11, i, 0))) {
times.add(i);
}
}
assertEquals("[35, 56]", times.toString());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册