001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright � 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.timescale;
051:
052: import java.text.DateFormat;
053: import java.util.Calendar;
054: import java.util.Date;
055:
056: import com.projity.pm.time.HasStartAndEnd;
057: import com.projity.util.DateTime;
058:
059: public class CalendarUtil {
060: public static final long SECOND_ms = 1000;
061: public static final long MINUTE_ms = 60 * SECOND_ms;
062: public static final long HOUR_ms = 60 * MINUTE_ms;
063: public static final long DAY_ms = 24 * HOUR_ms;
064: public static final long WEEK_ms = DateTime.calendarInstance()
065: .getLeastMaximum(Calendar.DAY_OF_WEEK)
066: * DAY_ms;
067: public static final long MONTH_ms = DateTime.calendarInstance()
068: .getLeastMaximum(Calendar.DAY_OF_MONTH)
069: * DAY_ms;
070: public static final long YEAR_ms = DateTime.calendarInstance()
071: .getLeastMaximum(Calendar.DAY_OF_YEAR)
072: * DAY_ms;
073:
074: private CalendarUtil() {
075: }
076:
077: public static Date min(Date date, Date date1) {
078: return date.before(date1) ? date : date1;
079: }
080:
081: public static Date max(Date date, Date date1) {
082: return date.after(date1) ? date : date1;
083: }
084:
085: public static int compareEra(Calendar calendar, Calendar calendar1) {
086: if (calendar.getClass() != calendar1.getClass())
087: throw new IllegalArgumentException(
088: "Cannot compare calendars of dissimilar classes: "
089: + calendar + ", " + calendar1);
090: else
091: return calendar.get(Calendar.ERA)
092: - calendar1.get(Calendar.ERA);
093: }
094:
095: public static int compareYear(Calendar calendar, Calendar calendar1) {
096: int i = compareEra(calendar, calendar1);
097: if (i != 0)
098: return i;
099: else
100: return calendar.get(Calendar.YEAR)
101: - calendar1.get(Calendar.YEAR);
102: }
103:
104: public static int compareMonth(Calendar calendar, Calendar calendar1) {
105: int i = compareYear(calendar, calendar1);
106: if (i != 0)
107: return i;
108: else
109: return calendar.get(Calendar.MONTH)
110: - calendar1.get(Calendar.MONTH);
111: }
112:
113: public static int compareDay(Calendar calendar, Calendar calendar1) {
114: int i = compareYear(calendar, calendar1);
115: if (i != 0)
116: return i;
117: else
118: return calendar.get(Calendar.DAY_OF_YEAR)
119: - calendar1.get(Calendar.DAY_OF_YEAR);
120: }
121:
122: public static void secondFloor(Calendar calendar) {
123: calendar.set(Calendar.MILLISECOND, 0);
124: }
125:
126: public static void minuteFloor(Calendar calendar) {
127: secondFloor(calendar);
128: calendar.set(Calendar.SECOND, 0);
129: }
130:
131: public static void minuteFloor(Calendar calendar, int number) {
132: secondFloor(calendar);
133: calendar.set(Calendar.SECOND, 0);
134: if (number > 1) {
135: int minutes = calendar.get(Calendar.SECOND);
136: calendar.set(Calendar.SECOND, (minutes / number) * number);
137: }
138: }
139:
140: public static void hourFloor(Calendar calendar) {
141: minuteFloor(calendar);
142: calendar.set(Calendar.MINUTE, 0);
143: }
144:
145: public static void hourFloor(Calendar calendar, int number) {
146: minuteFloor(calendar);
147: calendar.set(Calendar.MINUTE, 0);
148: if (number > 1) {
149: int hours = calendar.get(Calendar.HOUR);
150: calendar.set(Calendar.HOUR, (hours / number) * number);
151: }
152: }
153:
154: public static void dayFloor(Calendar calendar) {
155: hourFloor(calendar);
156: calendar.set(Calendar.HOUR_OF_DAY, 0);
157: }
158:
159: public static void weekFloor(Calendar calendar) {
160: int i = calendar.get(Calendar.YEAR);
161: int k = calendar.get(Calendar.DAY_OF_YEAR);
162: int l = calendar.get(Calendar.DAY_OF_WEEK);
163: int i1 = calendar.getFirstDayOfWeek();
164: int j1 = l - i1;
165: if (j1 > 0)
166: k -= j1;
167: else if (j1 < 0)
168: k -= 7 + j1;
169: calendar.clear();
170: boolean flag = calendar.isLenient();
171: if (!flag)
172: calendar.setLenient(true);
173: calendar.set(Calendar.YEAR, i);
174: calendar.set(Calendar.DAY_OF_YEAR, k);
175: if (!flag) {
176: int j = calendar.get(Calendar.YEAR);
177: calendar.setLenient(false);
178: }
179: }
180:
181: public static void monthFloor(Calendar calendar) {
182: dayFloor(calendar);
183: calendar.set(Calendar.DAY_OF_MONTH, 1);
184: }
185:
186: public static void monthFloor(Calendar calendar, int number) { //number param for quarter and half
187: dayFloor(calendar);
188: calendar.set(Calendar.DAY_OF_MONTH, 1);
189: if (number > 1) {
190: int month = calendar.get(Calendar.MONTH);
191: calendar.set(Calendar.MONTH, (month / number) * number);
192: }
193: }
194:
195: public static void yearFloor(Calendar calendar) {
196: monthFloor(calendar);
197: calendar.set(Calendar.MONTH, 0);
198: }
199:
200: public static void floor(Calendar calendar, int field) {
201: floor(calendar, field, 1);
202: }
203:
204: public static void floor(Calendar calendar, int field, int number) {
205: switch (field) {
206: case Calendar.YEAR:
207: yearFloor(calendar);
208: break;
209: case Calendar.MONTH:
210: monthFloor(calendar, number);
211: break;
212: case Calendar.WEEK_OF_YEAR:
213: weekFloor(calendar);
214: break;
215: case Calendar.DAY_OF_WEEK:
216: dayFloor(calendar);
217: break;
218: case Calendar.DAY_OF_MONTH:
219: dayFloor(calendar);
220: break;
221: case Calendar.HOUR_OF_DAY:
222: hourFloor(calendar, number);
223: break;
224: case Calendar.MINUTE:
225: minuteFloor(calendar, number);
226: break;
227: case Calendar.SECOND:
228: secondFloor(calendar);
229: break;
230: }
231: }
232:
233: public static long getMinDuration(int field) {
234: switch (field) {
235: case Calendar.YEAR:
236: return YEAR_ms;
237: case Calendar.MONTH:
238: return MONTH_ms;
239: case Calendar.WEEK_OF_YEAR:
240: return WEEK_ms;
241: case Calendar.DAY_OF_WEEK:
242: return DAY_ms;
243: case Calendar.DAY_OF_MONTH:
244: return DAY_ms;
245: case Calendar.HOUR_OF_DAY:
246: return HOUR_ms;
247: case Calendar.MINUTE:
248: return MINUTE_ms;
249: case Calendar.SECOND:
250: return SECOND_ms;
251: }
252: return -1;
253:
254: }
255:
256: /**
257: * Don't use in loops. DateFormat and Date have to be reused
258: * @param t
259: * @return
260: */
261: public static String toString(long t) {
262: Calendar calendar = DateTime.calendarInstance();
263: calendar.setTimeInMillis(t);
264: return toString(calendar);
265: }
266:
267: public static String toString(Calendar calendar) {
268: DateFormat df = DateFormat.getDateTimeInstance();
269: return df.format(calendar.getTime());
270: }
271:
272: public static long toLongTime(double t) {
273: return Math.round(t / 1000) * 1000;
274: }
275:
276: public static long roundTime(double dt, Calendar tmp) {
277: long t = toLongTime(dt);
278: tmp.setTimeInMillis(t);
279: int sec = tmp.get(Calendar.SECOND);
280: return (sec > 30) ? t + (60 - sec) : t - sec;
281: }
282:
283: public static void roundTime(Calendar c) {
284: c.setTimeInMillis(roundTime(c.getTimeInMillis(), c));
285: }
286:
287: public static class DayIterator {
288: private Calendar calendar;
289: protected long end;
290:
291: public void setInterval(HasStartAndEnd interval) {
292: calendar = DateTime.calendarInstance();
293: calendar.setTimeInMillis(interval.getEnd());
294: dayFloor(calendar);
295: end = calendar.getTimeInMillis();
296: calendar.setTimeInMillis(interval.getStart());
297: dayFloor(calendar);
298: }
299:
300: public boolean hasMoreDays() {
301: return calendar.getTimeInMillis() <= end;
302: }
303:
304: public long nextDay() {
305: long current = calendar.getTimeInMillis();
306: calendar.add(Calendar.DATE, 1);
307: return current;
308: }
309: }
310:
311: }
|