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