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 }