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