1 /* ============================================================
2 * JRobin : Pure java implementation of RRDTool's functionality
3 * ============================================================
4 *
5 * Project Info: http://www.jrobin.org
6 * Project Lead: Sasa Markovic (saxon@jrobin.org);
7 *
8 * (C) Copyright 2003-2005, by Sasa Markovic.
9 *
10 * Developers: Sasa Markovic (saxon@jrobin.org)
11 *
12 *
13 * This library is free software; you can redistribute it and/or modify it under the terms
14 * of the GNU Lesser General Public License as published by the Free Software Foundation;
15 * either version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 * See the GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License along with this
22 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23 * Boston, MA 02111-1307, USA.
24 */
25
26 package org.jrobin.core.timespec;
27
28 import org.jrobin.core.RrdException;
29 import org.jrobin.core.Util;
30
31 import java.util.Calendar;
32 import java.util.Date;
33 import java.util.GregorianCalendar;
34
35 /**
36 * Simple class to represent time obtained by parsing at-style date specification (described
37 * in detail on the rrdfetch man page. See javadoc for {@link org.jrobin.core.timespec.TimeParser}
38 * for more information.
39 */
40 public class TimeSpec {
41 static final int TYPE_ABSOLUTE = 0;
42 static final int TYPE_START = 1;
43 static final int TYPE_END = 2;
44
45 int type = TYPE_ABSOLUTE;
46 int year, month, day, hour, min, sec;
47 int wday;
48 int dyear, dmonth, dday, dhour, dmin, dsec;
49
50 String dateString;
51
52 TimeSpec context;
53
54 TimeSpec(String dateString) {
55 this.dateString = dateString;
56 }
57
58 void localtime(long timestamp) {
59 GregorianCalendar date = new GregorianCalendar();
60 date.setTime(new Date(timestamp * 1000L));
61 year = date.get(Calendar.YEAR) - 1900;
62 month = date.get(Calendar.MONTH);
63 day = date.get(Calendar.DAY_OF_MONTH);
64 hour = date.get(Calendar.HOUR_OF_DAY);
65 min = date.get(Calendar.MINUTE);
66 sec = date.get(Calendar.SECOND);
67 wday = date.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
68 }
69
70 GregorianCalendar getTime() throws RrdException {
71 GregorianCalendar gc;
72 // absoulte time, this is easy
73 if (type == TYPE_ABSOLUTE) {
74 gc = new GregorianCalendar(year + 1900, month, day, hour, min, sec);
75 }
76 // relative time, we need a context to evaluate it
77 else if (context != null && context.type == TYPE_ABSOLUTE) {
78 gc = context.getTime();
79 }
80 // how would I guess what time it was?
81 else {
82 throw new RrdException("Relative times like '" +
83 dateString + "' require proper absolute context to be evaluated");
84 }
85 gc.add(Calendar.YEAR, dyear);
86 gc.add(Calendar.MONTH, dmonth);
87 gc.add(Calendar.DAY_OF_MONTH, dday);
88 gc.add(Calendar.HOUR_OF_DAY, dhour);
89 gc.add(Calendar.MINUTE, dmin);
90 gc.add(Calendar.SECOND, dsec);
91 return gc;
92 }
93
94 /**
95 * Returns the corresponding timestamp (seconds since Epoch). Example:<p>
96 * <pre>
97 * TimeParser p = new TimeParser("now-1day");
98 * TimeSpec ts = p.parse();
99 * 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
169