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 }