package org.rrd4j.core.timespec; import org.rrd4j.core.Util; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; /** * Simple class to represent time obtained by parsing at-style date specification (described * in detail on the rrdfetch man page. See javadoc for {@link org.rrd4j.core.timespec.TimeParser} * for more information. * */ public class TimeSpec { static final int TYPE_ABSOLUTE = 0; static final int TYPE_START = 1; static final int TYPE_END = 2; int type = TYPE_ABSOLUTE; int year, month, day, hour, min, sec; int wday; int dyear, dmonth, dday, dhour, dmin, dsec; String dateString; TimeSpec context; TimeSpec(String dateString) { this.dateString = dateString; } void localtime(long timestamp) { GregorianCalendar date = new GregorianCalendar(); date.setTime(new Date(timestamp * 1000L)); year = date.get(Calendar.YEAR) - 1900; month = date.get(Calendar.MONTH); day = date.get(Calendar.DAY_OF_MONTH); hour = date.get(Calendar.HOUR_OF_DAY); min = date.get(Calendar.MINUTE); sec = date.get(Calendar.SECOND); wday = date.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY; } GregorianCalendar getTime() { GregorianCalendar gc; // absolute time, this is easy if (type == TYPE_ABSOLUTE) { gc = new GregorianCalendar(year + 1900, month, day, hour, min, sec); } // relative time, we need a context to evaluate it else if (context != null && context.type == TYPE_ABSOLUTE) { gc = context.getTime(); } // how would I guess what time it was? else { throw new IllegalStateException("Relative times like '" + dateString + "' require proper absolute context to be evaluated"); } gc.add(Calendar.YEAR, dyear); gc.add(Calendar.MONTH, dmonth); gc.add(Calendar.DAY_OF_MONTH, dday); gc.add(Calendar.HOUR_OF_DAY, dhour); gc.add(Calendar.MINUTE, dmin); gc.add(Calendar.SECOND, dsec); return gc; } /** * <p>Returns the corresponding timestamp (seconds since Epoch). Example:</p> * <pre> * TimeParser p = new TimeParser("now-1day"); * TimeSpec ts = p.parse(); * System.out.println("Timestamp was: " + ts.getTimestamp(); * </pre> * * @return Timestamp (in seconds, no milliseconds) */ public long getTimestamp() { return Util.getTimestamp(getTime()); } String dump() { return (type == TYPE_ABSOLUTE ? "ABSTIME" : type == TYPE_START ? "START" : "END") + ": " + year + "/" + month + "/" + day + "/" + hour + "/" + min + "/" + sec + " (" + dyear + "/" + dmonth + "/" + dday + "/" + dhour + "/" + dmin + "/" + dsec + ")"; } /** * <p>Use this static method to resolve relative time references and obtain the corresponding * Calendar objects. Example:</p> * <pre> * TimeParser pStart = new TimeParser("now-1month"); // starting time * TimeParser pEnd = new TimeParser("start+1week"); // ending time * TimeSpec specStart = pStart.parse(); * TimeSpec specEnd = pEnd.parse(); * GregorianCalendar[] gc = TimeSpec.getTimes(specStart, specEnd); * </pre> * * @param spec1 Starting time specification * @param spec2 Ending time specification * @return Two element array containing Calendar objects */ public static Calendar[] getTimes(TimeSpec spec1, TimeSpec spec2) { if (spec1.type == TYPE_START || spec2.type == TYPE_END) { throw new IllegalArgumentException("Recursive time specifications not allowed"); } spec1.context = spec2; spec2.context = spec1; return new Calendar[]{ spec1.getTime(), spec2.getTime() }; } /** * <p>Use this static method to resolve relative time references and obtain the corresponding * timestamps (seconds since epoch). Example:</p> * <pre> * TimeParser pStart = new TimeParser("now-1month"); // starting time * TimeParser pEnd = new TimeParser("start+1week"); // ending time * TimeSpec specStart = pStart.parse(); * TimeSpec specEnd = pEnd.parse(); * long[] ts = TimeSpec.getTimestamps(specStart, specEnd); * </pre> * * @param spec1 Starting time specification * @param spec2 Ending time specification * @return array containing two timestamps (in seconds since epoch) */ public static long[] getTimestamps(TimeSpec spec1, TimeSpec spec2) { Calendar[] gcs = getTimes(spec1, spec2); return new long[] { Util.getTimestamp(gcs[0]), Util.getTimestamp(gcs[1]) }; } }