001 /*
002 * $Id: CalendarUtils.java 3100 2008-10-14 22:33:10Z rah003 $
003 *
004 * Copyright 2007 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021 package org.jdesktop.swingx.calendar;
022
023 import java.util.Calendar;
024 import java.util.Date;
025
026 /**
027 * Calendar manipulation.
028 *
029 * PENDING: replace by something tested - as is c&p'ed dateUtils
030 * to work on a calendar instead of using long
031 *
032 * @author Jeanette Winzenburg
033 */
034 public class CalendarUtils {
035
036 // Constants used internally; unit is milliseconds
037 @SuppressWarnings("unused")
038 public static final int ONE_MINUTE = 60*1000;
039 @SuppressWarnings("unused")
040 public static final int ONE_HOUR = 60*ONE_MINUTE;
041 @SuppressWarnings("unused")
042 public static final int THREE_HOURS = 3 * ONE_HOUR;
043 @SuppressWarnings("unused")
044 public static final int ONE_DAY = 24*ONE_HOUR;
045
046 /**
047 * Adjusts the Calendar to the end of the day of the last day in DST in the
048 * current year or unchanged if not using DST. Returns the calendar's date or null, if not
049 * using DST.<p>
050 *
051 *
052 * @param calendar the calendar to adjust
053 * @return the end of day of the last day in DST, or null if not using DST.
054 */
055 public static Date getEndOfDST(Calendar calendar) {
056 if (!calendar.getTimeZone().useDaylightTime()) return null;
057 long old = calendar.getTimeInMillis();
058 calendar.set(Calendar.MONTH, Calendar.DECEMBER);
059 endOfMonth(calendar);
060 startOfDay(calendar);
061 for (int i = 0; i < 366; i++) {
062 calendar.add(Calendar.DATE, -1);
063 if (calendar.getTimeZone().inDaylightTime(calendar.getTime())) {
064 endOfDay(calendar);
065 return calendar.getTime();
066 }
067 }
068 calendar.setTimeInMillis(old);
069 return null;
070 }
071
072
073 /**
074 * Adjusts the Calendar to the end of the day of the first day in DST in the
075 * current year or unchanged if not using DST. Returns the calendar's date or null, if not
076 * using DST.<p>
077 *
078 * Note: the start of the day of the first day in DST is ill-defined!
079 *
080 * @param calendar the calendar to adjust
081 * @return the start of day of the first day in DST, or null if not using DST.
082 */
083 public static Date getStartOfDST(Calendar calendar) {
084 if (!calendar.getTimeZone().useDaylightTime()) return null;
085 long old = calendar.getTimeInMillis();
086 calendar.set(Calendar.MONTH, Calendar.JANUARY);
087 startOfMonth(calendar);
088 endOfDay(calendar);
089 for (int i = 0; i < 366; i++) {
090 calendar.add(Calendar.DATE, 1);
091 if (calendar.getTimeZone().inDaylightTime(calendar.getTime())) {
092 endOfDay(calendar);
093 return calendar.getTime();
094 }
095 }
096 calendar.setTimeInMillis(old);
097 return null;
098 }
099 /**
100 * Returns a boolean indicating if the given calendar represents the
101 * start of a day (in the calendar's time zone). The calendar is unchanged.
102 *
103 * @param calendar the calendar to check.
104 *
105 * @return true if the calendar's time is the start of the day,
106 * false otherwise.
107 */
108 public static boolean isStartOfDay(Calendar calendar) {
109 Calendar temp = (Calendar) calendar.clone();
110 temp.add(Calendar.MILLISECOND, -1);
111 return temp.get(Calendar.DATE) != calendar.get(Calendar.DATE);
112 }
113
114 /**
115 * Returns a boolean indicating if the given calendar represents the
116 * end of a day (in the calendar's time zone). The calendar is unchanged.
117 *
118 * @param calendar the calendar to check.
119 *
120 * @return true if the calendar's time is the end of the day,
121 * false otherwise.
122 */
123 public static boolean isEndOfDay(Calendar calendar) {
124 Calendar temp = (Calendar) calendar.clone();
125 temp.add(Calendar.MILLISECOND, 1);
126 return temp.get(Calendar.DATE) != calendar.get(Calendar.DATE);
127 }
128
129 /**
130 * Returns a boolean indicating if the given calendar represents the
131 * start of a month (in the calendar's time zone). Returns true, if the time is
132 * the start of the first day of the month, false otherwise. The calendar is unchanged.
133 *
134 * @param calendar the calendar to check.
135 *
136 * @return true if the calendar's time is the start of the first day of the month,
137 * false otherwise.
138 */
139 public static boolean isStartOfMonth(Calendar calendar) {
140 Calendar temp = (Calendar) calendar.clone();
141 temp.add(Calendar.MILLISECOND, -1);
142 return temp.get(Calendar.MONTH) != calendar.get(Calendar.MONTH);
143 }
144
145 /**
146 * Returns a boolean indicating if the given calendar represents the
147 * end of a month (in the calendar's time zone). Returns true, if the time is
148 * the end of the last day of the month, false otherwise. The calendar is unchanged.
149 *
150 * @param calendar the calendar to check.
151 *
152 * @return true if the calendar's time is the end of the last day of the month,
153 * false otherwise.
154 */
155 public static boolean isEndOfMonth(Calendar calendar) {
156 Calendar temp = (Calendar) calendar.clone();
157 temp.add(Calendar.MILLISECOND, 1);
158 return temp.get(Calendar.MONTH) != calendar.get(Calendar.MONTH);
159 }
160
161 /**
162 * Returns a boolean indicating if the given calendar represents the
163 * start of a month (in the calendar's time zone). Returns true, if the time is
164 * the start of the first day of the month, false otherwise. The calendar is unchanged.
165 *
166 * @param calendar the calendar to check.
167 *
168 * @return true if the calendar's time is the start of the first day of the month,
169 * false otherwise.
170 */
171 public static boolean isStartOfWeek(Calendar calendar) {
172 Calendar temp = (Calendar) calendar.clone();
173 temp.add(Calendar.MILLISECOND, -1);
174 return temp.get(Calendar.WEEK_OF_YEAR) != calendar.get(Calendar.WEEK_OF_YEAR);
175 }
176
177 /**
178 * Returns a boolean indicating if the given calendar represents the
179 * end of a week (in the calendar's time zone). Returns true, if the time is
180 * the end of the last day of the week, false otherwise. The calendar is unchanged.
181 *
182 * @param calendar the calendar to check.
183 *
184 * @return true if the calendar's time is the end of the last day of the week,
185 * false otherwise.
186 */
187 public static boolean isEndOfWeek(Calendar calendar) {
188 Calendar temp = (Calendar) calendar.clone();
189 temp.add(Calendar.MILLISECOND, 1);
190 return temp.get(Calendar.WEEK_OF_YEAR) != calendar.get(Calendar.WEEK_OF_YEAR);
191 }
192
193 /**
194 * Adjusts the calendar to the start of the current week.
195 * That is, first day of the week with all time fields cleared.
196 * @param calendar the calendar to adjust.
197 */
198 public static void startOfWeek(Calendar calendar) {
199 calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
200 startOfDay(calendar);
201 }
202
203 /**
204 * Adjusts the calendar to the end of the current week.
205 * That is, last day of the week with all time fields at max.
206 * @param calendar the calendar to adjust.
207 */
208 public static void endOfWeek(Calendar calendar) {
209 startOfWeek(calendar);
210 calendar.add(Calendar.DATE, 7);
211 calendar.add(Calendar.MILLISECOND, -1);
212 }
213
214 /**
215 * Adjusts the calendar to the end of the current week.
216 * That is, last day of the week with all time fields at max.
217 * The Date of the adjusted Calendar is
218 * returned.
219 *
220 * @param calendar calendar to adjust.
221 * @param date the Date to use.
222 * @return the end of the week of the given date
223 */
224 public static Date endOfWeek(Calendar calendar, Date date) {
225 calendar.setTime(date);
226 endOfWeek(calendar);
227 return calendar.getTime();
228 }
229
230 /**
231 * Adjusts the calendar to the start of the current week.
232 * That is, last day of the week with all time fields at max.
233 * The Date of the adjusted Calendar is
234 * returned.
235 *
236 * @param calendar calendar to adjust.
237 * @param date the Date to use.
238 * @return the start of the week of the given date
239 */
240 public static Date startOfWeek(Calendar calendar, Date date) {
241 calendar.setTime(date);
242 startOfWeek(calendar);
243 return calendar.getTime();
244 }
245
246 /**
247 * Adjusts the calendar to the start of the current month.
248 * That is, first day of the month with all time fields cleared.
249 * @param calendar
250 */
251 public static void startOfMonth(Calendar calendar) {
252 calendar.set(Calendar.DAY_OF_MONTH, 1);
253 startOfDay(calendar);
254 }
255
256 /**
257 * Adjusts the calendar to the end of the current month.
258 * That is the last day of the month with all time-fields
259 * at max.
260 *
261 * @param calendar
262 */
263 public static void endOfMonth(Calendar calendar) {
264 // start of next month
265 calendar.add(Calendar.MONTH, 1);
266 startOfMonth(calendar);
267 // one millisecond back
268 calendar.add(Calendar.MILLISECOND, -1);
269 }
270
271
272
273 /**
274 * Adjust the given calendar to the first millisecond of the given date.
275 * that is all time fields cleared. The Date of the adjusted Calendar is
276 * returned.
277 *
278 * @param calendar calendar to adjust.
279 * @param date the Date to use.
280 * @return the start of the day of the given date
281 */
282 public static Date startOfDay(Calendar calendar, Date date) {
283 calendar.setTime(date);
284 startOfDay(calendar);
285 return calendar.getTime();
286 }
287
288
289 /**
290 * Adjust the given calendar to the last millisecond of the given date.
291 * that is all time fields cleared. The Date of the adjusted Calendar is
292 * returned.
293 *
294 * @param calendar calendar to adjust.
295 * @param date the Date to use.
296 * @return the end of the day of the given date
297 */
298 public static Date endOfDay(Calendar calendar, Date date) {
299 calendar.setTime(date);
300 endOfDay(calendar);
301 return calendar.getTime();
302 }
303
304
305 /**
306 * Adjust the given calendar to the first millisecond of the current day.
307 * that is all time fields cleared.
308 *
309 * @param calendar calendar to adjust.
310 */
311 public static void startOfDay(Calendar calendar) {
312 calendar.set(Calendar.HOUR_OF_DAY, 0);
313 calendar.set(Calendar.MILLISECOND, 0);
314 calendar.set(Calendar.SECOND, 0);
315 calendar.set(Calendar.MINUTE, 0);
316 }
317 /**
318 * Adjust the given calendar to the last millisecond of the specified date.
319 *
320 * @param calendar calendar to adjust.
321 */
322 public static void endOfDay(Calendar calendar) {
323 calendar.add(Calendar.DATE, 1);
324 startOfDay(calendar);
325 calendar.add(Calendar.MILLISECOND, -1);
326 }
327
328 /**
329 * Checks the given dates for being equal.
330 *
331 * @param current one of the dates to compare
332 * @param date the otherr of the dates to compare
333 * @return true if the two given dates both are null or both are not null and equal,
334 * false otherwise.
335 */
336 public static boolean areEqual(Date current, Date date) {
337 if ((date == null) && (current == null)) {
338 return true;
339 }
340 if (date != null) {
341 return date.equals(current);
342 }
343 return false;
344 }
345
346 /**
347 * Returns a boolean indicating whether the given Date is the same day as
348 * the day in the calendar. Calendar and date are unchanged by the check.
349 *
350 * @param today the Calendar representing a date, must not be null.
351 * @param now the date to compare to, must not be null
352 * @return true if the calendar and date represent the same day in the
353 * given calendar.
354 */
355 public static boolean isSameDay(Calendar today, Date now) {
356 Calendar temp = (Calendar) today.clone();
357 startOfDay(temp);
358 Date start = temp.getTime();
359 temp.setTime(now);
360 startOfDay(temp);
361 return start.equals(temp.getTime());
362 }
363
364
365 }