001 /*
002 * $Id: DateUtils.java,v 1.4 2005/10/10 18:02:45 rbair Exp $
003 *
004 * Copyright 2004 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 * @author Scott Violet
028 * @version $Revision: 1.4 $
029 */
030 public class DateUtils {
031 private static Calendar CALENDAR = Calendar.getInstance();
032
033 /**
034 * Returns the last millisecond of the specified date.
035 *
036 * @param date Date to calculate end of day from
037 * @return Last millisecond of <code>date</code>
038 */
039 public static Date endOfDay(Date date) {
040 Calendar calendar = CALENDAR;
041 synchronized(calendar) {
042 calendar.setTime(date);
043 calendar.set(Calendar.HOUR_OF_DAY, 23);
044 calendar.set(Calendar.MILLISECOND, 999);
045 calendar.set(Calendar.SECOND, 59);
046 calendar.set(Calendar.MINUTE, 59);
047 return calendar.getTime();
048 }
049 }
050
051
052 /**
053 * Returns a new Date with the hours, milliseconds, seconds and minutes
054 * set to 0.
055 *
056 * @param date Date used in calculating start of day
057 * @return Start of <code>date</code>
058 */
059 public static Date startOfDay(Date date) {
060 Calendar calendar = CALENDAR;
061 synchronized(calendar) {
062 calendar.setTime(date);
063 calendar.set(Calendar.HOUR_OF_DAY, 0);
064 calendar.set(Calendar.MILLISECOND, 0);
065 calendar.set(Calendar.SECOND, 0);
066 calendar.set(Calendar.MINUTE, 0);
067 return calendar.getTime();
068 }
069 }
070
071 /**
072 * Returns day in millis with the hours, milliseconds, seconds and minutes
073 * set to 0.
074 *
075 * @param date long used in calculating start of day
076 * @return Start of <code>date</code>
077 */
078 public static long startOfDayInMillis(long date) {
079 Calendar calendar = CALENDAR;
080 synchronized(calendar) {
081 calendar.setTimeInMillis(date);
082 calendar.set(Calendar.HOUR_OF_DAY, 0);
083 calendar.set(Calendar.MILLISECOND, 0);
084 calendar.set(Calendar.SECOND, 0);
085 calendar.set(Calendar.MINUTE, 0);
086 return calendar.getTimeInMillis();
087 }
088 }
089
090 /**
091 * Returns the last millisecond of the specified date.
092 *
093 * @param date long to calculate end of day from
094 * @return Last millisecond of <code>date</code>
095 */
096 public static long endOfDayInMillis(long date) {
097 Calendar calendar = CALENDAR;
098 synchronized(calendar) {
099 calendar.setTimeInMillis(date);
100 calendar.set(Calendar.HOUR_OF_DAY, 23);
101 calendar.set(Calendar.MILLISECOND, 999);
102 calendar.set(Calendar.SECOND, 59);
103 calendar.set(Calendar.MINUTE, 59);
104 return calendar.getTimeInMillis();
105 }
106 }
107
108
109 /**
110 * Returns the day after <code>date</code>.
111 *
112 * @param date Date used in calculating next day
113 * @return Day after <code>date</code>.
114 */
115 public static Date nextDay(Date date) {
116 return new Date(addDays(date.getTime(), 1));
117 }
118
119 /**
120 * Adds <code>amount</code> days to <code>time</code> and returns
121 * the resulting time.
122 *
123 * @param time Base time
124 * @param amount Amount of increment.
125 *
126 * @return the <var>time</var> + <var>amount</var> days
127 */
128 public static long addDays(long time, int amount) {
129 Calendar calendar = CALENDAR;
130 synchronized(calendar) {
131 calendar.setTimeInMillis(time);
132 calendar.add(Calendar.DAY_OF_MONTH, amount);
133 return calendar.getTimeInMillis();
134 }
135 }
136
137 /**
138 * Returns the day after <code>date</code>.
139 *
140 * @param date Date used in calculating next day
141 * @return Day after <code>date</code>.
142 */
143 public static long nextDay(long date) {
144 return addDays(date, 1);
145 }
146
147 /**
148 * Returns the week after <code>date</code>.
149 *
150 * @param date Date used in calculating next week
151 * @return week after <code>date</code>.
152 */
153 public static long nextWeek(long date) {
154 return addDays(date, 7);
155 }
156
157
158 /**
159 * Returns the number of days difference between <code>t1</code> and
160 * <code>t2</code>.
161 *
162 * @param t1 Time 1
163 * @param t2 Time 2
164 * @param checkOverflow indicates whether to check for overflow
165 * @return Number of days between <code>start</code> and <code>end</code>
166 */
167 public static int getDaysDiff(long t1, long t2, boolean checkOverflow) {
168 if (t1 > t2) {
169 long tmp = t1;
170 t1 = t2;
171 t2 = tmp;
172 }
173 Calendar calendar = CALENDAR;
174 synchronized(calendar) {
175 calendar.setTimeInMillis(t1);
176 int delta = 0;
177 while (calendar.getTimeInMillis() < t2) {
178 calendar.add(Calendar.DAY_OF_MONTH, 1);
179 delta++;
180 }
181 if (checkOverflow && (calendar.getTimeInMillis() > t2)) {
182 delta--;
183 }
184 return delta;
185 }
186 }
187
188 /**
189 * Returns the number of days difference between <code>t1</code> and
190 * <code>t2</code>.
191 *
192 * @param t1 Time 1
193 * @param t2 Time 2
194 * @return Number of days between <code>start</code> and <code>end</code>
195 */
196 public static int getDaysDiff(long t1, long t2) {
197 return getDaysDiff(t1, t2, true);
198 }
199
200 /**
201 * Check, whether the date passed in is the first day of the year.
202 *
203 * @param date date to check in millis
204 * @return <code>true</code> if <var>date</var> corresponds to the first
205 * day of a year
206 * @see Date#getTime()
207 */
208 public static boolean isFirstOfYear(long date) {
209 boolean ret = false;
210 Calendar calendar = CALENDAR;
211 synchronized(calendar) {
212 calendar.setTimeInMillis(date);
213 int currentYear = calendar.get(Calendar.YEAR);
214 // Check yesterday
215 calendar.add(Calendar.DATE,-1);
216 int yesterdayYear = calendar.get(Calendar.YEAR);
217 ret = (currentYear != yesterdayYear);
218 }
219 return ret;
220 }
221
222 /**
223 * Check, whether the date passed in is the first day of the month.
224 *
225 * @param date date to check in millis
226 * @return <code>true</code> if <var>date</var> corresponds to the first
227 * day of a month
228 * @see Date#getTime()
229 */
230 public static boolean isFirstOfMonth(long date) {
231 boolean ret = false;
232 Calendar calendar = CALENDAR;
233 synchronized(calendar) {
234 calendar.setTimeInMillis(date);
235 int currentMonth = calendar.get(Calendar.MONTH);
236 // Check yesterday
237 calendar.add(Calendar.DATE,-1);
238 int yesterdayMonth = calendar.get(Calendar.MONTH);
239 ret = (currentMonth != yesterdayMonth);
240 }
241 return ret;
242 }
243
244
245 /**
246 * Returns the day before <code>date</code>.
247 *
248 * @param date Date used in calculating previous day
249 * @return Day before <code>date</code>.
250 */
251 public static long previousDay(long date) {
252 return addDays(date, -1);
253 }
254
255 /**
256 * Returns the week before <code>date</code>.
257 *
258 * @param date Date used in calculating previous week
259 * @return week before <code>date</code>.
260 */
261 public static long previousWeek(long date) {
262 return addDays(date, -7);
263 }
264
265
266 /**
267 * Returns the first day before <code>date</code> that has the
268 * day of week matching <code>startOfWeek</code>. For example, if you
269 * want to find the previous monday relative to <code>date</code> you
270 * would call <code>getPreviousDay(date, Calendar.MONDAY)</code>.
271 *
272 * @param date Base date
273 * @param startOfWeek Calendar constant correspoding to start of week.
274 * @return start of week, return value will have 0 hours, 0 minutes,
275 * 0 seconds and 0 ms.
276 *
277 */
278 public static long getPreviousDay(long date, int startOfWeek) {
279 return getDay(date, startOfWeek, -1);
280 }
281
282 /**
283 * Returns the first day after <code>date</code> that has the
284 * day of week matching <code>startOfWeek</code>. For example, if you
285 * want to find the next monday relative to <code>date</code> you
286 * would call <code>getPreviousDay(date, Calendar.MONDAY)</code>.
287 *
288 * @param date Base date
289 * @param startOfWeek Calendar constant correspoding to start of week.
290 * @return start of week, return value will have 0 hours, 0 minutes,
291 * 0 seconds and 0 ms.
292 *
293 */
294 public static long getNextDay(long date, int startOfWeek) {
295 return getDay(date, startOfWeek, 1);
296 }
297
298 private static long getDay(long date, int startOfWeek, int increment) {
299 Calendar calendar = CALENDAR;
300 synchronized(calendar) {
301 calendar.setTimeInMillis(date);
302 int day = calendar.get(Calendar.DAY_OF_WEEK);
303 // Normalize the view starting date to a week starting day
304 while (day != startOfWeek) {
305 calendar.add(Calendar.DATE, increment);
306 day = calendar.get(Calendar.DAY_OF_WEEK);
307 }
308 return startOfDayInMillis(calendar.getTimeInMillis());
309 }
310 }
311
312 /**
313 * Returns the previous month.
314 *
315 * @param date Base date
316 * @return previous month
317 */
318 public static long getPreviousMonth(long date) {
319 return incrementMonth(date, -1);
320 }
321
322 /**
323 * Returns the next month.
324 *
325 * @param date Base date
326 * @return next month
327 */
328 public static long getNextMonth(long date) {
329 return incrementMonth(date, 1);
330 }
331
332 private static long incrementMonth(long date, int increment) {
333 Calendar calendar = CALENDAR;
334 synchronized(calendar) {
335 calendar.setTimeInMillis(date);
336 calendar.add(Calendar.MONTH, increment);
337 return calendar.getTimeInMillis();
338 }
339 }
340
341 /**
342 * Returns the date corresponding to the start of the month.
343 *
344 * @param date Base date
345 * @return Start of month.
346 */
347 public static long getStartOfMonth(long date) {
348 return getMonth(date, -1);
349 }
350
351 /**
352 * Returns the date corresponding to the end of the month.
353 *
354 * @param date Base date
355 * @return End of month.
356 */
357 public static long getEndOfMonth(long date) {
358 return getMonth(date, 1);
359 }
360
361 private static long getMonth(long date, int increment) {
362 long result;
363 Calendar calendar = CALENDAR;
364 synchronized(calendar) {
365 calendar.setTimeInMillis(date);
366 if (increment == -1) {
367 calendar.set(Calendar.DAY_OF_MONTH, 1);
368 result = startOfDayInMillis(calendar.getTimeInMillis());
369 } else {
370 calendar.add(Calendar.MONTH, 1);
371 calendar.set(Calendar.DAY_OF_MONTH, 1);
372 calendar.set(Calendar.HOUR_OF_DAY, 0);
373 calendar.set(Calendar.MILLISECOND, 0);
374 calendar.set(Calendar.SECOND, 0);
375 calendar.set(Calendar.MINUTE, 0);
376 calendar.add(Calendar.MILLISECOND, -1);
377 result = calendar.getTimeInMillis();
378 }
379 }
380 return result;
381 }
382
383 /**
384 * Returns the day of the week.
385 *
386 * @param date date
387 * @return day of week.
388 */
389 public static int getDayOfWeek(long date) {
390 Calendar calendar = CALENDAR;
391 synchronized(calendar) {
392 calendar.setTimeInMillis(date);
393 return (calendar.get(Calendar.DAY_OF_WEEK));
394 }
395 }
396 }