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 */ 021package org.jdesktop.swingx.calendar; 022 023import java.util.Calendar; 024import 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 */ 039public 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}