1 21 22 package org.opensubsystems.core.util; 23 24 import java.sql.Timestamp ; 25 import java.text.DateFormat ; 26 import java.text.ParseException ; 27 import java.text.SimpleDateFormat ; 28 import java.util.Calendar ; 29 import java.util.Date ; 30 import java.util.GregorianCalendar ; 31 32 import org.opensubsystems.core.error.OSSInvalidDataException; 33 34 42 public final class DateUtils 43 { 44 46 49 public static final long ONE_SECOND = 1000L; 50 51 54 public static final long ONE_MINUTE = ONE_SECOND * 60L; 55 56 59 public static final long ONE_HOUR = ONE_MINUTE * 60L; 60 61 64 public static final long ONE_DAY = ONE_HOUR * 24L; 65 66 70 public static final char NANO_SEPARATOR = ':'; 71 72 75 public static final int TIMING_NEVER = 0; 76 77 80 public static final int TIMING_MINUTES = 1; 81 82 85 public static final int TIMING_HOURS = 2; 86 87 90 public static final int TIMING_DAYS = 3; 91 92 95 public static final int TIMING_WEEKS = 4; 96 97 100 public static final int TIMING_MONTHS = 5; 101 102 105 public static final int TIMING_YEARS = 6; 106 107 110 public static final int TIMING_NONE = 7; 111 112 115 public static final String CURRENT_DATE_CODE = "now"; 116 117 120 public static final char YEAR_CODE = 'y'; 121 122 125 public static final char MONTH_CODE = 'M'; 126 127 130 public static final char WEEK_CODE = 'w'; 131 132 135 public static final char DAY_CODE = 'd'; 136 137 140 public static final char HOUR_CODE = 'h'; 141 142 145 public static final char MINUTE_CODE = 'm'; 146 147 150 public static final char SECOND_CODE = 's'; 151 152 155 public static final int DATE_TYPE_DATE = 1; 156 157 160 public static final int DATE_TYPE_TIME = 2; 161 162 165 public static final int DATE_TYPE_DATETIME = 3; 166 167 169 216 218 221 public static final SimpleDateFormat DATE_FORMAT 222 = (SimpleDateFormat ) DateFormat.getDateInstance(DateFormat.SHORT); 223 224 227 public static final SimpleDateFormat TIME_FORMAT 228 = (SimpleDateFormat ) DateFormat.getTimeInstance(DateFormat.MEDIUM); 229 230 233 public static final SimpleDateFormat DATETIME_FORMAT 234 = (SimpleDateFormat ) DateFormat.getDateTimeInstance(DateFormat.SHORT, 235 DateFormat.MEDIUM); 236 237 241 public static final SimpleDateFormat DATE_STORE_FORMAT 242 = new SimpleDateFormat ("MM/dd/yyyy"); 243 244 248 public static final SimpleDateFormat TIME_STORE_FORMAT 249 = new SimpleDateFormat ("HH:mm:ss"); 250 251 255 public static final SimpleDateFormat DATETIME_STORE_FORMAT 256 = new SimpleDateFormat ("MM/dd/yyyy HH:mm:ss"); 257 258 259 262 public static final SimpleDateFormat DATE_SQL_FORMAT 263 = new SimpleDateFormat ("yyyy-MM-dd 00:00:00"); 264 265 268 public static final SimpleDateFormat TIME_SQL_FORMAT 269 = new SimpleDateFormat ("1970-01-01 HH:mm:ss"); 270 271 274 public static final SimpleDateFormat DATETIME_SQL_FORMAT 275 = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 276 277 279 282 private DateUtils( 283 ) 284 { 285 } 287 288 290 298 public static boolean dateEquals( 299 Date dtFirst, 300 Date dtSecond 301 ) 302 { 303 boolean bReturn = false; 304 305 bReturn = (dtFirst == dtSecond); 307 if (!bReturn) 308 { 309 if (dtFirst == null) 310 { 311 bReturn = (dtSecond == null); 313 } 314 else 315 { 316 if (dtSecond != null) 317 { 318 Calendar compCalendar; 319 int iEra; 320 int iYear; 321 int iMonth; 322 int iDay; 323 324 compCalendar = Calendar.getInstance(); 325 compCalendar.setTime(dtFirst); 326 iEra = compCalendar.get(Calendar.ERA); 327 iYear = compCalendar.get(Calendar.YEAR); 328 iMonth = compCalendar.get(Calendar.MONTH); 329 iDay = compCalendar.get(Calendar.DATE); 330 compCalendar.setTime(dtSecond); 331 332 bReturn = ((iEra == compCalendar.get(Calendar.ERA)) 333 && (iYear == compCalendar.get(Calendar.YEAR)) 334 && (iMonth == compCalendar.get(Calendar.MONTH)) 335 && (iDay == compCalendar.get(Calendar.DATE))); 336 } 337 } 338 } 339 340 return bReturn; 341 } 342 343 352 public static boolean timeEquals( 353 Date dtFirst, 354 Date dtSecond, 355 boolean bIgnoreMilliseconds 356 ) 357 { 358 boolean bReturn = false; 359 360 bReturn = (dtFirst == dtSecond); 362 if (!bReturn) 363 { 364 if (dtFirst == null) 365 { 366 bReturn = (dtSecond == null); 368 } 369 else 370 { 371 if (dtSecond != null) 372 { 373 Calendar compCalendar; 374 int iHour; 375 int iMinute; 376 int iSecond; 377 int iMili; 378 379 compCalendar = Calendar.getInstance(); 380 compCalendar.setTime(dtFirst); 381 iHour = compCalendar.get(Calendar.HOUR_OF_DAY); 382 iMinute = compCalendar.get(Calendar.MINUTE); 383 iSecond = compCalendar.get(Calendar.SECOND); 384 iMili = compCalendar.get(Calendar.MILLISECOND); 385 compCalendar.setTime(dtSecond); 386 387 bReturn = ((iHour == compCalendar.get(Calendar.HOUR_OF_DAY)) 388 && (iMinute == compCalendar.get(Calendar.MINUTE)) 389 && (iSecond == compCalendar.get(Calendar.SECOND)) 390 && ((bIgnoreMilliseconds) 391 || (iMili == compCalendar.get(Calendar.MILLISECOND)))); 392 } 393 } 394 } 395 396 return bReturn; 397 } 398 399 407 public static boolean dateAndTimeEquals( 408 Date dtFirst, 409 Date dtSecond 410 ) 411 { 412 boolean bReturn = false; 413 414 bReturn = (dtFirst == dtSecond); 416 if (!bReturn) 417 { 418 if (dtFirst == null) 419 { 420 bReturn = (dtSecond == null); 422 } 423 else 424 { 425 if (dtSecond != null) 426 { 427 bReturn = (dtFirst.getTime() == dtSecond.getTime()); 431 } 432 } 433 } 434 435 return bReturn; 436 } 437 438 446 public static boolean isFunction( 447 String strValue 448 ) 449 { 450 boolean bReturn = false; 451 452 if ((strValue != null) && (strValue.length() > 0) 453 && (strValue.trim().startsWith(CURRENT_DATE_CODE))) 454 { 455 bReturn = true; 456 } 457 458 return bReturn; 459 } 460 461 474 public static Timestamp parseDateTime( 475 String strValue, 476 int iDateType, 477 boolean stored 478 ) throws OSSInvalidDataException 479 { 480 Timestamp tsReturn = null; 481 Calendar workCal = GregorianCalendar.getInstance(); 482 483 if (strValue != null && strValue.length() > 0) 484 { 485 strValue = strValue.trim(); 486 if (strValue.startsWith(CURRENT_DATE_CODE)) 487 { 488 strValue = strValue.replaceAll("[ ]", ""); 489 490 workCal.setTime(new Date ()); 493 494 496 int iBeginIndex = CURRENT_DATE_CODE.length(); 498 int iMaxLength = strValue.length(); 499 int iSign = 1; 500 int iNumberIndex; 501 int iValue; 502 char cChar = ' '; 503 504 while (iBeginIndex < iMaxLength) 505 { 506 if (strValue.charAt(iBeginIndex) == '+') 508 { 509 iSign = 1; 510 } 511 else if (strValue.charAt(iBeginIndex) == '-') 512 { 513 iSign = -1; 514 } 515 else 516 { 517 throw new OSSInvalidDataException( 519 "Date function is in incorrect format: " 520 + strValue + " at " + strValue.substring(iBeginIndex)); 521 } 522 iBeginIndex++; 523 524 iNumberIndex = iBeginIndex; 526 527 while (((iBeginIndex == iNumberIndex) || Character.isDigit(cChar)) 528 && (iBeginIndex < iMaxLength)) 529 { 530 cChar = strValue.charAt(iBeginIndex++); 531 } 532 533 iBeginIndex--; 535 536 try 537 { 538 iValue = Integer.parseInt(strValue.substring(iNumberIndex, iBeginIndex)); 539 } 540 catch (NumberFormatException nmeExc) 541 { 542 throw new OSSInvalidDataException( 544 "Date function is in incorrect format: " 545 + strValue + " at " + strValue.substring(iNumberIndex)); 546 } 547 548 cChar = strValue.charAt(iBeginIndex); 551 switch(cChar) 552 { 553 case(YEAR_CODE): 554 { 555 if (iDateType == DATE_TYPE_TIME) 556 { 557 throw new OSSInvalidDataException( 558 "Date function is in incorrect format: " + 559 "used YEAR modifier for TIME type"); 560 } 561 workCal.add(Calendar.YEAR, iSign * iValue); 562 break; 563 } 564 case(MONTH_CODE): 565 { 566 if (iDateType == DATE_TYPE_TIME) 567 { 568 throw new OSSInvalidDataException( 569 "Date function is in incorrect format: " + 570 "used MONTH modifier for TIME type"); 571 } 572 workCal.add(Calendar.MONTH, iSign * iValue); 573 break; 574 } 575 case(WEEK_CODE): 576 { 577 if (iDateType == DATE_TYPE_TIME) 578 { 579 throw new OSSInvalidDataException( 580 "Date function is in incorrect format: " + 581 "used WEEK modifier for TIME type"); 582 } 583 workCal.add(Calendar.WEEK_OF_YEAR, iSign * iValue); 584 break; 585 } 586 case(DAY_CODE): 587 { 588 if (iDateType == DATE_TYPE_TIME) 589 { 590 throw new OSSInvalidDataException( 591 "Date function is in incorrect format: " + 592 "used DAY modifier for TIME type"); 593 } 594 workCal.add(Calendar.DATE, iSign * iValue); 595 break; 596 } 597 case(HOUR_CODE): 598 { 599 if (iDateType == DATE_TYPE_DATE) 600 { 601 throw new OSSInvalidDataException( 602 "Date function is in incorrect format: " + 603 "used HOUR modifier for DATE type"); 604 } 605 workCal.add(Calendar.HOUR, iSign * iValue); 606 break; 607 } 608 case(MINUTE_CODE): 609 { 610 if (iDateType == DATE_TYPE_DATE) 611 { 612 throw new OSSInvalidDataException( 613 "Date function is in incorrect format: " + 614 "used MINUTE modifier for DATE type"); 615 } 616 workCal.add(Calendar.MINUTE, iSign * iValue); 617 break; 618 } 619 case(SECOND_CODE): 620 { 621 if (iDateType == DATE_TYPE_DATE) 622 { 623 throw new OSSInvalidDataException( 624 "Date function is in incorrect format: " + 625 "used SECOND modifier for DATE type"); 626 } 627 workCal.add(Calendar.SECOND, iSign * iValue); 628 break; 629 } 630 default: 631 { 632 throw new OSSInvalidDataException( 634 "Date function is in incorrect format: " 635 + strValue + " at " + strValue.substring(iBeginIndex)); 636 } 637 } 638 639 iBeginIndex++; 640 } 641 642 tsReturn = new Timestamp (workCal.getTimeInMillis()); 643 644 } 645 else 646 { 647 try 648 { 649 if (stored) 650 { 651 switch (iDateType) 652 { 653 case (DATE_TYPE_DATE) : 654 { 655 tsReturn = new Timestamp (DATE_STORE_FORMAT.parse(strValue).getTime()); 656 break; 657 } 658 case (DATE_TYPE_TIME) : 659 { 660 tsReturn = new Timestamp (TIME_STORE_FORMAT.parse(strValue).getTime()); 661 break; 662 } 663 case (DATE_TYPE_DATETIME) : 664 { 665 tsReturn = new Timestamp (DATETIME_STORE_FORMAT.parse(strValue).getTime()); 666 break; 667 } 668 default: 669 { 670 assert false : "Unknown date type " + iDateType; 671 } 672 } 673 } 674 else 675 { 676 switch (iDateType) 677 { 678 case (DATE_TYPE_DATE) : 679 { 680 tsReturn = new Timestamp (DATE_FORMAT.parse(strValue).getTime()); 681 break; 682 } 683 case (DATE_TYPE_TIME) : 684 { 685 tsReturn = new Timestamp (TIME_FORMAT.parse(strValue).getTime()); 686 break; 687 } 688 case (DATE_TYPE_DATETIME) : 689 { 690 tsReturn = new Timestamp (DATETIME_FORMAT.parse(strValue).getTime()); 691 break; 692 } 693 default: 694 { 695 assert false : "Unknown date type " + iDateType; 696 } 697 } 698 } 699 } 700 catch (ParseException peExc) 701 { 702 throw new OSSInvalidDataException( 703 "Date is in incorrect format. Problems with parsing.", 704 peExc); 705 } 706 } 707 } 708 709 return tsReturn; 710 } 711 712 719 public static String parseDayPeriod( 720 long lPeriod 721 ) 722 { 723 StringBuffer sbReturn = new StringBuffer (); 724 long lDays = 0L; 725 726 if (lPeriod > 0) 727 { 728 lPeriod = lPeriod + DateUtils.ONE_DAY - 1; 730 731 lDays = lPeriod / DateUtils.ONE_DAY; 732 sbReturn.append(lDays); 733 if (lDays == 1L) 734 { 735 sbReturn.append(" day"); 736 } 737 else 738 { 739 sbReturn.append(" days"); 740 } 741 } 742 else 743 { 744 sbReturn.append("0 days"); 745 } 746 747 return sbReturn.toString(); 748 } 749 750 758 public static String parseDayTimePeriod( 759 long lPeriod 760 ) 761 { 762 StringBuffer sbReturn = new StringBuffer (); 763 long lHelp = 0L; 764 765 766 if (lPeriod > 0) 767 { 768 lPeriod = lPeriod + DateUtils.ONE_MINUTE - 1; 769 lHelp = lPeriod / DateUtils.ONE_DAY; 771 if (lHelp > 0) 772 { 773 sbReturn.append(lHelp); 774 if (lHelp == 1L) 775 { 776 sbReturn.append(" d "); 777 } 778 else 779 { 780 sbReturn.append(" d "); 781 } 782 } 783 lPeriod = lPeriod % DateUtils.ONE_DAY; 784 lHelp = lPeriod / DateUtils.ONE_HOUR; 785 if (lHelp > 0 || sbReturn.length() > 0) 786 { 787 sbReturn.append(lHelp); 788 if (lHelp == 1L) 789 { 790 sbReturn.append(" h "); 791 } 792 else 793 { 794 sbReturn.append(" h "); 795 } 796 } 797 lPeriod = lPeriod % DateUtils.ONE_HOUR; 798 lHelp = lPeriod / DateUtils.ONE_MINUTE; 799 if (lHelp > 0 || sbReturn.length() > 0) 800 { 801 sbReturn.append(lHelp); 802 if (lHelp == 1L) 803 { 804 sbReturn.append(" min"); 805 } 806 else 807 { 808 sbReturn.append(" min"); 809 } 810 } 811 } 812 else 813 { 814 sbReturn.append("0 min"); 815 } 816 return sbReturn.toString(); 817 } 818 819 843 866 924 935 public static Timestamp getPeriodExpiration( 936 Timestamp tsStartDate, 937 int iPeriodType, 938 int iPeriodDuration 939 ) 940 { 941 Timestamp tsReturn = null; 942 Calendar calHelp; 943 if (tsStartDate != null && iPeriodDuration > 0 944 && iPeriodType > TIMING_NEVER && iPeriodType < TIMING_NONE) 945 { 946 calHelp = Calendar.getInstance(); 947 calHelp.setTime(tsStartDate); 948 949 switch (iPeriodType) 950 { 951 case (TIMING_MINUTES) : 952 { 953 calHelp.add(Calendar.MINUTE, iPeriodDuration); 954 break; 955 } 956 case (TIMING_HOURS) : 957 { 958 calHelp.add(Calendar.HOUR, iPeriodDuration); 959 break; 960 } 961 case (TIMING_DAYS) : 962 { 963 calHelp.add(Calendar.DATE, iPeriodDuration); 964 break; 965 } 966 case (TIMING_WEEKS) : 967 { 968 calHelp.add(Calendar.WEEK_OF_YEAR, iPeriodDuration); 969 break; 970 } 971 case (TIMING_MONTHS) : 972 { 973 calHelp.add(Calendar.MONTH, iPeriodDuration); 974 break; 975 } 976 case (TIMING_YEARS) : 977 { 978 calHelp.add(Calendar.YEAR, iPeriodDuration); 979 break; 980 } 981 default : 982 { 983 assert false : "Not supported Timing type " + iPeriodType; 984 } 985 } 986 tsReturn = new Timestamp (calHelp.getTimeInMillis()); 987 } 988 989 return tsReturn; 990 } 991 992 1005 public static int comparePeriods( 1006 int iPeriodType1, 1007 int iPeriodDuration1, 1008 int iPeriodType2, 1009 int iPeriodDuration2 1010 ) 1011 { 1012 int iReturn = 0; 1013 1014 if ((iPeriodType1 != TIMING_NEVER) && (iPeriodType1 != TIMING_NONE) 1015 && (iPeriodType2 != TIMING_NEVER) && (iPeriodType2 != TIMING_NONE)) 1016 { 1017 Timestamp tsTimestamp1 = getPeriodExpiration( 1018 new Timestamp (0), iPeriodType1, iPeriodDuration1); 1019 Timestamp tsTimestamp2 = getPeriodExpiration( 1020 new Timestamp (0), iPeriodType2, iPeriodDuration2); 1021 1022 if ((tsTimestamp1 != null) && (tsTimestamp2 != null)) 1024 { 1025 if (tsTimestamp1.after(tsTimestamp2)) 1026 { 1027 iReturn = 1; 1028 } 1029 else if (tsTimestamp2.after(tsTimestamp1)) 1030 { 1031 iReturn = -1; 1032 } 1033 } 1034 } 1035 else 1036 { 1037 if (iPeriodType1 != iPeriodType2) 1038 { 1039 if (iPeriodType1 == TIMING_NEVER) 1040 { 1041 iReturn = 1; 1042 } 1043 else if (iPeriodType1 == TIMING_NONE) 1044 { 1045 iReturn = -1; 1046 } 1047 else if (iPeriodType2 == TIMING_NEVER) 1048 { 1049 iReturn = -1; 1050 } 1051 else if (iPeriodType2 == TIMING_NONE) 1052 { 1053 iReturn = 1; 1054 } 1055 } 1056 } 1057 1058 return iReturn; 1059 } 1060 1061 1068 public static String getTimestampAsString( 1069 Timestamp tsTimestamp 1070 ) 1071 { 1072 StringBuffer sbTimestamp = new StringBuffer (); 1073 1074 sbTimestamp.append(tsTimestamp.getTime()); 1075 sbTimestamp.append(NANO_SEPARATOR); 1076 sbTimestamp.append(tsTimestamp.getNanos()); 1077 1078 return sbTimestamp.toString(); 1079 } 1080 1081 1089 public static Timestamp parseTimestamp( 1090 String strTimestamp 1091 ) throws NumberFormatException 1092 { 1093 long lTime; 1094 int iNanos; 1095 1096 if ("0".equals(strTimestamp)) 1097 { 1098 lTime = 0L; 1099 iNanos = 0; 1100 } 1101 else 1102 { 1103 int iIndex; 1104 1105 iIndex = strTimestamp.indexOf(NANO_SEPARATOR); 1106 if (iIndex == -1) 1107 { 1108 throw new NumberFormatException ( 1109 "The timestamp string doesn't contain nanosecond separator: " 1110 + strTimestamp); 1111 } 1112 1113 lTime = Long.parseLong(strTimestamp.substring(0, iIndex)); 1114 iNanos = Integer.parseInt(strTimestamp.substring(iIndex + 1)); 1115 } 1116 1117 return new TimestampCopy(lTime, iNanos); 1118 } 1119 1120 1126 public static String getStringTime( 1127 long lTimeInMiliseconds 1128 ) 1129 { 1130 long lTotalMS = lTimeInMiliseconds; 1131 long lMS = lTotalMS % 1000; 1132 long lTotalSecs = lTotalMS / 1000; 1133 long lSecs = lTotalSecs % 60; 1134 long lTotalMins = lTotalSecs / 60; 1135 long lMinutes = lTotalMins % 60; 1136 long lHours = lTotalMins / 60; 1137 StringBuffer sbBuffer = new StringBuffer (); 1138 1139 if (lHours > 0) 1140 { 1141 sbBuffer.append(lHours); 1142 sbBuffer.append(":"); 1143 sbBuffer.append(lMinutes); 1144 sbBuffer.append(":"); 1145 sbBuffer.append(lSecs); 1146 sbBuffer.append("."); 1147 sbBuffer.append(lMS); 1148 } 1149 else if (lMinutes > 0) 1150 { 1151 sbBuffer.append(lMinutes); 1152 sbBuffer.append(":"); 1153 sbBuffer.append(lSecs); 1154 sbBuffer.append("."); 1155 sbBuffer.append(lMS); 1156 } 1157 else if (lSecs > 0) 1158 { 1159 sbBuffer.append(lSecs); 1160 sbBuffer.append("."); 1161 sbBuffer.append(lMS); 1162 sbBuffer.append(" seconds"); 1163 } 1164 else 1165 { 1166 sbBuffer.append(lMS); 1167 sbBuffer.append(" ms"); 1168 } 1169 1170 return sbBuffer.toString(); 1171 } 1172 1173} 1252 | Popular Tags |