From: Tarus B. <ta...@us...> - 2006-12-21 18:03:16
|
Update of /cvsroot/jrobin/src/org/jrobin/core/timespec In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv9082/org/jrobin/core/timespec Modified Files: Epoch.java TimeParser.java TimeScanner.java TimeSpec.java TimeToken.java Log Message: Adding the new 1.5.4 code Index: TimeSpec.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/timespec/TimeSpec.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TimeSpec.java 17 Feb 2005 10:43:13 -0000 1.1 --- TimeSpec.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,164 **** ! /* ============================================================ ! * JRobin : Pure java implementation of RRDTool's functionality ! * ============================================================ ! * ! * Project Info: http://www.jrobin.org ! * Project Lead: Sasa Markovic (sa...@jr...); ! * ! * (C) Copyright 2003, by Sasa Markovic. ! * ! * Developers: Sasa Markovic (sa...@jr...) ! * Arne Vandamme (cob...@jr...) ! * ! * This library is free software; you can redistribute it and/or modify it under the terms ! * of the GNU Lesser General Public License as published by the Free Software Foundation; ! * either version 2.1 of the License, or (at your option) any later version. ! * ! * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ! * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! * See the GNU Lesser General Public License for more details. ! * ! * You should have received a copy of the GNU Lesser General Public License along with this ! * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, ! * Boston, MA 02111-1307, USA. ! */ ! ! package org.jrobin.core.timespec; ! ! import org.jrobin.core.RrdException; ! import org.jrobin.core.Util; ! ! import java.util.GregorianCalendar; ! import java.util.Date; ! import java.util.Calendar; ! ! /** ! * Simple class to represent time obtained by parsing at-style date specification (described ! * in detail on the rrdfetch man page. See javadoc {@link org.jrobin.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() throws RrdException { ! GregorianCalendar gc; ! // absoulte 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 RrdException("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; ! } ! ! /** ! * 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) ! * @throws RrdException Thrown if this TimeSpec object does not represent absolute time. ! */ ! public long getTimestamp() throws RrdException { ! 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 + ")"; ! } ! ! /** ! * Use this static method to resolve relative time references and obtain the corresponding ! * GregorianCalendar 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 ! * @throws RrdException Thrown if relative time references cannot be resolved ! */ ! public static GregorianCalendar[] getTimes(TimeSpec spec1, TimeSpec spec2) throws RrdException { ! if(spec1.type == TYPE_START || spec2.type == TYPE_END) { ! throw new RrdException("Recursive time specifications not allowed"); ! } ! spec1.context = spec2; ! spec2.context = spec1; ! return new GregorianCalendar[] { ! spec1.getTime(), ! spec2.getTime() ! }; ! } ! ! /** ! * 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 ! * @throws RrdException Thrown if relative time references cannot be resolved ! */ ! public static long[] getTimestamps(TimeSpec spec1, TimeSpec spec2) throws RrdException { ! GregorianCalendar[] gcs = getTimes(spec1, spec2); ! return new long[] { ! Util.getTimestamp(gcs[0]), Util.getTimestamp(gcs[1]) ! }; ! } ! } ! --- 1,168 ---- ! /* ============================================================ ! * JRobin : Pure java implementation of RRDTool's functionality ! * ============================================================ ! * ! * Project Info: http://www.jrobin.org ! * Project Lead: Sasa Markovic (sa...@jr...); ! * ! * (C) Copyright 2003-2005, by Sasa Markovic. ! * ! * Developers: Sasa Markovic (sa...@jr...) ! * ! * ! * This library is free software; you can redistribute it and/or modify it under the terms ! * of the GNU Lesser General Public License as published by the Free Software Foundation; ! * either version 2.1 of the License, or (at your option) any later version. ! * ! * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ! * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! * See the GNU Lesser General Public License for more details. ! * ! * You should have received a copy of the GNU Lesser General Public License along with this ! * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, ! * Boston, MA 02111-1307, USA. ! */ ! ! package org.jrobin.core.timespec; ! ! import org.jrobin.core.RrdException; ! import org.jrobin.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.jrobin.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() throws RrdException { ! GregorianCalendar gc; ! // absoulte 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 RrdException("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; ! } ! ! /** ! * 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) ! * @throws RrdException Thrown if this TimeSpec object does not represent absolute time. ! */ ! public long getTimestamp() throws RrdException { ! 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 + ")"; ! } ! ! /** ! * 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 ! * @throws RrdException Thrown if relative time references cannot be resolved ! */ ! public static Calendar[] getTimes(TimeSpec spec1, TimeSpec spec2) throws RrdException { ! if (spec1.type == TYPE_START || spec2.type == TYPE_END) { ! throw new RrdException("Recursive time specifications not allowed"); ! } ! spec1.context = spec2; ! spec2.context = spec1; ! return new Calendar[] { ! spec1.getTime(), ! spec2.getTime() ! }; ! } ! ! /** ! * 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) ! * @throws RrdException Thrown if relative time references cannot be resolved ! */ ! public static long[] getTimestamps(TimeSpec spec1, TimeSpec spec2) throws RrdException { ! Calendar[] gcs = getTimes(spec1, spec2); ! return new long[] { ! Util.getTimestamp(gcs[0]), Util.getTimestamp(gcs[1]) ! }; ! } ! } ! Index: TimeParser.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/timespec/TimeParser.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TimeParser.java 17 Feb 2005 10:43:13 -0000 1.1 --- TimeParser.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,432 **** ! /* ============================================================ ! * JRobin : Pure java implementation of RRDTool's functionality ! * ============================================================ ! * ! * Project Info: http://www.jrobin.org ! * Project Lead: Sasa Markovic (sa...@jr...); ! * ! * (C) Copyright 2003, by Sasa Markovic. ! * ! * Developers: Sasa Markovic (sa...@jr...) ! * Arne Vandamme (cob...@jr...) ! * ! * This library is free software; you can redistribute it and/or modify it under the terms ! * of the GNU Lesser General Public License as published by the Free Software Foundation; ! * either version 2.1 of the License, or (at your option) any later version. ! * ! * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ! * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! * See the GNU Lesser General Public License for more details. ! * ! * You should have received a copy of the GNU Lesser General Public License along with this ! * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, ! * Boston, MA 02111-1307, USA. ! */ ! ! /* ! * Java port of Tobi's original parsetime.c routine ! */ ! package org.jrobin.core.timespec; ! ! import org.jrobin.core.RrdException; ! import org.jrobin.core.Util; ! ! /** ! * Class which parses at-style time specification (describided in detail on the rrdfetch man page), ! * used in all RRDTool commands. This code is in most parts just a java port of Tobi's parsetime.c ! * code. ! */ ! public class TimeParser { ! private static final int PREVIOUS_OP = -1; ! ! TimeToken token; ! TimeScanner scanner; ! TimeSpec spec; ! ! int op = TimeToken.PLUS; ! int prev_multiplier = -1; ! ! /** ! * Constructs TimeParser instance from the given input string. ! * @param dateString at-style time specification (read rrdfetch man page ! * for the complete explanation) ! */ ! public TimeParser(String dateString) { ! scanner = new TimeScanner(dateString); ! spec = new TimeSpec(dateString); ! } ! ! private void expectToken(int desired, String errorMessage) throws RrdException { ! token = scanner.nextToken(); ! if (token.id != desired) { ! throw new RrdException(errorMessage); ! } ! } ! ! private void plusMinus(int doop) throws RrdException { ! if (doop >= 0) { ! op = doop; ! expectToken(TimeToken.NUMBER, "There should be number after " + ! (op == TimeToken.PLUS ? '+' : '-')); ! prev_multiplier = -1; /* reset months-minutes guessing mechanics */ ! } ! int delta = Integer.parseInt(token.value); ! token = scanner.nextToken(); ! if (token.id == TimeToken.MONTHS_MINUTES) { ! /* hard job to guess what does that -5m means: -5mon or -5min? */ ! switch (prev_multiplier) { ! case TimeToken.DAYS: ! case TimeToken.WEEKS: ! case TimeToken.MONTHS: ! case TimeToken.YEARS: ! token = scanner.resolveMonthsMinutes(TimeToken.MONTHS); ! break; ! case TimeToken.SECONDS: ! case TimeToken.MINUTES: ! case TimeToken.HOURS: ! token = scanner.resolveMonthsMinutes(TimeToken.MINUTES); ! break; ! default: ! if (delta < 6) { ! token = scanner.resolveMonthsMinutes(TimeToken.MONTHS); ! } else { ! token = scanner.resolveMonthsMinutes(TimeToken.MINUTES); ! } ! } ! } ! prev_multiplier = token.id; ! delta *= (op == TimeToken.PLUS) ? +1 : -1; ! switch (token.id) { ! case TimeToken.YEARS: ! spec.dyear += delta; ! return; ! case TimeToken.MONTHS: ! spec.dmonth += delta; ! return; ! case TimeToken.WEEKS: ! delta *= 7; ! /* FALLTHRU */ ! case TimeToken.DAYS: ! spec.dday += delta; ! return; ! case TimeToken.HOURS: ! spec.dhour += delta; ! return; ! case TimeToken.MINUTES: ! spec.dmin += delta; ! return; ! case TimeToken.SECONDS: ! default: // default is 'seconds' ! spec.dsec += delta; ! return; ! } ! // unreachable statement ! // throw new RrdException("Well-known time unit expected after " + delta); ! } ! ! private void timeOfDay() throws RrdException { ! int hour, minute = 0; ! /* save token status in case we must abort */ ! scanner.saveState(); ! /* first pick out the time of day - we assume a HH (COLON|DOT) MM time */ ! if (token.value.length() > 2) { ! return; ! } ! hour = Integer.parseInt(token.value); ! token = scanner.nextToken(); ! if (token.id == TimeToken.SLASH || token.id == TimeToken.DOT) { ! /* guess we are looking at a date */ ! token = scanner.restoreState(); ! return; ! } ! if (token.id == TimeToken.COLON) { ! expectToken(TimeToken.NUMBER, "Parsing HH:MM syntax, expecting MM as number, got none"); ! minute = Integer.parseInt(token.value); ! if (minute > 59) { ! throw new RrdException("Parsing HH:MM syntax, got MM = " + ! minute + " (>59!)"); ! } ! token = scanner.nextToken(); ! } ! /* check if an AM or PM specifier was given */ ! if (token.id == TimeToken.AM || token.id == TimeToken.PM) { ! if (hour > 12) { ! throw new RrdException("There cannot be more than 12 AM or PM hours"); ! } ! if (token.id == TimeToken.PM) { ! if (hour != 12) { ! /* 12:xx PM is 12:xx, not 24:xx */ ! hour += 12; ! } ! } else { ! if (hour == 12) { ! /* 12:xx AM is 00:xx, not 12:xx */ ! hour = 0; ! } ! } ! token = scanner.nextToken(); ! } else if (hour > 23) { ! /* guess it was not a time then ... */ ! token = scanner.restoreState(); ! return; ! } ! spec.hour = hour; ! spec.min = minute; ! spec.sec = 0; ! if (spec.hour == 24) { ! spec.hour = 0; ! spec.day++; ! } ! } ! ! private void assignDate(long mday, long mon, long year) throws RrdException { ! if (year > 138) { ! if (year > 1970) { ! year -= 1900; ! } else { ! throw new RrdException("Invalid year " + year + ! " (should be either 00-99 or >1900)"); ! } ! } else if (year >= 0 && year < 38) { ! year += 100; /* Allow year 2000-2037 to be specified as */ ! } /* 00-37 until the problem of 2038 year will */ ! /* arise for unices with 32-bit time_t */ ! if (year < 70) { ! throw new RrdException("Won't handle dates before epoch (01/01/1970), sorry"); ! } ! spec.year = (int) year; ! spec.month = (int) mon; ! spec.day = (int) mday; ! } ! ! private void day() throws RrdException { ! long mday = 0, wday, mon, year = spec.year; ! switch (token.id) { ! case TimeToken.YESTERDAY: ! spec.day--; ! /* FALLTRHU */ ! case TimeToken.TODAY: /* force ourselves to stay in today - no further processing */ ! token = scanner.nextToken(); ! break; ! case TimeToken.TOMORROW: ! spec.day++; ! token = scanner.nextToken(); ! break; ! case TimeToken.JAN: ! case TimeToken.FEB: ! case TimeToken.MAR: ! case TimeToken.APR: ! case TimeToken.MAY: ! case TimeToken.JUN: ! case TimeToken.JUL: ! case TimeToken.AUG: ! case TimeToken.SEP: ! case TimeToken.OCT: ! case TimeToken.NOV: ! case TimeToken.DEC: ! /* do month mday [year] */ ! mon = (token.id - TimeToken.JAN); ! expectToken(TimeToken.NUMBER, "the day of the month should follow month name"); ! mday = Long.parseLong(token.value); ! token = scanner.nextToken(); ! if (token.id == TimeToken.NUMBER) { ! year = Long.parseLong(token.value); ! token = scanner.nextToken(); ! } else { ! year = spec.year; ! } ! assignDate(mday, mon, year); ! break; ! case TimeToken.SUN: ! case TimeToken.MON: ! case TimeToken.TUE: ! case TimeToken.WED: ! case TimeToken.THU: ! case TimeToken.FRI: ! case TimeToken.SAT: ! /* do a particular day of the week */ ! wday = (token.id - TimeToken.SUN); ! spec.day += (wday - spec.wday); ! token = scanner.nextToken(); ! break; ! case TimeToken.NUMBER: ! /* get numeric <sec since 1970>, MM/DD/[YY]YY, or DD.MM.[YY]YY */ ! // int tlen = token.value.length(); ! mon = Long.parseLong(token.value); ! if (mon > 10L * 365L * 24L * 60L * 60L) { ! spec.localtime(mon); ! token = scanner.nextToken(); ! break; ! } ! if (mon > 19700101 && mon < 24000101) { /*works between 1900 and 2400 */ ! year = mon / 10000; ! mday = mon % 100; ! mon = (mon / 100) % 100; ! token = scanner.nextToken(); ! } else { ! token = scanner.nextToken(); ! if (mon <= 31 && (token.id == TimeToken.SLASH || token.id == TimeToken.DOT)) { ! int sep = token.id; ! expectToken(TimeToken.NUMBER, "there should be " + ! (sep == TimeToken.DOT ? "month" : "day") + ! " number after " + ! (sep == TimeToken.DOT ? '.' : '/')); ! mday = Long.parseLong(token.value); ! token = scanner.nextToken(); ! if (token.id == sep) { ! expectToken(TimeToken.NUMBER, "there should be year number after " + ! (sep == TimeToken.DOT ? '.' : '/')); ! year = Long.parseLong(token.value); ! token = scanner.nextToken(); ! } ! /* flip months and days for European timing */ ! if (sep == TimeToken.DOT) { ! long x = mday; ! mday = mon; ! mon = x; ! } ! } ! } ! mon--; ! if (mon < 0 || mon > 11) { ! throw new RrdException("Did you really mean month " + (mon + 1)); ! } ! if (mday < 1 || mday > 31) { ! throw new RrdException("I'm afraid that " + mday + ! " is not a valid day of the month"); ! } ! assignDate(mday, mon, year); ! break; ! } ! } ! ! /** ! * Parses the input string specified in the constructor. ! * @return Object representing parsed date/time. ! * @throws RrdException Thrown if the date string cannot be parsed. ! */ ! public TimeSpec parse() throws RrdException { ! long now = Util.getTime(); ! int hr = 0; ! /* this MUST be initialized to zero for midnight/noon/teatime */ ! /* establish the default time reference */ ! spec.localtime(now); ! token = scanner.nextToken(); ! switch (token.id) { ! case TimeToken.PLUS: ! case TimeToken.MINUS: ! break; /* jump to OFFSET-SPEC part */ ! case TimeToken.START: ! spec.type = TimeSpec.TYPE_START; ! /* FALLTHRU */ ! case TimeToken.END: ! if (spec.type != TimeSpec.TYPE_START) { ! spec.type = TimeSpec.TYPE_END; ! } ! spec.year = spec.month = spec.day = spec.hour = spec.min = spec.sec = 0; ! /* FALLTHRU */ ! case TimeToken.NOW: ! int time_reference = token.id; ! token = scanner.nextToken(); ! if (token.id == TimeToken.PLUS || token.id == TimeToken.MINUS) { ! break; ! } ! if (time_reference != TimeToken.NOW) { ! throw new RrdException("Words 'start' or 'end' MUST be followed by +|- offset"); ! } else if (token.id != TimeToken.EOF) { ! throw new RrdException("If 'now' is followed by a token it must be +|- offset"); ! } ! break; ! /* Only absolute time specifications below */ ! case TimeToken.NUMBER: ! timeOfDay(); ! if (token.id != TimeToken.NUMBER) { ! break; ! } ! /* fix month parsing */ ! case TimeToken.JAN: ! case TimeToken.FEB: ! case TimeToken.MAR: ! case TimeToken.APR: ! case TimeToken.MAY: ! case TimeToken.JUN: ! case TimeToken.JUL: ! case TimeToken.AUG: ! case TimeToken.SEP: ! case TimeToken.OCT: ! case TimeToken.NOV: ! case TimeToken.DEC: ! day(); ! if (token.id != TimeToken.NUMBER) { ! break; ! } ! timeOfDay(); ! break; ! ! /* evil coding for TEATIME|NOON|MIDNIGHT - we've initialized ! * hr to zero up above, then fall into this case in such a ! * way so we add +12 +4 hours to it for teatime, +12 hours ! * to it for noon, and nothing at all for midnight, then ! * set our rettime to that hour before leaping into the ! * month scanner ! */ ! case TimeToken.TEATIME: ! hr += 4; ! /* FALLTHRU */ ! case TimeToken.NOON: ! hr += 12; ! /* FALLTHRU */ ! case TimeToken.MIDNIGHT: ! spec.hour = hr; ! spec.min = 0; ! spec.sec = 0; ! token = scanner.nextToken(); ! day(); ! break; ! default: ! throw new RrdException("Unparsable time: " + token.value); ! } ! ! /* ! * the OFFSET-SPEC part ! * ! * (NOTE, the sc_tokid was prefetched for us by the previous code) ! */ ! if (token.id == TimeToken.PLUS || token.id == TimeToken.MINUS) { ! scanner.setContext(false); ! while (token.id == TimeToken.PLUS || token.id == TimeToken.MINUS || ! token.id == TimeToken.NUMBER) { ! if (token.id == TimeToken.NUMBER) { ! plusMinus(PREVIOUS_OP); ! } else { ! plusMinus(token.id); ! } ! token = scanner.nextToken(); ! /* We will get EOF eventually but that's OK, since ! token() will return us as many EOFs as needed */ ! } ! } ! /* now we should be at EOF */ ! if (token.id != TimeToken.EOF) { ! throw new RrdException("Unparsable trailing text: " + token.value); ! } ! return spec; ! } ! ! /* ! public static void main(String[] args) throws IOException { ! BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); ! while (true) { ! String s = r.readLine(); ! try { ! TimeParser p = new TimeParser(s); ! TimeSpec spec = p.parse(); ! System.out.println(spec.getTime().getTime()); ! // System.out.println(spec.dump()); ! } catch (RrdException e) { ! System.err.println("ERROR: " + e); ! } ! } ! } ! */ } \ No newline at end of file --- 1,426 ---- ! /* ============================================================ ! * JRobin : Pure java implementation of RRDTool's functionality ! * ============================================================ ! * ! * Project Info: http://www.jrobin.org ! * Project Lead: Sasa Markovic (sa...@jr...); ! * ! * (C) Copyright 2003-2005, by Sasa Markovic. ! * ! * Developers: Sasa Markovic (sa...@jr...) ! * ! * ! * This library is free software; you can redistribute it and/or modify it under the terms ! * of the GNU Lesser General Public License as published by the Free Software Foundation; ! * either version 2.1 of the License, or (at your option) any later version. ! * ! * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ! * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! * See the GNU Lesser General Public License for more details. ! * ! * You should have received a copy of the GNU Lesser General Public License along with this ! * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, ! * Boston, MA 02111-1307, USA. ! */ ! ! /* ! * Java port of Tobi's original parsetime.c routine ! */ ! package org.jrobin.core.timespec; ! ! import org.jrobin.core.RrdException; ! import org.jrobin.core.Util; ! ! /** ! * Class which parses at-style time specification (describided in detail on the rrdfetch man page), ! * used in all RRDTool commands. This code is in most parts just a java port of Tobi's parsetime.c ! * code. ! */ ! public class TimeParser { ! private static final int PREVIOUS_OP = -1; ! ! TimeToken token; ! TimeScanner scanner; ! TimeSpec spec; ! ! int op = TimeToken.PLUS; ! int prev_multiplier = -1; ! ! /** ! * Constructs TimeParser instance from the given input string. ! * ! * @param dateString at-style time specification (read rrdfetch man page ! * for the complete explanation) ! */ ! public TimeParser(String dateString) { ! scanner = new TimeScanner(dateString); ! spec = new TimeSpec(dateString); ! } ! ! private void expectToken(int desired, String errorMessage) throws RrdException { ! token = scanner.nextToken(); ! if (token.id != desired) { ! throw new RrdException(errorMessage); ! } ! } ! ! private void plusMinus(int doop) throws RrdException { ! if (doop >= 0) { ! op = doop; ! expectToken(TimeToken.NUMBER, "There should be number after " + ! (op == TimeToken.PLUS ? '+' : '-')); ! prev_multiplier = -1; /* reset months-minutes guessing mechanics */ ! } ! int delta = Integer.parseInt(token.value); ! token = scanner.nextToken(); ! if (token.id == TimeToken.MONTHS_MINUTES) { ! /* hard job to guess what does that -5m means: -5mon or -5min? */ ! switch (prev_multiplier) { ! case TimeToken.DAYS: ! case TimeToken.WEEKS: ! case TimeToken.MONTHS: ! case TimeToken.YEARS: ! token = scanner.resolveMonthsMinutes(TimeToken.MONTHS); ! break; ! case TimeToken.SECONDS: ! case TimeToken.MINUTES: ! case TimeToken.HOURS: ! token = scanner.resolveMonthsMinutes(TimeToken.MINUTES); ! break; ! default: ! if (delta < 6) { ! token = scanner.resolveMonthsMinutes(TimeToken.MONTHS); ! } ! else { ! token = scanner.resolveMonthsMinutes(TimeToken.MINUTES); ! } ! } ! } ! prev_multiplier = token.id; ! delta *= (op == TimeToken.PLUS) ? +1 : -1; ! switch (token.id) { ! case TimeToken.YEARS: ! spec.dyear += delta; ! break; ! case TimeToken.MONTHS: ! spec.dmonth += delta; ! break; ! case TimeToken.WEEKS: ! delta *= 7; ! /* FALLTHRU */ ! case TimeToken.DAYS: ! spec.dday += delta; ! break; ! case TimeToken.HOURS: ! spec.dhour += delta; ! break; ! case TimeToken.MINUTES: ! spec.dmin += delta; ! break; ! case TimeToken.SECONDS: ! default: // default is 'seconds' ! spec.dsec += delta; ! break; ! } ! // unreachable statement ! // throw new RrdException("Well-known time unit expected after " + delta); ! } ! ! private void timeOfDay() throws RrdException { ! int hour, minute = 0; ! /* save token status in case we must abort */ ! scanner.saveState(); ! /* first pick out the time of day - we assume a HH (COLON|DOT) MM time */ ! if (token.value.length() > 2) { ! return; ! } ! hour = Integer.parseInt(token.value); ! token = scanner.nextToken(); ! if (token.id == TimeToken.SLASH || token.id == TimeToken.DOT) { ! /* guess we are looking at a date */ ! token = scanner.restoreState(); ! return; ! } ! if (token.id == TimeToken.COLON) { ! expectToken(TimeToken.NUMBER, "Parsing HH:MM syntax, expecting MM as number, got none"); ! minute = Integer.parseInt(token.value); ! if (minute > 59) { ! throw new RrdException("Parsing HH:MM syntax, got MM = " + ! minute + " (>59!)"); ! } ! token = scanner.nextToken(); ! } ! /* check if an AM or PM specifier was given */ ! if (token.id == TimeToken.AM || token.id == TimeToken.PM) { ! if (hour > 12) { ! throw new RrdException("There cannot be more than 12 AM or PM hours"); ! } ! if (token.id == TimeToken.PM) { ! if (hour != 12) { ! /* 12:xx PM is 12:xx, not 24:xx */ ! hour += 12; ! } ! } ! else { ! if (hour == 12) { ! /* 12:xx AM is 00:xx, not 12:xx */ ! hour = 0; ! } ! } ! token = scanner.nextToken(); ! } ! else if (hour > 23) { ! /* guess it was not a time then ... */ ! token = scanner.restoreState(); ! return; ! } ! spec.hour = hour; ! spec.min = minute; ! spec.sec = 0; ! if (spec.hour == 24) { ! spec.hour = 0; ! spec.day++; ! } ! } ! ! private void assignDate(long mday, long mon, long year) throws RrdException { ! if (year > 138) { ! if (year > 1970) { ! year -= 1900; ! } ! else { ! throw new RrdException("Invalid year " + year + ! " (should be either 00-99 or >1900)"); ! } ! } ! else if (year >= 0 && year < 38) { ! year += 100; /* Allow year 2000-2037 to be specified as */ ! } /* 00-37 until the problem of 2038 year will */ ! /* arise for unices with 32-bit time_t */ ! if (year < 70) { ! throw new RrdException("Won't handle dates before epoch (01/01/1970), sorry"); ! } ! spec.year = (int) year; ! spec.month = (int) mon; ! spec.day = (int) mday; ! } ! ! private void day() throws RrdException { ! long mday = 0, wday, mon, year = spec.year; ! switch (token.id) { ! case TimeToken.YESTERDAY: ! spec.day--; ! /* FALLTRHU */ ! case TimeToken.TODAY: /* force ourselves to stay in today - no further processing */ ! token = scanner.nextToken(); ! break; ! case TimeToken.TOMORROW: ! spec.day++; ! token = scanner.nextToken(); ! break; ! case TimeToken.JAN: ! case TimeToken.FEB: ! case TimeToken.MAR: ! case TimeToken.APR: ! case TimeToken.MAY: ! case TimeToken.JUN: ! case TimeToken.JUL: ! case TimeToken.AUG: ! case TimeToken.SEP: ! case TimeToken.OCT: ! case TimeToken.NOV: ! case TimeToken.DEC: ! /* do month mday [year] */ ! mon = (token.id - TimeToken.JAN); ! expectToken(TimeToken.NUMBER, "the day of the month should follow month name"); ! mday = Long.parseLong(token.value); ! token = scanner.nextToken(); ! if (token.id == TimeToken.NUMBER) { ! year = Long.parseLong(token.value); ! token = scanner.nextToken(); ! } ! else { ! year = spec.year; ! } ! assignDate(mday, mon, year); ! break; ! case TimeToken.SUN: ! case TimeToken.MON: ! case TimeToken.TUE: ! case TimeToken.WED: ! case TimeToken.THU: ! case TimeToken.FRI: ! case TimeToken.SAT: ! /* do a particular day of the week */ ! wday = (token.id - TimeToken.SUN); ! spec.day += (wday - spec.wday); ! token = scanner.nextToken(); ! break; ! case TimeToken.NUMBER: ! /* get numeric <sec since 1970>, MM/DD/[YY]YY, or DD.MM.[YY]YY */ ! // int tlen = token.value.length(); ! mon = Long.parseLong(token.value); ! if (mon > 10L * 365L * 24L * 60L * 60L) { ! spec.localtime(mon); ! token = scanner.nextToken(); ! break; ! } ! if (mon > 19700101 && mon < 24000101) { /*works between 1900 and 2400 */ ! year = mon / 10000; ! mday = mon % 100; ! mon = (mon / 100) % 100; ! token = scanner.nextToken(); ! } ! else { ! token = scanner.nextToken(); ! if (mon <= 31 && (token.id == TimeToken.SLASH || token.id == TimeToken.DOT)) { ! int sep = token.id; ! expectToken(TimeToken.NUMBER, "there should be " + ! (sep == TimeToken.DOT ? "month" : "day") + ! " number after " + ! (sep == TimeToken.DOT ? '.' : '/')); ! mday = Long.parseLong(token.value); ! token = scanner.nextToken(); ! if (token.id == sep) { ! expectToken(TimeToken.NUMBER, "there should be year number after " + ! (sep == TimeToken.DOT ? '.' : '/')); ! year = Long.parseLong(token.value); ! token = scanner.nextToken(); ! } ! /* flip months and days for European timing */ ! if (sep == TimeToken.DOT) { ! long x = mday; ! mday = mon; ! mon = x; ! } ! } ! } ! mon--; ! if (mon < 0 || mon > 11) { ! throw new RrdException("Did you really mean month " + (mon + 1)); ! } ! if (mday < 1 || mday > 31) { ! throw new RrdException("I'm afraid that " + mday + ! " is not a valid day of the month"); ! } ! assignDate(mday, mon, year); ! break; ! } ! } ! ! /** ! * Parses the input string specified in the constructor. ! * ! * @return Object representing parsed date/time. ! * @throws RrdException Thrown if the date string cannot be parsed. ! */ ! public TimeSpec parse() throws RrdException { ! long now = Util.getTime(); ! int hr = 0; ! /* this MUST be initialized to zero for midnight/noon/teatime */ ! /* establish the default time reference */ ! spec.localtime(now); ! token = scanner.nextToken(); ! switch (token.id) { ! case TimeToken.PLUS: ! case TimeToken.MINUS: ! break; /* jump to OFFSET-SPEC part */ ! case TimeToken.START: ! spec.type = TimeSpec.TYPE_START; ! /* FALLTHRU */ ! case TimeToken.END: ! if (spec.type != TimeSpec.TYPE_START) { ! spec.type = TimeSpec.TYPE_END; ! } ! spec.year = spec.month = spec.day = spec.hour = spec.min = spec.sec = 0; ! /* FALLTHRU */ ! case TimeToken.NOW: ! int time_reference = token.id; ! token = scanner.nextToken(); ! if (token.id == TimeToken.PLUS || token.id == TimeToken.MINUS) { ! break; ! } ! if (time_reference != TimeToken.NOW) { ! throw new RrdException("Words 'start' or 'end' MUST be followed by +|- offset"); ! } ! else if (token.id != TimeToken.EOF) { ! throw new RrdException("If 'now' is followed by a token it must be +|- offset"); ! } ! break; ! /* Only absolute time specifications below */ ! case TimeToken.NUMBER: ! timeOfDay(); ! if (token.id != TimeToken.NUMBER) { ! break; ! } ! /* fix month parsing */ ! case TimeToken.JAN: ! case TimeToken.FEB: ! case TimeToken.MAR: ! case TimeToken.APR: ! case TimeToken.MAY: ! case TimeToken.JUN: ! case TimeToken.JUL: ! case TimeToken.AUG: ! case TimeToken.SEP: ! case TimeToken.OCT: ! case TimeToken.NOV: ! case TimeToken.DEC: ! day(); ! if (token.id != TimeToken.NUMBER) { ! break; ! } ! timeOfDay(); ! break; ! ! /* evil coding for TEATIME|NOON|MIDNIGHT - we've initialized ! * hr to zero up above, then fall into this case in such a ! * way so we add +12 +4 hours to it for teatime, +12 hours ! * to it for noon, and nothing at all for midnight, then ! * set our rettime to that hour before leaping into the ! * month scanner ! */ ! case TimeToken.TEATIME: ! hr += 4; ! /* FALLTHRU */ ! case TimeToken.NOON: ! hr += 12; ! /* FALLTHRU */ ! case TimeToken.MIDNIGHT: ! spec.hour = hr; ! spec.min = 0; ! spec.sec = 0; ! token = scanner.nextToken(); ! day(); ! break; ! default: ! throw new RrdException("Unparsable time: " + token.value); ! } ! ! /* ! * the OFFSET-SPEC part ! * ! * (NOTE, the sc_tokid was prefetched for us by the previous code) ! */ ! if (token.id == TimeToken.PLUS || token.id == TimeToken.MINUS) { ! scanner.setContext(false); ! while (token.id == TimeToken.PLUS || token.id == TimeToken.MINUS || ! token.id == TimeToken.NUMBER) { ! if (token.id == TimeToken.NUMBER) { ! plusMinus(PREVIOUS_OP); ! } ! else { ! plusMinus(token.id); ! } ! token = scanner.nextToken(); ! /* We will get EOF eventually but that's OK, since ! token() will return us as many EOFs as needed */ ! } ! } ! /* now we should be at EOF */ ! if (token.id != TimeToken.EOF) { ! throw new RrdException("Unparsable trailing text: " + token.value); ! } ! return spec; ! } } \ No newline at end of file Index: Epoch.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/timespec/Epoch.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Epoch.java 17 Feb 2005 10:43:13 -0000 1.1 --- Epoch.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,152 **** ! package org.jrobin.core.timespec; ! ! import org.jrobin.core.RrdException; ! import org.jrobin.core.Util; ! ! import javax.swing.*; ! import java.util.Date; ! import java.awt.*; ! import java.awt.event.ActionListener; ! import java.awt.event.ActionEvent; ! import java.text.SimpleDateFormat; ! import java.text.ParseException; ! ! class Epoch extends JFrame implements Runnable { ! private static final String[] formats = { ! "MM/dd/yy HH:mm:ss", ! "dd.MM.yy HH:mm:ss", ! "yy-MM-dd HH:mm:ss", ! "MM/dd/yy HH:mm", ! "dd.MM.yy HH:mm", ! "yy-MM-dd HH:mm", ! "MM/dd/yy", ! "dd.MM.yy", ! "yy-MM-dd", ! "HH:mm MM/dd/yy", ! "HH:mm dd.MM.yy", ! "HH:mm yy-MM-dd", ! "HH:mm:ss MM/dd/yy", ! "HH:mm:ss dd.MM.yy", ! "HH:mm:ss yy-MM-dd" ! }; ! ! private static final SimpleDateFormat[] parsers = new SimpleDateFormat[formats.length]; ! private static final String helpText; ! ! static { ! for(int i = 0; i < parsers.length; i++) { ! parsers[i] = new SimpleDateFormat(formats[i]); ! parsers[i].setLenient(true); ! } ! StringBuffer tooltipBuff = new StringBuffer("<html><b>Supported input formats:</b><br>"); ! for(int i = 0; i < formats.length; i++) { ! tooltipBuff.append(formats[i] + "<br>"); ! } ! tooltipBuff.append("<b>RRDTool time format</b><br>"); ! tooltipBuff.append("... including timestamps</html>"); ! helpText = tooltipBuff.toString(); ! } ! ! private JLabel topLabel = new JLabel("Enter timestamp or readable date:"); ! private JTextField inputField = new JTextField(25); ! private JButton button = new JButton("Convert"); ! //private JLabel helpLabel = new JLabel(helpText); ! ! private static final SimpleDateFormat OUTPUT_DATE_FORMAT = ! new SimpleDateFormat("MM/dd/yy HH:mm:ss EEE"); ! ! Epoch() { ! super("Epoch"); ! constructUI(); ! setVisible(true); ! new Thread(this).start(); ! } ! ! private void constructUI() { ! JPanel c = (JPanel) getContentPane(); ! c.setLayout(new BorderLayout()); ! ! c.add(topLabel, BorderLayout.NORTH); ! c.add(inputField, BorderLayout.CENTER); ! c.add(button, BorderLayout.EAST); ! // c.add(helpLabel, BorderLayout.WEST); ! ! button.setToolTipText(helpText); ! button.addActionListener(new ActionListener() { ! public void actionPerformed(ActionEvent e) { ! convert(); ! } ! }); ! ! inputField.requestFocus(); ! getRootPane().setDefaultButton(button); ! setResizable(false); ! setDefaultCloseOperation(EXIT_ON_CLOSE); ! pack(); ! centerOnScreen(); ! ! } ! ! void centerOnScreen() { ! Toolkit t = Toolkit.getDefaultToolkit(); ! Dimension screenSize = t.getScreenSize(); ! Dimension frameSize = getPreferredSize(); ! double x = (screenSize.getWidth() - frameSize.getWidth()) / 2; ! double y = (screenSize.getHeight() - frameSize.getHeight()) / 2; ! setLocation((int) x, (int) y); ! } ! ! private void convert() { ! String time = inputField.getText().trim(); ! if(time.length() > 0) { ! // try simple timestamp ! try { ! long timestamp = Long.parseLong(time); ! Date date = new Date(timestamp * 1000L); ! formatDate(date); ! } ! catch(NumberFormatException nfe) { ! // failed, try as a date ! try { ! inputField.setText("" + parseDate(time)); ! } ! catch (RrdException e) { ! inputField.setText("Could not convert, sorry"); ! } ! } ! } ! } ! ! public void run() { ! for(;;) { ! Date now = new Date(); ! long timestamp = now.getTime() / 1000L; ! setTitle(timestamp + " seconds since epoch"); ! try { ! Thread.sleep(1000L); ! } ! catch (InterruptedException e) { ! } ! } ! } ! ! void formatDate(Date date) { ! inputField.setText(OUTPUT_DATE_FORMAT.format(date)); ! } ! ! private long parseDate(String time) throws RrdException { ! for(int i = 0; i < parsers.length; i++) { ! try { ! return Util.getTimestamp(parsers[i].parse(time)); ! } ! catch (ParseException e) { ! } ! } ! return new TimeParser(time).parse().getTimestamp(); ! } ! ! ! public static void main(String[] args) { ! new Epoch(); ! } ! } --- 1,168 ---- ! package org.jrobin.core.timespec; ! ! import org.jrobin.core.RrdException; ! import org.jrobin.core.Util; ! ! import javax.swing.*; ! import java.awt.*; ! import java.awt.event.ActionEvent; ! import java.awt.event.ActionListener; ! import java.text.ParseException; ! import java.text.SimpleDateFormat; ! import java.util.Date; ! ! /** ! * Small swing-based utility to convert timestamps (seconds since epoch) to readable dates and vice versa. ! * Supports at-style time specification (like "now-2d", "noon yesterday") and other human-readable ! * data formats:<p> ! * <ul> ! * <li>MM/dd/yy HH:mm:ss ! * <li>dd.MM.yy HH:mm:ss ! * <li>dd.MM.yy HH:mm:ss ! * <li>MM/dd/yy HH:mm ! * <li>dd.MM.yy HH:mm ! * <li>yy-MM-dd HH:mm ! * <li>MM/dd/yy ! * <li>dd.MM.yy ! * <li>yy-MM-dd ! * <li>HH:mm MM/dd/yy ! * <li>HH:mm dd.MM.yy ! * <li>HH:mm yy-MM-dd ! * <li>HH:mm:ss MM/dd/yy ! * <li>HH:mm:ss dd.MM.yy ! * <li>HH:mm:ss yy-MM-dd ! * </ul> ! * The current timestamp is displayed in the title bar :)<p> ! */ ! public class Epoch extends JFrame { ! private static final String[] supportedFormats = { ! "MM/dd/yy HH:mm:ss", "dd.MM.yy HH:mm:ss", "yy-MM-dd HH:mm:ss", "MM/dd/yy HH:mm", ! "dd.MM.yy HH:mm", "yy-MM-dd HH:mm", "MM/dd/yy", "dd.MM.yy", "yy-MM-dd", "HH:mm MM/dd/yy", ! "HH:mm dd.MM.yy", "HH:mm yy-MM-dd", "HH:mm:ss MM/dd/yy", "HH:mm:ss dd.MM.yy", "HH:mm:ss yy-MM-dd" ! }; ! ! private static final SimpleDateFormat[] parsers = new SimpleDateFormat[supportedFormats.length]; ! private static final String helpText; ! ! private Timer timer = new Timer(1000, new ActionListener() { ! public void actionPerformed(ActionEvent e) { ! showTimestamp(); ! } ! }); ! ! static { ! for (int i = 0; i < parsers.length; i++) { ! parsers[i] = new SimpleDateFormat(supportedFormats[i]); ! parsers[i].setLenient(true); ! } ! StringBuffer tooltipBuff = new StringBuffer("<html><b>Supported input formats:</b><br>"); ! for (String supportedFormat : supportedFormats) { ! tooltipBuff.append(supportedFormat).append("<br>"); ! } ! tooltipBuff.append("<b>AT-style time specification</b><br>"); ! tooltipBuff.append("timestamp<br><br>"); ! tooltipBuff.append("Copyright (C) 2003-2005 Sasa Markovic, All Rights Reserved</html>"); ! helpText = tooltipBuff.toString(); ! } ! ! private JLabel topLabel = new JLabel("Enter timestamp or readable date:"); ! private JTextField inputField = new JTextField(25); ! private JButton convertButton = new JButton("Convert"); ! private JButton helpButton = new JButton("Help"); ! ! private static final SimpleDateFormat OUTPUT_DATE_FORMAT = ! new SimpleDateFormat("MM/dd/yy HH:mm:ss EEE"); ! ! Epoch() { ! super("Epoch"); ! constructUI(); ! timer.start(); ! } ! ! private void constructUI() { ! JPanel c = (JPanel) getContentPane(); ! c.setLayout(new BorderLayout(3, 3)); ! c.add(topLabel, BorderLayout.NORTH); ! c.add(inputField, BorderLayout.WEST); ! c.add(convertButton, BorderLayout.CENTER); ! convertButton.setToolTipText(helpText); ! convertButton.addActionListener(new ActionListener() { ! public void actionPerformed(ActionEvent e) { ! convert(); ! } ! }); ! c.add(helpButton, BorderLayout.EAST); ! helpButton.addActionListener(new ActionListener() { ! public void actionPerformed(ActionEvent e) { ! JOptionPane.showMessageDialog(helpButton, helpText, "Epoch Help", JOptionPane.INFORMATION_MESSAGE); ! } ! }); ! inputField.requestFocus(); ! getRootPane().setDefaultButton(convertButton); ! setResizable(false); ! setDefaultCloseOperation(EXIT_ON_CLOSE); ! pack(); ! centerOnScreen(); ! setVisible(true); ! } ! ! void centerOnScreen() { ! Toolkit t = Toolkit.getDefaultToolkit(); ! Dimension screenSize = t.getScreenSize(); ! Dimension frameSize = getPreferredSize(); ! double x = (screenSize.getWidth() - frameSize.getWidth()) / 2; ! double y = (screenSize.getHeight() - frameSize.getHeight()) / 2; ! setLocation((int) x, (int) y); ! } ! ! private void convert() { ! String time = inputField.getText().trim(); ! if (time.length() > 0) { ! // try simple timestamp ! try { ! long timestamp = Long.parseLong(time); ! Date date = new Date(timestamp * 1000L); ! formatDate(date); ! } ! catch (NumberFormatException nfe) { ! // failed, try as a date ! try { ! inputField.setText("" + parseDate(time)); ! } ! catch (RrdException e) { ! inputField.setText("Could not convert, sorry"); ! } ! } ! } ! } ! ! private void showTimestamp() { ! long timestamp = Util.getTime(); ! setTitle(timestamp + " seconds since epoch"); ! } ! ! void formatDate(Date date) { ! inputField.setText(OUTPUT_DATE_FORMAT.format(date)); ! } ! ! private long parseDate(String time) throws RrdException { ! for (SimpleDateFormat parser : parsers) { ! try { ! return Util.getTimestamp(parser.parse(time)); ! } ! catch (ParseException e) { ! // NOP ! } ! } ! return new TimeParser(time).parse().getTimestamp(); ! } ! ! /** ! * Main method which runs this utility. ! * ! * @param args Not used. ! */ ! public static void main(String[] args) { ! new Epoch(); ! } ! } Index: TimeToken.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/timespec/TimeToken.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TimeToken.java 17 Feb 2005 10:43:13 -0000 1.1 --- TimeToken.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,88 **** ! /* ============================================================ ! * JRobin : Pure java implementation of RRDTool's functionality ! * ============================================================ ! * ! * Project Info: http://www.jrobin.org ! * Project Lead: Sasa Markovic (sa...@jr...); ! * ! * (C) Copyright 2003, by Sasa Markovic. ! * ! * Developers: Sasa Markovic (sa...@jr...) ! * Arne Vandamme (cob...@jr...) ! * ! * This library is free software; you can redistribute it and/or modify it under the terms ! * of the GNU Lesser General Public License as published by the Free Software Foundation; ! * either version 2.1 of the License, or (at your option) any later version. ! * ! * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ! * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! * See the GNU Lesser General Public License for more details. ! * ! * You should have received a copy of the GNU Lesser General Public License along with this ! * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, ! * Boston, MA 02111-1307, USA. ! */ ! ! package org.jrobin.core.timespec; ! ! class TimeToken { ! public static final int MIDNIGHT = 1; ! public static final int NOON = 2; ! public static final int TEATIME = 3; ! public static final int PM = 4; ! public static final int AM = 5; ! public static final int YESTERDAY = 6; ! public static final int TODAY = 7; ! public static final int TOMORROW = 8; ! public static final int NOW = 9; ! public static final int START = 10; ! public static final int END = 11; ! public static final int SECONDS = 12; ! public static final int MINUTES = 13; ! public static final int HOURS = 14; ! public static final int DAYS = 15; ! public static final int WEEKS = 16; ! public static final int MONTHS = 17; ! public static final int YEARS = 18; ! public static final int MONTHS_MINUTES = 19; ! public static final int NUMBER = 20; ! public static final int PLUS = 21; ! public static final int MINUS = 22; ! public static final int DOT = 23; ! public static final int COLON = 24; ! public static final int SLASH = 25; ! public static final int ID = 26; ! public static final int JUNK = 27; ! public static final int JAN = 28; ! public static final int FEB = 29; ! public static final int MAR = 30; ! public static final int APR = 31; ! public static final int MAY = 32; ! public static final int JUN = 33; ! public static final int JUL = 34; ! public static final int AUG = 35; ! public static final int SEP = 36; ! public static final int OCT = 37; ! public static final int NOV = 38; ! public static final int DEC = 39; ! public static final int SUN = 40; ! public static final int MON = 41; ! public static final int TUE = 42; ! public static final int WED = 43; ! public static final int THU = 44; ! public static final int FRI = 45; ! public static final int SAT = 46; ! public static final int EOF = -1; ! ! final String value; /* token name */ ! final int id; /* token id */ ! ! public TimeToken(String value, int id) { ! this.value = value; ! this.id = id; ! } ! ! public String toString() { ! return value + " [" + id + "]"; ! } } \ No newline at end of file --- 1,88 ---- ! /* ============================================================ ! * JRobin : Pure java implementation of RRDTool's functionality ! * ============================================================ ! * ! * Project Info: http://www.jrobin.org ! * Project Lead: Sasa Markovic (sa...@jr...); ! * ! * (C) Copyright 2003-2005, by Sasa Markovic. ! * ! * Developers: Sasa Markovic (sa...@jr...) ! * ! * ! * This library is free software; you can redistribute it and/or modify it under the terms ! * of the GNU Lesser General Public License as published by the Free Software Foundation; ! * either version 2.1 of the License, or (at your option) any later version. ! * ! * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ! * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! * See the GNU Lesser General Public License for more details. ! * ! * You should have received a copy of the GNU Lesser General Public License along with this ! * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, ! * Boston, MA 02111-1307, USA. ! */ ! ! package org.jrobin.core.timespec; ! ! class TimeToken { ! public static final int MIDNIGHT = 1; ! public static final int NOON = 2; ! public static final int TEATIME = 3; ! public static final int PM = 4; ! public static final int AM = 5; ! public static final int YESTERDAY = 6; ! public static final int TODAY = 7; ! public static final int TOMORROW = 8; ! public static final int NOW = 9; ! public static final int START = 10; ! public static final int END = 11; ! public static final int SECONDS = 12; ! public static final int MINUTES = 13; ! public static final int HOURS = 14; ! public static final int DAYS = 15; ! public static final int WEEKS = 16; ! public static final int MONTHS = 17; ! public static final int YEARS = 18; ! public static final int MONTHS_MINUTES = 19; ! public static final int NUMBER = 20; ! public static final int PLUS = 21; ! public static final int MINUS = 22; ! public static final int DOT = 23; ! public static final int COLON = 24; ! public static final int SLASH = 25; ! public static final int ID = 26; ! public static final int JUNK = 27; ! public static final int JAN = 28; ! public static final int FEB = 29; ! public static final int MAR = 30; ! public static final int APR = 31; ! public static final int MAY = 32; ! public static final int JUN = 33; ! public static final int JUL = 34; ! public static final int AUG = 35; ! public static final int SEP = 36; ! public static final int OCT = 37; ! public static final int NOV = 38; ! public static final int DEC = 39; ! public static final int SUN = 40; ! public static final int MON = 41; ! public static final int TUE = 42; ! public static final int WED = 43; ! public static final int THU = 44; ! public static final int FRI = 45; ! public static final int SAT = 46; ! public static final int EOF = -1; ! ! final String value; /* token name */ ! final int id; /* token id */ ! ! public TimeToken(String value, int id) { ! this.value = value; ! this.id = id; ! } ! ! public String toString() { ! return value + " [" + id + "]"; ! } } \ No newline at end of file Index: TimeScanner.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/timespec/TimeScanner.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TimeScanner.java 17 Feb 2005 10:43:13 -0000 1.1 --- TimeScanner.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,208 **** ! /* ============================================================ ! * JRobin : Pure java implementation of RRDTool's functionality ! * ============================================================ ! * ! * Project Info: http://www.jrobin.org ! * Project Lead: Sasa Markovic (sa...@jr...); ! * ! * (C) Copyright 2003, by Sasa Markovic. ! * ! * Developers: Sasa Markovic (sa...@jr...) ! * Arne Vandamme (cob...@jr...) ! * ! * This library is free software; you can redistribute it and/or modify it under the terms ! * of the GNU Lesser General Public License as published by the Free Software Foundation; ! * either version 2.1 of the License, or (at your option) any later version. ! * ! * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ! * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! * See the GNU Lesser General Public License for more details. ! * ! * You should have received a copy of the GNU Lesser General Public License along with this ! * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, ! * Boston, MA 02111-1307, USA. ! */ ! package org.jrobin.core.timespec; ! ! class TimeScanner { ! private String dateString; ! ! private int pos, pos_save; ! private TimeToken token, token_save; ! ! static final TimeToken[] WORDS = { ! new TimeToken("midnight", TimeToken.MIDNIGHT), /* 00:00:00 of today or tomorrow */ ! new TimeToken("noon", TimeToken.NOON), /* 12:00:00 of today or tomorrow */ ! new TimeToken("teatime", TimeToken.TEATIME), /* 16:00:00 of today or tomorrow */ ! new TimeToken("am", TimeToken.AM), /* morning times for 0-12 clock */ ! new TimeToken("pm", TimeToken.PM), /* evening times for 0-12 clock */ ! new TimeToken("tomorrow", TimeToken.TOMORROW), ! new TimeToken("yesterday", TimeToken.YESTERDAY), ! new TimeToken("today", TimeToken.TODAY), ! new TimeToken("now", TimeToken.NOW), ! new TimeToken("n", TimeToken.NOW), ! new TimeToken("start", TimeToken.START), ! new TimeToken("s", TimeToken.START), ! new TimeToken("end", TimeToken.END), ! new TimeToken("e", TimeToken.END), ! new TimeToken("jan", TimeToken.JAN), ! new TimeToken("feb", TimeToken.FEB), ! new TimeToken("mar", TimeToken.MAR), ! new TimeToken("apr", TimeToken.APR), ! new TimeToken("may", TimeToken.MAY), ! new TimeToken("jun", TimeToken.JUN), ! new TimeToken("jul", TimeToken.JUL), ! new TimeToken("aug", TimeToken.AUG), ! new TimeToken("sep", TimeToken.SEP), ! new TimeToken("oct", TimeToken.OCT), ! new TimeToken("nov", TimeToken.NOV), ! new TimeToken("dec", TimeToken.DEC), ! new TimeToken("january", TimeToken.JAN), ! new TimeToken("february", TimeToken.FEB), ! new TimeToken("march", TimeToken.MAR), ! new TimeToken("april", TimeToken.APR), ! new TimeToken("may", TimeToken.MAY), ! new TimeToken("june", TimeToken.JUN), ! new TimeToken("july", TimeToken.JUL), ! new TimeToken("august", TimeToken.AUG), ! new TimeToken("september", TimeToken.SEP), ! new TimeToken("october", TimeToken.OCT), ! new TimeToken("november", TimeToken.NOV), ! new TimeToken("december", TimeToken.DEC), ! new TimeToken("sunday", TimeToken.SUN), ! new TimeToken("su... [truncated message content] |