1 15 package org.pentaho.util; 16 17 import java.util.Calendar ; 18 import java.util.Locale ; 19 import java.util.StringTokenizer ; 20 import java.text.DateFormat ; 21 import java.text.SimpleDateFormat ; 22 23 import org.pentaho.messages.util.LocaleHelper; 24 25 68 public class DateMath { 69 70 private static final char POSITION_END = 'E'; 71 72 private static final char POSITION_START = 'S'; 73 74 private static final char UNIT_YEAR = 'Y'; 75 76 private static final char UNIT_MONTH = 'M'; 77 78 private static final char UNIT_WEEK = 'W'; 79 80 private static final char UNIT_DAY = 'D'; 81 82 private static final char UNIT_HOUR = 'h'; 83 84 private static final char UNIT_MINUTE = 'm'; 85 86 private static final char UNIT_SECOND = 's'; 87 88 102 public static String claculateDateString(String expressionWithFormat) { 103 return calculateDateString(null, expressionWithFormat, null); 104 } 105 106 120 public static String calculateDateString(Calendar date, String expressionWithFormat) { 121 return calculateDateString(date, expressionWithFormat, null); 122 } 123 124 140 public static String calculateDateString(Calendar date, String expressionWithFormat, Locale locale) { 141 int index = expressionWithFormat.indexOf(';'); 142 String expression; 143 String pattern = null; 144 Calendar target = (date == null) ? Calendar.getInstance() : date; 145 DateFormat format; 146 Locale myLocale; 147 148 if (index >= 0) { 149 pattern = expressionWithFormat.substring(index + 1); 150 expression = expressionWithFormat.substring(0, index); 151 } else { 152 expression = expressionWithFormat; 153 } 154 155 target = calculateDate(date, expression); 156 157 myLocale = (locale == null) ? LocaleHelper.getLocale() : locale; 158 if (myLocale == null) { 159 myLocale = LocaleHelper.getDefaultLocale(); 160 } 161 162 if (pattern != null) { 163 format = new SimpleDateFormat (pattern, myLocale); 164 } else { 165 format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, myLocale); 166 } 167 168 return format.format(target.getTime()); 169 } 170 171 182 public static Calendar calculateDate(String expression) { 183 return calculateDate(null, expression); 184 } 185 186 199 public static Calendar calculateDate(Calendar date, String expression) { 200 StringTokenizer tok; 201 String myExpression; 202 Calendar target = date; 203 int index = expression.indexOf(';'); 204 205 if (index >= 0) { 206 myExpression = expression.substring(index + 1); 207 } else { 208 myExpression = expression; 209 } 210 211 tok = new StringTokenizer (myExpression, " \t;"); while (tok.hasMoreElements()) { 213 target = parseAndCalculateDate(target, (String ) tok.nextElement()); 214 } 215 216 return target; 217 } 218 219 231 private static Calendar parseAndCalculateDate(Calendar date, String expression) { 232 int index = expression.indexOf(':'); char operation = '+'; char unit = ' '; char position = ' '; int operand = 0; 237 Calendar result; 238 239 if (index >= 0) { 240 try { 241 String number = expression.substring(0, index); 242 243 operation = number.charAt(0); 244 if ((operation == '+') || (operation == '-')) { number = number.substring(1); 248 } else { 249 operation = '+'; 250 } 251 252 operand = Integer.parseInt(number); 253 254 index++; 255 unit = expression.charAt(index); 256 257 index++; 258 if (index < expression.length()) { 259 position = expression.charAt(index); 260 } 261 262 result = calculateDate(date, operation, operand, unit, position); 263 } catch (Exception ex) { 264 IllegalArgumentException err = new IllegalArgumentException (expression); 265 266 err.initCause(ex); 267 throw err; 268 } 269 } else { 270 throw new IllegalArgumentException (expression); 271 } 272 273 return result; 274 } 275 276 297 private static Calendar calculateDate(Calendar date, char operation, int operand, char unit, char position) { 298 Calendar target = (date == null) ? Calendar.getInstance() : date; 299 int calendarField = -1; 300 301 switch (unit) { 302 case UNIT_YEAR: 303 calendarField = Calendar.YEAR; 304 break; 305 case UNIT_MONTH: 306 calendarField = Calendar.MONTH; 307 break; 308 case UNIT_WEEK: 309 calendarField = Calendar.DAY_OF_YEAR; 310 operand = operand * 7; 311 break; 312 case UNIT_DAY: 313 calendarField = Calendar.DAY_OF_YEAR; 314 break; 315 case UNIT_HOUR: 316 calendarField = Calendar.HOUR_OF_DAY; 317 break; 318 case UNIT_MINUTE: 319 calendarField = Calendar.MINUTE; 320 break; 321 case UNIT_SECOND: 322 calendarField = Calendar.SECOND; 323 break; 324 325 default: 326 throw new IllegalArgumentException (); 327 } 328 329 if (operation == ' ') { 330 target.set(calendarField, operand); 331 } else if (operation == '+') { 332 target.add(calendarField, operand); 333 } else if (operation == '-') { 334 target.add(calendarField, -Math.abs(operand)); 335 } 336 337 if (unit == UNIT_YEAR) { 338 if (position == POSITION_START) { 339 target.set(Calendar.DAY_OF_YEAR, 1); 340 setTimeToStart(target); 341 } else if (position == POSITION_END) { 342 target.set(Calendar.DAY_OF_YEAR, target.getActualMaximum(Calendar.DAY_OF_YEAR)); 343 setTimeToEnd(target); 344 } 345 } else if (unit == UNIT_MONTH) { 346 if (position == POSITION_START) { 347 target.set(Calendar.DAY_OF_MONTH, 1); 348 setTimeToStart(target); 349 } else if (position == POSITION_END) { 350 target.set(Calendar.DAY_OF_MONTH, target.getActualMaximum(Calendar.DAY_OF_MONTH)); 351 setTimeToEnd(target); 352 } 353 } else if (unit == UNIT_WEEK) { 354 int firstDOW = target.getFirstDayOfWeek(); 355 int dayOfWeek = target.get(Calendar.DAY_OF_WEEK); int dayOffset = 0; 358 359 if (position == POSITION_START) { 360 if (dayOfWeek > firstDOW) { 361 362 dayOffset = firstDOW - dayOfWeek; 365 } else if (dayOfWeek < firstDOW) { 366 367 dayOffset = -7 + (firstDOW - dayOfWeek); 372 } 373 374 setTimeToStart(target); 375 } else if (position == POSITION_END) { 376 int lastDOW; 377 378 if (firstDOW == Calendar.SUNDAY) { 379 lastDOW = Calendar.SATURDAY; 380 } else { 381 lastDOW = firstDOW - 1; 382 } 383 384 if (dayOfWeek < lastDOW) { 385 386 dayOffset = lastDOW - dayOfWeek; 389 } else if (dayOfWeek > lastDOW) { 390 391 dayOffset = 7 - (dayOfWeek - lastDOW); 394 } 395 396 setTimeToEnd(target); 397 } 398 399 if (dayOffset != 0) { 400 target.add(Calendar.DAY_OF_YEAR, dayOffset); 401 } 402 } else if (unit == UNIT_DAY) { 403 if (position == POSITION_START) { 404 setTimeToStart(target); 405 } else if (position == POSITION_END) { 406 setTimeToEnd(target); 407 } 408 } else if (unit == UNIT_HOUR) { 409 if (position == POSITION_START) { 410 target.set(Calendar.MINUTE, 0); 411 target.set(Calendar.SECOND, 0); 412 target.set(Calendar.MILLISECOND, 0); 413 } else if (position == POSITION_END) { 414 target.set(Calendar.MINUTE, 59); 415 target.set(Calendar.SECOND, 59); 416 target.set(Calendar.MILLISECOND, 999); 417 } 418 } else if (unit == UNIT_MINUTE) { 419 if (position == POSITION_START) { 420 target.set(Calendar.SECOND, 0); 421 target.set(Calendar.MILLISECOND, 0); 422 } else if (position == POSITION_END) { 423 target.set(Calendar.SECOND, 59); 424 target.set(Calendar.MILLISECOND, 999); 425 } 426 } else if (unit == UNIT_SECOND) { 427 if (position == POSITION_START) { 428 target.set(Calendar.MILLISECOND, 0); 429 } else if (position == POSITION_END) { 430 target.set(Calendar.MILLISECOND, 999); 431 } 432 } 433 434 target.getTimeInMillis(); 436 return target; 437 } 438 439 445 private static void setTimeToStart(Calendar target) { 446 target.set(Calendar.MILLISECOND, 0); 447 target.set(Calendar.SECOND, 0); 448 target.set(Calendar.MINUTE, 0); 449 target.set(Calendar.HOUR_OF_DAY, 0); 450 } 451 452 458 private static void setTimeToEnd(Calendar target) { 459 target.set(Calendar.MILLISECOND, 999); 460 target.set(Calendar.SECOND, 59); 461 target.set(Calendar.MINUTE, 59); 462 target.set(Calendar.HOUR_OF_DAY, 23); 463 } 464 } 465 | Popular Tags |