001 /* ============================================================
002 * JRobin : Pure java implementation of RRDTool's functionality
003 * ============================================================
004 *
005 * Project Info: http://www.jrobin.org
006 * Project Lead: Sasa Markovic (saxon@jrobin.org);
007 *
008 * (C) Copyright 2003-2005, by Sasa Markovic.
009 *
010 * Developers: Sasa Markovic (saxon@jrobin.org)
011 *
012 *
013 * This library is free software; you can redistribute it and/or modify it under the terms
014 * of the GNU Lesser General Public License as published by the Free Software Foundation;
015 * either version 2.1 of the License, or (at your option) any later version.
016 *
017 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
018 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
019 * See the GNU Lesser General Public License for more details.
020 *
021 * You should have received a copy of the GNU Lesser General Public License along with this
022 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
023 * Boston, MA 02111-1307, USA.
024 */
025
026 package org.jrobin.core.timespec;
027
028 import org.jrobin.core.RrdException;
029 import org.jrobin.core.Util;
030
031 import java.util.Calendar;
032 import java.util.Date;
033 import java.util.GregorianCalendar;
034
035 /**
036 * Simple class to represent time obtained by parsing at-style date specification (described
037 * in detail on the rrdfetch man page. See javadoc for {@link org.jrobin.core.timespec.TimeParser}
038 * for more information.
039 */
040 public class TimeSpec {
041 static final int TYPE_ABSOLUTE = 0;
042 static final int TYPE_START = 1;
043 static final int TYPE_END = 2;
044
045 int type = TYPE_ABSOLUTE;
046 int year, month, day, hour, min, sec;
047 int wday;
048 int dyear, dmonth, dday, dhour, dmin, dsec;
049
050 String dateString;
051
052 TimeSpec context;
053
054 TimeSpec(String dateString) {
055 this.dateString = dateString;
056 }
057
058 void localtime(long timestamp) {
059 GregorianCalendar date = new GregorianCalendar();
060 date.setTime(new Date(timestamp * 1000L));
061 year = date.get(Calendar.YEAR) - 1900;
062 month = date.get(Calendar.MONTH);
063 day = date.get(Calendar.DAY_OF_MONTH);
064 hour = date.get(Calendar.HOUR_OF_DAY);
065 min = date.get(Calendar.MINUTE);
066 sec = date.get(Calendar.SECOND);
067 wday = date.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
068 }
069
070 GregorianCalendar getTime() throws RrdException {
071 GregorianCalendar gc;
072 // absoulte time, this is easy
073 if (type == TYPE_ABSOLUTE) {
074 gc = new GregorianCalendar(year + 1900, month, day, hour, min, sec);
075 }
076 // relative time, we need a context to evaluate it
077 else if (context != null && context.type == TYPE_ABSOLUTE) {
078 gc = context.getTime();
079 }
080 // how would I guess what time it was?
081 else {
082 throw new RrdException("Relative times like '" +
083 dateString + "' require proper absolute context to be evaluated");
084 }
085 gc.add(Calendar.YEAR, dyear);
086 gc.add(Calendar.MONTH, dmonth);
087 gc.add(Calendar.DAY_OF_MONTH, dday);
088 gc.add(Calendar.HOUR_OF_DAY, dhour);
089 gc.add(Calendar.MINUTE, dmin);
090 gc.add(Calendar.SECOND, dsec);
091 return gc;
092 }
093
094 /**
095 * Returns the corresponding timestamp (seconds since Epoch). Example:<p>
096 * <pre>
097 * TimeParser p = new TimeParser("now-1day");
098 * TimeSpec ts = p.parse();
099 * System.out.println("Timestamp was: " + ts.getTimestamp();
100 * </pre>
101 *
102 * @return Timestamp (in seconds, no milliseconds)
103 * @throws RrdException Thrown if this TimeSpec object does not represent absolute time.
104 */
105 public long getTimestamp() throws RrdException {
106 return Util.getTimestamp(getTime());
107 }
108
109 String dump() {
110 return (type == TYPE_ABSOLUTE ? "ABSTIME" : type == TYPE_START ? "START" : "END") +
111 ": " + year + "/" + month + "/" + day +
112 "/" + hour + "/" + min + "/" + sec + " (" +
113 dyear + "/" + dmonth + "/" + dday +
114 "/" + dhour + "/" + dmin + "/" + dsec + ")";
115 }
116
117 /**
118 * Use this static method to resolve relative time references and obtain the corresponding
119 * Calendar objects. Example:<p>
120 * <pre>
121 * TimeParser pStart = new TimeParser("now-1month"); // starting time
122 * TimeParser pEnd = new TimeParser("start+1week"); // ending time
123 * TimeSpec specStart = pStart.parse();
124 * TimeSpec specEnd = pEnd.parse();
125 * GregorianCalendar[] gc = TimeSpec.getTimes(specStart, specEnd);
126 * </pre>
127 *
128 * @param spec1 Starting time specification
129 * @param spec2 Ending time specification
130 * @return Two element array containing Calendar objects
131 * @throws RrdException Thrown if relative time references cannot be resolved
132 */
133 public static Calendar[] getTimes(TimeSpec spec1, TimeSpec spec2) throws RrdException {
134 if (spec1.type == TYPE_START || spec2.type == TYPE_END) {
135 throw new RrdException("Recursive time specifications not allowed");
136 }
137 spec1.context = spec2;
138 spec2.context = spec1;
139 return new Calendar[] {
140 spec1.getTime(),
141 spec2.getTime()
142 };
143 }
144
145 /**
146 * Use this static method to resolve relative time references and obtain the corresponding
147 * timestamps (seconds since epoch). Example:<p>
148 * <pre>
149 * TimeParser pStart = new TimeParser("now-1month"); // starting time
150 * TimeParser pEnd = new TimeParser("start+1week"); // ending time
151 * TimeSpec specStart = pStart.parse();
152 * TimeSpec specEnd = pEnd.parse();
153 * long[] ts = TimeSpec.getTimestamps(specStart, specEnd);
154 * </pre>
155 *
156 * @param spec1 Starting time specification
157 * @param spec2 Ending time specification
158 * @return array containing two timestamps (in seconds since epoch)
159 * @throws RrdException Thrown if relative time references cannot be resolved
160 */
161 public static long[] getTimestamps(TimeSpec spec1, TimeSpec spec2) throws RrdException {
162 Calendar[] gcs = getTimes(spec1, spec2);
163 return new long[] {
164 Util.getTimestamp(gcs[0]), Util.getTimestamp(gcs[1])
165 };
166 }
167 }
168