Java/Development Class/Time

Материал из Java эксперт
Перейти к: навигация, поиск

Compare both times and dates

   <source lang="java">
  

/**

* Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
* 
* Project: OpenSubsystems
* 
* $Id: DateUtils.java,v 1.7 2007/01/07 06:14:00 bastafidli Exp $
* 
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License. 
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
*/

import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar;

/**

* Collection of useful utilities to work with dates. 
* 
* @version $Id: DateUtils.java,v 1.7 2007/01/07 06:14:00 bastafidli Exp $
* @author Miro Halas
* @code.reviewer Miro Halas
* @code.reviewed 1.5 2005/09/13 13:23:15 bastafidli
*/

public final class DateUtils {

  // Constants ////////////////////////////////////////////////////////////////
  
  /**
   * One second in milliseconds.
   */
  public static final long ONE_SECOND = 1000L;
  
  /**
   * One minute in milliseconds.
   */
  public static final long ONE_MINUTE = ONE_SECOND * 60L;
  
  /**
   * One hour in milliseconds.
   */
  public static final long ONE_HOUR = ONE_MINUTE * 60L;
  
  /**
   * One day in milliseconds.
   */
  public static final long ONE_DAY = ONE_HOUR * 24L;
  
  /**
   * Separator we used to separate time from the nanosecond portion of the 
   * timestamp when converted to string.
   */
  public static final char NANO_SEPARATOR = ":";
  
  /**
   * Constant for timing type
   */
  public static final int TIMING_NEVER = 0;
  /**
   * Constant for timing type
   */
  public static final int TIMING_MINUTES = 1;
  /**
   * Constant for timing type
   */
  public static final int TIMING_HOURS = 2;
  /**
   * Constant for timing type
   */
  public static final int TIMING_DAYS = 3;
  /**
   * Constant for timing type
   */
  public static final int TIMING_WEEKS = 4;
  /**
   * Constant for timing type
   */
  public static final int TIMING_MONTHS = 5;
  /**
   * Constant for timing type
   */
  public static final int TIMING_YEARS = 6;
  
  /**
   * Constant for timing type
   */
  public static final int TIMING_NONE = 7;
  /**
   * Constant for current date code used in date/time formulas 
   */
  public static final String CURRENT_DATE_CODE = "now";
  
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char YEAR_CODE = "y";
  
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char MONTH_CODE = "M";
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char WEEK_CODE = "w";
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char DAY_CODE = "d";
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char HOUR_CODE = "h";
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char MINUTE_CODE = "m";
  
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char SECOND_CODE = "s";
  /**
   * constant for date type DATE
   */
  public static final int DATE_TYPE_DATE = 1;
  /**
   * constant for date type TIME
   */
  public static final int DATE_TYPE_TIME = 2;
  /**
   * constant for date type DATETIME
   */
  public static final int DATE_TYPE_DATETIME = 3;
  
  // Constants for period start types /////////////////////////////////////////

// TODO: For Miro: Remove this code once all the code which referred to these // constants was fixed // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_NONE = 0; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_CREATION = 1; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_COMPLETION = 2; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_APPROVAL = 3; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_ACTIVATION = 4; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_INACTIVATION = 5; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_DYNAMIC = 6; // // /** // * constant for period type code // */ // public static final int PERIOD_TYPE_CODE = 99; // // /** // * constant for period type object // */ // public static final Integer PERIOD_TYPE_OBJ = new Integer(PERIOD_TYPE_CODE);

  // Cached variables /////////////////////////////////////////////////////////
  
  /**
   * static SimpleDateFormat for date format to display on UI and in messages.
   */
  public static final SimpleDateFormat DATE_FORMAT 
                         = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT);
  
  /**
   * static SimpleDateFormat for time format to display on UI and in messages.
   */
  public static final SimpleDateFormat TIME_FORMAT 
                         = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.MEDIUM);
  
  /**
   * static SimpleDateFormat for datetime format to display on UI and in messages.
   */
  public static final SimpleDateFormat DATETIME_FORMAT 
                         = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, 
                                                          DateFormat.MEDIUM); 
  /**
   * static SimpleDateFormat for date format to store date as string so that
   * it is stored consistently.
   */
  public static final SimpleDateFormat DATE_STORE_FORMAT
                         = new SimpleDateFormat("MM/dd/yyyy");
  
  /**
   * static SimpleDateFormat for time format to store time as string so that
   * it is stored consistently.
   */
  public static final SimpleDateFormat TIME_STORE_FORMAT 
                         = new SimpleDateFormat("HH:mm:ss");
  
  /**
   * static SimpleDateFormat for datetime format to store date and time as 
   * string so that it is stored consistently.
   */
  public static final SimpleDateFormat DATETIME_STORE_FORMAT 
                         = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
  /**
   * static SimpleDateFormat for date format for sql date
   */
  public static final SimpleDateFormat DATE_SQL_FORMAT
                         = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
  
  /**
   * static SimpleDateFormat for time format for sql time
   */
  public static final SimpleDateFormat TIME_SQL_FORMAT 
                         = new SimpleDateFormat("1970-01-01 HH:mm:ss");
  
  /**
   * static SimpleDateFormat for datetime format for sql date and time
   */
  public static final SimpleDateFormat DATETIME_SQL_FORMAT 
                         = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  // Constructors /////////////////////////////////////////////////////////////
  
  /** 
   * Private constructor since this class cannot be instantiated
   */
  private DateUtils(
  )
  {
     // Do nothing
  }
  
  // Public methods ///////////////////////////////////////////////////////////
  
  /**
   * Check if two dates equals regardless of the time. Two null dates are equal. 
   * Null and not null dates are not equal.
   * 
   * @param  dtFirst - first date to compare, can be null
   * @param  dtSecond - second date to compare, can be null 
   * @return boolean - true if two dates equals regardless of what the time is 
   */
  public static boolean dateEquals(
     Date dtFirst,
     Date dtSecond
  )
  {
     boolean  bReturn = false;
     
     // If they are the same object, they are equals
     bReturn = (dtFirst == dtSecond);
     if (!bReturn)
     {
        if (dtFirst == null)
        {
           // Two null dates are the same
           bReturn = (dtSecond == null);
        }
        else
        {
           if (dtSecond != null)
           {
              Calendar compCalendar;
              int      iEra;
              int      iYear;
              int      iMonth;
              int      iDay;
              
              compCalendar = Calendar.getInstance();
              compCalendar.setTime(dtFirst);
              iEra   = compCalendar.get(Calendar.ERA);
              iYear  = compCalendar.get(Calendar.YEAR);
              iMonth = compCalendar.get(Calendar.MONTH);
              iDay   = compCalendar.get(Calendar.DATE);
              compCalendar.setTime(dtSecond);
        
              bReturn = ((iEra == compCalendar.get(Calendar.ERA))
                        && (iYear == compCalendar.get(Calendar.YEAR))
                        && (iMonth == compCalendar.get(Calendar.MONTH))
                        && (iDay == compCalendar.get(Calendar.DATE)));
           }
        }
     } 
           
     return bReturn;            
  }
  
  /**
   * Check if two times equals regardless of the date. Two null times are equal. 
   * Null and not null times are not equal.
   * 
   * @param  dtFirst - first time to compare, can be null
   * @param  dtSecond - second time to compare, can be null
   * @param  bIgnoreMilliseconds - if true milliseconds will be ignored in comparison
   * @return boolean - true if two time equals regardless of what the date is 
   */
  public static boolean timeEquals(
     Date    dtFirst,
     Date    dtSecond,
     boolean bIgnoreMilliseconds
  )
  {
     boolean  bReturn = false;
     
     // If they are the same object, they are equals
     bReturn = (dtFirst == dtSecond);
     if (!bReturn)
     {
        if (dtFirst == null)
        {
           // Two null dates are the same
           bReturn = (dtSecond == null);
        }
        else
        {
           if (dtSecond != null)
           {
              Calendar compCalendar;
              int      iHour;
              int      iMinute;
              int      iSecond;
              int      iMili;
              
              compCalendar = Calendar.getInstance();
              compCalendar.setTime(dtFirst);
              iHour   = compCalendar.get(Calendar.HOUR_OF_DAY);
              iMinute = compCalendar.get(Calendar.MINUTE);
              iSecond = compCalendar.get(Calendar.SECOND);
              iMili   = compCalendar.get(Calendar.MILLISECOND);
              compCalendar.setTime(dtSecond);
        
              bReturn = ((iHour == compCalendar.get(Calendar.HOUR_OF_DAY))
                        && (iMinute == compCalendar.get(Calendar.MINUTE))
                        && (iSecond == compCalendar.get(Calendar.SECOND))
                        && ((bIgnoreMilliseconds) 
                           || (iMili == compCalendar.get(Calendar.MILLISECOND))));
           }
        }
     } 
           
     return bReturn;            
  }
  /**
   * Check if two dates and times are equal. Two null dates are equal. Null 
   * and not null dates are not equal.
   * 
   * @param  dtFirst - first date time to compare, can be null
   * @param  dtSecond - second date time to compare, can be null
   * @return boolean - true if two date and times are equal 
   */
  public static boolean dateAndTimeEquals(
     Date dtFirst,
     Date dtSecond
  )
  {
     boolean bReturn = false;
     
     // If they are the same object, they are equals
     bReturn = (dtFirst == dtSecond);
     if (!bReturn)
     {
        if (dtFirst == null)
        {
           // Two null dates are the same
           bReturn = (dtSecond == null);
        }
        else
        {
           if (dtSecond != null)
           {
              // They are both not null so they have to match to millisecond
              // (actually to nanosecond since the getTime takes nanoseconds
              // into account)
              bReturn = (dtFirst.getTime() == dtSecond.getTime());                               
           }
        }
     }
           
     return bReturn;            
  }
  /**
   * Check if String representing date is function or date. Date is a function
   * (formula) if it starts with the current date/time variable which can be 
   * followed by expression describing period from current date.
   *
   * @param strValue - string representation of date or date function
   * @return boolean - date function flag
   */
  public static boolean isFunction(
     String   strValue
  )
  {
     boolean bReturn = false;
     if ((strValue != null) && (strValue.length() > 0) 
        && (strValue.trim().startsWith(CURRENT_DATE_CODE)))
     {
        bReturn = true;
     }
     
     return bReturn;
  }
  
  /**
   * Parse date time value from given string resolving any functions or formulas
   * the string can contain. This method  can be therefore used if the passed 
   * string contains string representation date, time or timestamp or a formula
   * such as now + 3h - 1m + 4d. 
   *
   * @param strValue - string representation of date or date function
   * @param iDateType - date type code, one of the DATE_TYPE_XXX constants
   * @param stored - flag if Date should be parsed using format used for 
   *                 storage or for display
   * @return Timestamp - parsed date or null if date was null
   * @throws OSSInvalidDataException - error during parsing
   */
  public static Timestamp parseDateTime(
     String   strValue,
     int      iDateType,
     boolean  stored
  )
  {
     Timestamp tsReturn = null;
     Calendar workCal = GregorianCalendar.getInstance();
     
     if (strValue != null && strValue.length() > 0)
     {
        strValue = strValue.trim();
        if (strValue.startsWith(CURRENT_DATE_CODE))
        {
           strValue = strValue.replaceAll("[ ]", "");
           // If the user specified "UseCurrent", then substitute the
           // current date/time in the value
           workCal.setTime(new Date());

// Log.getInstance().debug("Parsing current date " + strValue);

           // Parse the date math
           int iBeginIndex = CURRENT_DATE_CODE.length();
           int iMaxLength = strValue.length();
           int iSign = 1;
           int iNumberIndex;
           int iValue;
           char cChar = " ";
           while (iBeginIndex < iMaxLength)
           {
              // This has to be sign
              if (strValue.charAt(iBeginIndex) == "+")
              {
                 iSign = 1;
              }
              else if (strValue.charAt(iBeginIndex) == "-")
              {
                 iSign = -1;
              }
              else
              {
                 // Incorrect String
                 throw new RuntimeException(
                          "Date function is in incorrect format: "
                          + strValue + " at " + strValue.substring(iBeginIndex));
              }
              iBeginIndex++;
              // Now we have to have number
              iNumberIndex = iBeginIndex;
              
              while (((iBeginIndex == iNumberIndex) || Character.isDigit(cChar)) 
                    && (iBeginIndex < iMaxLength))
              {
                 cChar = strValue.charAt(iBeginIndex++);
              }
              // We have to go one back because we should stop on modifier (e.g 1m)
              iBeginIndex--;
              try
              {
                 iValue = Integer.parseInt(strValue.substring(iNumberIndex, iBeginIndex));
              }
              catch (NumberFormatException nmeExc)
              {
                 // Incorrect String
                 throw new RuntimeException(
                          "Date function is in incorrect format: "
                          + strValue + " at " + strValue.substring(iNumberIndex));
              }
              // This has to be modifier: y - year, M - month, w - week, 
              // d - day, h - hour, m - minute, s - second
              cChar = strValue.charAt(iBeginIndex);
              switch(cChar)
              {
                 case(YEAR_CODE):
                 {
                    if (iDateType == DATE_TYPE_TIME)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used YEAR modifier for TIME type");
                    }
                    workCal.add(Calendar.YEAR, iSign * iValue);
                    break;
                 }
                 case(MONTH_CODE):
                 {
                    if (iDateType == DATE_TYPE_TIME)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used MONTH modifier for TIME type");
                    }
                    workCal.add(Calendar.MONTH, iSign * iValue);
                    break;
                 }
                 case(WEEK_CODE):
                 {
                    if (iDateType == DATE_TYPE_TIME)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used WEEK modifier for TIME type");
                    }
                    workCal.add(Calendar.WEEK_OF_YEAR, iSign * iValue);
                    break;
                 }
                 case(DAY_CODE):
                 {
                    if (iDateType == DATE_TYPE_TIME)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used DAY modifier for TIME type");
                    }
                    workCal.add(Calendar.DATE, iSign * iValue);
                    break;
                 }
                 case(HOUR_CODE):
                 {
                    if (iDateType == DATE_TYPE_DATE)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used HOUR modifier for DATE type");
                    }
                    workCal.add(Calendar.HOUR, iSign * iValue);
                    break;
                 }
                 case(MINUTE_CODE):
                 {
                    if (iDateType == DATE_TYPE_DATE)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used MINUTE modifier for DATE type");
                    }
                    workCal.add(Calendar.MINUTE, iSign * iValue);
                    break;
                 }
                 case(SECOND_CODE):
                 {
                    if (iDateType == DATE_TYPE_DATE)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used SECOND modifier for DATE type");
                    }
                    workCal.add(Calendar.SECOND, iSign * iValue);
                    break;
                 }
                 default:
                 {
                    // Incorrect String
                    throw new RuntimeException(
                          "Date function is in incorrect format: "
                          + strValue + " at " + strValue.substring(iBeginIndex));
                 }
              }
              iBeginIndex++;
           }
           
           tsReturn = new Timestamp(workCal.getTimeInMillis());
           
        }
        else
        {
           try
           {
              if (stored)
              {
                 switch (iDateType)
                 {
                    case (DATE_TYPE_DATE) :
                    {
                       tsReturn = new Timestamp(DATE_STORE_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    case (DATE_TYPE_TIME) :
                    {
                       tsReturn = new Timestamp(TIME_STORE_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    case (DATE_TYPE_DATETIME) :
                    {
                       tsReturn = new Timestamp(DATETIME_STORE_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    default:
                    {
                       assert false : "Unknown date type " + iDateType;
                    }
                 }                  
              }
              else
              {
                 switch (iDateType)
                 {
                    case (DATE_TYPE_DATE) :
                    {
                       tsReturn = new Timestamp(DATE_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    case (DATE_TYPE_TIME) :
                    {
                       tsReturn = new Timestamp(TIME_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    case (DATE_TYPE_DATETIME) :
                    {
                       tsReturn = new Timestamp(DATETIME_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    default:
                    {
                       assert false : "Unknown date type " + iDateType;
                    }                  
                 }                  
              }
           }
           catch (ParseException peExc)
           {
              throw new RuntimeException(
                    "Date is in incorrect format. Problems with parsing.",
                    peExc);
           }
        }
     }
     return tsReturn;
  }
  
  /**
   * Parse the specified period into string displaying number of days the 
   * period represents. 
   * 
   * @param lPeriod - period in miliseconds
   * @return String - period in format "x day(s)" or "" if not valid period
   */
  public static String parseDayPeriod(
     long lPeriod
  )
  {
     StringBuffer sbReturn = new StringBuffer();
     long lDays = 0L;
     
     if (lPeriod > 0)
     {
        // we will count each started day as counted day 
        lPeriod = lPeriod + DateUtils.ONE_DAY - 1;
        
        lDays = lPeriod / DateUtils.ONE_DAY;
        sbReturn.append(lDays);
        if (lDays == 1L)
        {
           sbReturn.append(" day");
        }
        else
        {
           sbReturn.append(" days");
        }
     }
     else
     {
        sbReturn.append("0 days");
     }
     return sbReturn.toString();
  }
  
  /**
   * Parse the specified period into string displaying date and time the 
   * period represents. 
   * 
   * @param lPeriod - preiod in miliseconds
   * @return String - period in format "x day(s) y hour(s) z minute(s)" 
   *                  or "" if not valid period
   */
  public static String parseDayTimePeriod(
     long lPeriod
  )
  {
     StringBuffer sbReturn = new StringBuffer();
     long lHelp = 0L;
     
     
     if (lPeriod > 0)
     {
        lPeriod = lPeriod + DateUtils.ONE_MINUTE - 1;
        // we will count each started day as counted day 
        lHelp = lPeriod / DateUtils.ONE_DAY;
        if (lHelp > 0)
        {
           sbReturn.append(lHelp);
           if (lHelp == 1L)
           {
              sbReturn.append(" d ");
           }
           else
           {
              sbReturn.append(" d ");
           }
        }
        lPeriod = lPeriod % DateUtils.ONE_DAY;
        lHelp = lPeriod / DateUtils.ONE_HOUR;
        if (lHelp > 0 || sbReturn.length() > 0)
        {
           sbReturn.append(lHelp);
           if (lHelp == 1L)
           {
              sbReturn.append(" h ");
           }
           else
           {
              sbReturn.append(" h ");
           }
        }
        lPeriod = lPeriod % DateUtils.ONE_HOUR;
        lHelp = lPeriod / DateUtils.ONE_MINUTE;
        if (lHelp > 0 || sbReturn.length() > 0)
        {
           sbReturn.append(lHelp);
           if (lHelp == 1L)
           {
              sbReturn.append(" min");
           }
           else
           {
              sbReturn.append(" min");
           }
        }
     }
     else
     {
        sbReturn.append("0 min");
     }
     return sbReturn.toString();
  }
  

// TODO: For Miro: Remove this code once all the code which referred to these // was fixed. These should be moved to a GUI related class. // /** // * Method for list of timing types. // * // * @return List - list of timing types // */ // public static List getTimingTypes( // ) // { // List lstTimingTypes = new ArrayList(); // // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_MINUTES), // "Minute(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_HOURS), "Hour(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_DAYS), "Day(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_WEEKS), "Week(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_MONTHS), "Month(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_YEARS), "Year(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_NEVER), "Never")); // // return lstTimingTypes; // } // /** // * Method for list of timing types with None option. // * // * @return List - list of timing types // */ // public static List getTimingTypesWithNone( // ) // { // List lstTimingTypes = new ArrayList(); // // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_NONE), "None")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_MINUTES), // "Minute(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_HOURS), "Hour(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_DAYS), "Day(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_WEEKS), "Week(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_MONTHS), "Month(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_YEARS), "Year(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_NEVER), "Never")); // // return lstTimingTypes; // } // /** // * Method for getting string name of the timing type. // * // * @param iTimingType - timing type constant // * @return String - string name of timing type // */ // public static String getTimingTypeName( // int iTimingType // ) // { // String outTimingTypeName = "Never"; // switch (iTimingType) // { // case (DateUtils.TIMING_NEVER): // { // outTimingTypeName = "Never"; // break; // } // case (DateUtils.TIMING_MINUTES): // { // outTimingTypeName = "Minute(s)"; // break; // } // case (DateUtils.TIMING_HOURS): // { // outTimingTypeName = "Hour(s)"; // break; // } // case (DateUtils.TIMING_DAYS): // { // outTimingTypeName = "Day(s)"; // break; // } // case (DateUtils.TIMING_WEEKS): // { // outTimingTypeName = "Week(s)"; // break; // } // case (DateUtils.TIMING_MONTHS): // { // outTimingTypeName = "Month(s)"; // break; // } // case (DateUtils.TIMING_YEARS): // { // outTimingTypeName = "Year(s)"; // break; // } // case (DateUtils.TIMING_NONE): // { // outTimingTypeName = "None"; // break; // } // } // // return outTimingTypeName; // }

  /**
   * Get expiration timestamp from start date, period type and duration. For 
   * example if the start date is now, period type is hour and duration is 2
   * then the result will be timestamp representing now + 2 hours.  
   * 
   * @param tsStartDate - start date of period counting
   * @param iPeriodType - one of the period type constant TIMING_XXX 
   * @param iPeriodDuration - period duration, number of time units specified 
   *                          by period type
   * @return Timestamp - date of period expiration or null if any problem
   */
  public static Timestamp getPeriodExpiration(
     Timestamp tsStartDate,
     int       iPeriodType,
     int       iPeriodDuration
  )
  {
     Timestamp tsReturn = null;
     Calendar calHelp;
     if (tsStartDate != null && iPeriodDuration > 0 
           && iPeriodType > TIMING_NEVER && iPeriodType < TIMING_NONE)
     {
        calHelp = Calendar.getInstance();
        calHelp.setTime(tsStartDate);
        
        switch (iPeriodType)
        {
           case (TIMING_MINUTES) :
           {
              calHelp.add(Calendar.MINUTE, iPeriodDuration);
              break;
           }
           case (TIMING_HOURS) :
           {
              calHelp.add(Calendar.HOUR, iPeriodDuration);
              break;
           }
           case (TIMING_DAYS) :
           {
              calHelp.add(Calendar.DATE, iPeriodDuration);
              break;
           }
           case (TIMING_WEEKS) :
           {
              calHelp.add(Calendar.WEEK_OF_YEAR, iPeriodDuration);
              break;
           }
           case (TIMING_MONTHS) :
           {
              calHelp.add(Calendar.MONTH, iPeriodDuration);
              break;
           }
           case (TIMING_YEARS) :
           {
              calHelp.add(Calendar.YEAR, iPeriodDuration);
              break;
           }
           default :
           {
              assert false : "Not supported Timing type " + iPeriodType;
           } 
        }
        tsReturn = new Timestamp(calHelp.getTimeInMillis());
     }
     
     return tsReturn;
  }
  
  /**
   * Method to compare time periods
   * 
   * @param iPeriodType1 - first period type, one of the period type constant 
   *                       TIMING_XXX
   * @param iPeriodDuration1 - first period duration
   * @param iPeriodType2 - second period type, one of the period type constant 
   *                       TIMING_XXX
   * @param iPeriodDuration2 - second period duration
   * @return int - 1 - first period is longer
   *               0 - periods are same
   *              -1 - first period is shorter
   */
  public static int comparePeriods(
     int iPeriodType1,
     int iPeriodDuration1,
     int iPeriodType2,
     int iPeriodDuration2
  )
  {
     int iReturn = 0;
     
     if ((iPeriodType1 != TIMING_NEVER) && (iPeriodType1 != TIMING_NONE) 
        && (iPeriodType2 != TIMING_NEVER) && (iPeriodType2 != TIMING_NONE))
     {
        Timestamp tsTimestamp1 = getPeriodExpiration(
              new Timestamp(0), iPeriodType1, iPeriodDuration1);
        Timestamp tsTimestamp2 = getPeriodExpiration(
              new Timestamp(0), iPeriodType2, iPeriodDuration2);
        
        // TODO: Improve: When would any of these be null?
        if ((tsTimestamp1 != null) && (tsTimestamp2 != null))
        {
           if (tsTimestamp1.after(tsTimestamp2))
           {
              iReturn = 1;
           }
           else if (tsTimestamp2.after(tsTimestamp1))
           {
              iReturn = -1;
           }
        }
     }
     else
     {
        if (iPeriodType1 != iPeriodType2)
        {
           if (iPeriodType1 == TIMING_NEVER)
           {
              iReturn = 1;
           }
           else if (iPeriodType1 == TIMING_NONE)
           {
              iReturn = -1;
           }
           else if (iPeriodType2 == TIMING_NEVER)
           {
              iReturn = -1;
           }
           else if (iPeriodType2 == TIMING_NONE)
           {
              iReturn = 1;
           }
        }
     }
     return iReturn;      
  }
  
  /**
   * Convert timestamp to string including it"s nanosecond portion so that it 
   * can be safely stored in variable of web page.
   * 
   * @param tsTimestamp - timestamp to convert
   * @return String - text containing time and nanosecond portion of timestamp
   */
  public static String getTimestampAsString(
     Timestamp tsTimestamp
  )
  {
     StringBuffer sbTimestamp = new StringBuffer();
     
     sbTimestamp.append(tsTimestamp.getTime());
     sbTimestamp.append(NANO_SEPARATOR);
     sbTimestamp.append(tsTimestamp.getNanos());
     
     return sbTimestamp.toString();
  }
  
  /**
   * Function returns time string in the form MM:SS.MS from the input specified in miliseconds. 
   * 
   * @param lTimeInMiliseconds - time in miliseconds
   * @return String - string representation of miliseconds in the form MM:SS.MS
   */
  public static String getStringTime(
     long lTimeInMiliseconds
  )
  {
     long lTotalMS   = lTimeInMiliseconds;
     long lMS        = lTotalMS % 1000;
     long lTotalSecs = lTotalMS / 1000;
     long lSecs      = lTotalSecs % 60;
     long lTotalMins = lTotalSecs / 60;
     long lMinutes   = lTotalMins % 60;
     long lHours     = lTotalMins / 60;
     StringBuffer sbBuffer = new StringBuffer();
     if (lHours > 0)
     {
        sbBuffer.append(lHours);
        sbBuffer.append(":");
        sbBuffer.append(lMinutes);
        sbBuffer.append(":");
        sbBuffer.append(lSecs);
        sbBuffer.append(".");
        sbBuffer.append(lMS);
     }
     else if (lMinutes > 0)
     {
        sbBuffer.append(lMinutes);
        sbBuffer.append(":");
        sbBuffer.append(lSecs);
        sbBuffer.append(".");
        sbBuffer.append(lMS);
     }
     else if (lSecs > 0)
     {
        sbBuffer.append(lSecs);
        sbBuffer.append(".");
        sbBuffer.append(lMS);
        sbBuffer.append(" seconds");
     }
     else
     {
        sbBuffer.append(lMS);
        sbBuffer.append(" ms");
     }
     
     return sbBuffer.toString();
  }

// TODO: For Miro: Remove this code once all the code which referred to these // was fixed. These should be moved to a GUI or business logic related class. // /** // * Method to check if valid period settings // * // * @param iPeriod - period length // * @param iPeriodType - period type // * @param iPeriodStartType - period start type // * @param iAttributeId - attribute ID for dynamic period start type // * @param bPeriodException - period exception flag // * @param strPeriodName - period name used for exception message // * @param bAdvancePeriodType - flag if advanced period type (includes also start type) // * @param bfideException - invalid data exception // */ // public static void validatePeriod( // int iPeriod, // int iPeriodType, // int iPeriodStartType, // int iAttributeId, // boolean bPeriodException, // String strPeriodName, // boolean bAdvancePeriodType, // OSSInvalidDataException messageException // ) // { // if ((iPeriod > 0) // || ((iPeriodType != TIMING_NONE) && (iPeriodType != TIMING_NEVER)) // || (bPeriodException) || (iPeriodStartType != PERIOD_START_TYPE_NONE)) // { // if (iPeriod <= 0) // { // if (messageException == null) // { // messageException = new OSSInvalidDataException(); // } // messageException.getErrorMessages().addMessage( // PERIOD_TYPE_OBJ, // "You have to set valid period length for " + strPeriodName + " type." // ); // } // else if ((iPeriodType == TIMING_NONE) || (iPeriodType == TIMING_NEVER)) // { // if (messageException == null) // { // messageException = new OSSInvalidDataException(); // } // messageException.getErrorMessages().addMessage( // PERIOD_TYPE_OBJ, // "You have to set valid period type for " + strPeriodName + " type." // ); // } // else if ((bAdvancePeriodType) && (iPeriodStartType == PERIOD_START_TYPE_NONE)) // { // if (messageException == null) // { // messageException = new OSSInvalidDataException(); // } // messageException.getErrorMessages().addMessage( // PERIOD_TYPE_OBJ, // "You have to set valid period start type for " + strPeriodName + " type." // ); // } // else if ((bAdvancePeriodType) // && (iPeriodStartType == PERIOD_START_TYPE_DYNAMIC) // && (iAttributeId == DataObject.NEW_ID)) // { // if (messageException == null) // { // messageException = new OSSInvalidDataException(); // } // messageException.getErrorMessages().addMessage( // PERIOD_TYPE_OBJ, // "You have to set valid period dynamic start attribute for " // + strPeriodName + " type." // ); // } // } // } }


 </source>
   
  
 
  



Convert milliseconds to readable string

   <source lang="java">
  

/*

   GNU LESSER GENERAL PUBLIC LICENSE
   Copyright (C) 2006 The Lobo Project
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   Contact info: lobochief@users.sourceforge.net
  • /

public class Timing {

 public static double round1(double value) {
   return Math.round(value * 10.0) / 10.0;
 }
 
 public static String getElapsedText(long elapsedMillis) {
   if(elapsedMillis < 60000) {
     double unit = round1(elapsedMillis / 1000.0); 
     return unit + (unit == 1 ? " second" : " seconds");
   }
   else if(elapsedMillis < 60000 * 60) {
     double unit = round1(elapsedMillis / 60000.0); 
     return unit + (unit == 1 ? " minute" : " minutes");
   }
   else if(elapsedMillis < 60000 * 60 * 24) {
     double unit = round1(elapsedMillis / (60000.0 * 60)); 
     return unit + (unit == 1 ? " hour" : " hours");
   }
   else {
     double unit = round1(elapsedMillis / (60000.0 * 60 * 24)); 
     return unit + (unit == 1 ? " day" : " days");
   }
 }

}


 </source>
   
  
 
  



Convert the time to the midnight of the currently set date

   <source lang="java">
  

/*

* Funambol is a mobile platform developed by Funambol, Inc. 
* Copyright (C) 2003 - 2007 Funambol, Inc.
* 
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission 
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE 
* WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
* 
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
* details.
* 
* You should have received a copy of the GNU Affero General Public License 
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
* 
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite 
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.ru.
* 
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
* 
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably 
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/

import java.util.Calendar; import java.util.Date; import java.util.TimeZone;

/**

* Utility class for date manipulation.
* This class gives a simple interface for common Date, Calendar and Timezone
* operations.
* It is possible to apply subsequent transformations to an initial date, and
* retrieve the changed Date object at any point.
*
*/

public class DateUtil {

   //-------------------------------------------------------------- Attributes
   private Calendar cal;
   
   //------------------------------------------------------------ Constructors
   
   /** Inizialize a new instance with the current date */
   public DateUtil() {
       this(new Date());
   }
   
   /** Inizialize a new instance with the given date */
   public DateUtil(Date d) {
       cal = Calendar.getInstance();
       cal.setTime(d);
   }
   
   //---------------------------------------------------------- Public methods
   
   /** Set a new time */
   public void setTime(Date d) {
       cal.setTime(d);
   }
   
   /** Get the current time */
   public Date getTime() {
       return cal.getTime();
   }
   
   /** Get the current TimeZone */
   public String getTZ() {
       return cal.getTimeZone().getID();
   }
   
   /**
    * Convert the time to the midnight of the currently set date.
    * The internal date is changed after this call.
    *
    * @return a reference to this DateUtil, for concatenation.
    */
   public DateUtil toMidnight() {
       
       cal.set(Calendar.HOUR_OF_DAY, 0);
       cal.set(Calendar.MINUTE, 0);
       cal.set(Calendar.SECOND, 0);
       cal.set(Calendar.MILLISECOND,0);
       
       return this;
   }
   
   /**
    * Make the date go back of the specified amount of days
    * The internal date is changed after this call.
    *
    * @return a reference to this DateUtil, for concatenation.
    */
   public DateUtil removeDays(int days) {
       
       Date d = cal.getTime();
       long time = d.getTime();
       time -= days * 24 * 3600 * 1000;
       d.setTime(time);
       cal.setTime(d);
       
       return this;
   }
   
   /**
    * Make the date go forward of the specified amount of minutes
    * The internal date is changed after this call.
    *
    * @return a reference to this DateUtil, for concatenation.
    */
   public DateUtil addMinutes(int minutes) {
       Date d = cal.getTime();
       long time = d.getTime();
       time += minutes * 60 * 1000;
       d.setTime(time);
       cal.setTime(d);
       
       return this;
   }
   
   /**
    * Convert the date to GMT. The internal date is changed
    *
    * @return a reference to this DateUtil, for concatenation.
    */
   public DateUtil toGMT() {
       return toTZ("GMT");
   }
   
   /**
    * Convert the date to the given timezone. The internal date is changed.
    *
    * @param tz The name of the timezone to set
    *
    * @return a reference to this DateUtil, for concatenation.
    */
   public DateUtil toTZ(String tz) {
       cal.setTimeZone(TimeZone.getTimeZone(tz));
       
       return this;
   }
   
   /**
    * Get the days passed from the specified date up to the date provided 
    * in the constructor
    *
    * @param date The starting date
    *
    * @return number of days within date used in constructor and the provided
    * date
    */
   public int getDaysSince(Date date) {
       long millisecs = date.getTime();
       Date d = cal.getTime();
       long time = d.getTime();
       long daysMillisecs = time - millisecs;
       int days = (int)((((daysMillisecs / 1000)/60)/60)/24);
       return days;
   }
   
   /**
    * Utility method wrapping Calendar.after method
    * Compares the date field parameter with the date provided with the constructor
    * answering the question: date from constructor is after the given param date ?
    *
    * @param date The date to be used for comparison
    *
    * @return true if date from constructor is after given param date
    */
   public boolean isAfter(Date date) {
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date);
       return cal.after(cal2);
   }

}


 </source>
   
  
 
  



Determines whether or not a date has any time values (hour, minute, seconds or millisecondsReturns the given date with the time values cleared

   <source lang="java">
  

import java.util.Calendar; import java.util.Date; public class DateUtils {

   /**
*

Checks if two dates are on the same day ignoring time.

    * @param date1  the first date, not altered, not null
    * @param date2  the second date, not altered, not null
    * @return true if they represent the same day
    * @throws IllegalArgumentException if either date is null
    */
   public static boolean isSameDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isSameDay(cal1, cal2);
   }
   
   /**
*

Checks if two calendars represent the same day ignoring time.

    * @param cal1  the first calendar, not altered, not null
    * @param cal2  the second calendar, not altered, not null
    * @return true if they represent the same day
    * @throws IllegalArgumentException if either calendar is null
    */
   public static boolean isSameDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
               cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
               cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
   }
   
   /**
*

Checks if a date is today.

    * @param date the date, not altered, not null.
    * @return true if the date is today.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isToday(Date date) {
       return isSameDay(date, Calendar.getInstance().getTime());
   }
   
   /**
*

Checks if a calendar date is today.

    * @param cal  the calendar, not altered, not null
    * @return true if cal date is today
    * @throws IllegalArgumentException if the calendar is null
    */
   public static boolean isToday(Calendar cal) {
       return isSameDay(cal, Calendar.getInstance());
   }
   
   /**
*

Checks if the first date is before the second date ignoring time.

    * @param date1 the first date, not altered, not null
    * @param date2 the second date, not altered, not null
    * @return true if the first date day is before the second date day.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isBeforeDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isBeforeDay(cal1, cal2);
   }
   
   /**
*

Checks if the first calendar date is before the second calendar date ignoring time.

    * @param cal1 the first calendar, not altered, not null.
    * @param cal2 the second calendar, not altered, not null.
    * @return true if cal1 date is before cal2 date ignoring time.
    * @throws IllegalArgumentException if either of the calendars are null
    */
   public static boolean isBeforeDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       if (cal1.get(Calendar.ERA) < cal2.get(Calendar.ERA)) return true;
       if (cal1.get(Calendar.ERA) > cal2.get(Calendar.ERA)) return false;
       if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) return true;
       if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) return false;
       return cal1.get(Calendar.DAY_OF_YEAR) < cal2.get(Calendar.DAY_OF_YEAR);
   }
   
   /**
*

Checks if the first date is after the second date ignoring time.

    * @param date1 the first date, not altered, not null
    * @param date2 the second date, not altered, not null
    * @return true if the first date day is after the second date day.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isAfterDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isAfterDay(cal1, cal2);
   }
   
   /**
*

Checks if the first calendar date is after the second calendar date ignoring time.

    * @param cal1 the first calendar, not altered, not null.
    * @param cal2 the second calendar, not altered, not null.
    * @return true if cal1 date is after cal2 date ignoring time.
    * @throws IllegalArgumentException if either of the calendars are null
    */
   public static boolean isAfterDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       if (cal1.get(Calendar.ERA) < cal2.get(Calendar.ERA)) return false;
       if (cal1.get(Calendar.ERA) > cal2.get(Calendar.ERA)) return true;
       if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) return false;
       if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) return true;
       return cal1.get(Calendar.DAY_OF_YEAR) > cal2.get(Calendar.DAY_OF_YEAR);
   }
   
   /**
*

Checks if a date is after today and within a number of days in the future.

    * @param date the date to check, not altered, not null.
    * @param days the number of days.
    * @return true if the date day is after today and within days in the future .
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isWithinDaysFuture(Date date, int days) {
       if (date == null) {
           throw new IllegalArgumentException("The date must not be null");
       }
       Calendar cal = Calendar.getInstance();
       cal.setTime(date);
       return isWithinDaysFuture(cal, days);
   }
   
   /**
*

Checks if a calendar date is after today and within a number of days in the future.

    * @param cal the calendar, not altered, not null
    * @param days the number of days.
    * @return true if the calendar date day is after today and within days in the future .
    * @throws IllegalArgumentException if the calendar is null
    */
   public static boolean isWithinDaysFuture(Calendar cal, int days) {
       if (cal == null) {
           throw new IllegalArgumentException("The date must not be null");
       }
       Calendar today = Calendar.getInstance();
       Calendar future = Calendar.getInstance();
       future.add(Calendar.DAY_OF_YEAR, days);
       return (isAfterDay(cal, today) && ! isAfterDay(cal, future));
   }
   
   /** Returns the given date with the time set to the start of the day. */
   public static Date getStart(Date date) {
       return clearTime(date);
   }
   
   /** Returns the given date with the time values cleared. */
   public static Date clearTime(Date date) {
       if (date == null) {
           return null;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       c.set(Calendar.HOUR_OF_DAY, 0);
       c.set(Calendar.MINUTE, 0);
       c.set(Calendar.SECOND, 0);
       c.set(Calendar.MILLISECOND, 0);
       return c.getTime();
   }    
   /** Determines whether or not a date has any time values (hour, minute, 
    * seconds or millisecondsReturns the given date with the time values cleared. */
   /**
    * Determines whether or not a date has any time values.
    * @param date The date.
    * @return true iff the date is not null and any of the date"s hour, minute,
    * seconds or millisecond values are greater than zero.
    */
   public static boolean hasTime(Date date) {
       if (date == null) {
           return false;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       if (c.get(Calendar.HOUR_OF_DAY) > 0) {
           return true;
       }
       if (c.get(Calendar.MINUTE) > 0) {
           return true;
       }
       if (c.get(Calendar.SECOND) > 0) {
           return true;
       }
       if (c.get(Calendar.MILLISECOND) > 0) {
           return true;
       }
       return false;
   }
   /** Returns the given date with time set to the end of the day */
   public static Date getEnd(Date date) {
       if (date == null) {
           return null;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       c.set(Calendar.HOUR_OF_DAY, 23);
       c.set(Calendar.MINUTE, 59);
       c.set(Calendar.SECOND, 59);
       c.set(Calendar.MILLISECOND, 999);
       return c.getTime();
   }
   /** 
    * Returns the maximum of two dates. A null date is treated as being less
    * than any non-null date. 
    */
   public static Date max(Date d1, Date d2) {
       if (d1 == null && d2 == null) return null;
       if (d1 == null) return d2;
       if (d2 == null) return d1;
       return (d1.after(d2)) ? d1 : d2;
   }
   
   /** 
    * Returns the minimum of two dates. A null date is treated as being greater
    * than any non-null date. 
    */
   public static Date min(Date d1, Date d2) {
       if (d1 == null && d2 == null) return null;
       if (d1 == null) return d2;
       if (d2 == null) return d1;
       return (d1.before(d2)) ? d1 : d2;
   }
   /** The maximum date possible. */
   public static Date MAX_DATE = new Date(Long.MAX_VALUE);
   

}


 </source>
   
  
 
  



Get Time From Date

   <source lang="java">
  

/*******************************************************************************

* Copyright 2008 Mjrz.net
* 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
*   http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/

import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; /**

* @author Mjrz contact@mjrz.net
*
*/

public class DateUtils {

 public static final String FORMAT_YYYYMMDD = "yyyy-MM-dd";
 public static final String FORMAT_YYYYMMDD_SLASHES = "yyyy/MM/dd";
 public static final String GENERIC_DISPLAY_FORMAT = "E, dd MMM yyyy";
 public static final String TIME_DISPLAY_FORMAT = "HH mm ss";
 public static final int LAST_WEEK = 1;
 public static final int LAST_MONTH = 2;
 public static final String formatDate(Date dt, String format) {
   GregorianCalendar cal = new GregorianCalendar();
   cal.setTime(dt);
   
   java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(format);
   sdf.setTimeZone(TimeZone.getDefault());     
   return (sdf.format(cal.getTime()));   
 }
 
 public static final String getCurrentDate(String format) {
   Calendar cal = Calendar.getInstance(TimeZone.getDefault());
     java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(format);
     sdf.setTimeZone(TimeZone.getDefault());     
     return (sdf.format(cal.getTime()));
 }
 
 public static final String dateToString(Date dt, String dateformat) {
   GregorianCalendar cal = new GregorianCalendar();
   cal.setTime(dt);
   
   StringBuffer ret = new StringBuffer();
   String separator = new String();
   if(dateformat.equals(DateUtils.FORMAT_YYYYMMDD) ) {
     separator = "-";
   }
   if(dateformat.equals(DateUtils.FORMAT_YYYYMMDD_SLASHES) ) {
     separator = "/";
   }
   ret.append(cal.get(Calendar.YEAR));
   ret.append(separator);
   ret.append(cal.get(Calendar.MONTH) + 1);
   ret.append(separator);
   ret.append(cal.get(Calendar.DATE));
   return ret.toString();
 }
 
 public static final String dateToString(Date dt, String tzString, String dateformat) {
   GregorianCalendar cal = new GregorianCalendar();
   cal.setTime(dt);
   cal.setTimeZone(TimeZone.getTimeZone(tzString));
   
   StringBuffer ret = new StringBuffer();
   String separator = new String();
   if(dateformat.equals(DateUtils.FORMAT_YYYYMMDD) ) {
     separator = "-";
   }
   if(dateformat.equals(DateUtils.FORMAT_YYYYMMDD_SLASHES) ) {
     separator = "/";
   }
   ret.append(cal.get(Calendar.YEAR));
   ret.append(separator);
   ret.append(cal.get(Calendar.MONTH) + 1);
   ret.append(separator);
   ret.append(cal.get(Calendar.DATE));
   return ret.toString();
 }
 public static final String getTimeFromDate(Date dt) {
   Calendar cal = new GregorianCalendar();
   cal.setTime(dt);
   
   StringBuffer ret = new StringBuffer();
   ret.append(cal.get(Calendar.HOUR));
   ret.append(":");
   ret.append(cal.get(Calendar.MINUTE));
   
   return ret.toString();
 }
 
 public static final String getTimeFromDate(Date dt, String tzString) {
   try {
     GregorianCalendar gc = new GregorianCalendar();
     gc.setTime(dt);
     gc.setTimeZone(TimeZone.getTimeZone(tzString));
     StringBuffer ret = new StringBuffer();
     ret.append(gc.get(Calendar.HOUR));
     ret.append(":");
     ret.append(gc.get(Calendar.MINUTE));
     ret.append(" ");
     if(gc.get(Calendar.AM_PM) == 0) {
       ret.append("AM");
     }
     else { 
       ret.append("PM");
     }
     return ret.toString();
   }
   catch(Exception e) {
     return "";
   }
 }
 
 public static final String getDateTimeFromDate(Date dt, String tzString) {
   try {
     GregorianCalendar gc = new GregorianCalendar();
     gc.setTime(dt);
     gc.setTimeZone(TimeZone.getTimeZone(tzString));
     StringBuffer ret = new StringBuffer();
     ret.append(gc.get(Calendar.YEAR));
     ret.append("-");
     ret.append(gc.get(Calendar.MONTH) - 1);
     ret.append("-");
     ret.append(gc.get(Calendar.DATE));
     ret.append(" ");
     ret.append(gc.get(Calendar.HOUR));
     ret.append(":");
     ret.append(gc.get(Calendar.MINUTE));
     ret.append(" ");
     if(gc.get(Calendar.AM_PM) == 0) {
       ret.append("AM");
     }
     else { 
       ret.append("PM");
     }
     return ret.toString();
   }
   catch(Exception e) {
     return "";
   }
 }
 
 public static final String calendarToString(Calendar cal, String dateformat) {
   StringBuffer ret = new StringBuffer();
   if(dateformat.equals(FORMAT_YYYYMMDD) ) {
     ret.append(cal.get(Calendar.YEAR));
     ret.append("-");
     
     String month = null;
     int mo = cal.get(Calendar.MONTH) + 1; /* Calendar month is zero indexed, string months are not */
     if(mo < 10) {
       month = "0" + mo;
     }
     else {
       month = "" + mo;
     }
     ret.append(month);      
     
     ret.append("-");
     
     String date = null;
     int dt = cal.get(Calendar.DATE);
     if(dt < 10) {
       date = "0" + dt;
     }
     else {
       date = "" + dt;
     }
     ret.append(date);
   }
   
   return ret.toString();
 }


 public static final GregorianCalendar getCurrentCalendar(String utimezonestring) {
   try {
     GregorianCalendar gc = new GregorianCalendar();
     gc.setTimeZone(TimeZone.getTimeZone(utimezonestring));
     return gc;
   }
   catch(Exception e) {
     //If exception, return server TimeStamp
     return new GregorianCalendar();
   }
 }
 
 public static String[] getDateRange(int cmd) {
   GregorianCalendar gc = new GregorianCalendar();
   GregorianCalendar gc2 = new GregorianCalendar();
   
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$
   String ret[] = new String[2];
   ret[1] = sdf.format(gc.getTime());
   
   if(cmd == LAST_WEEK) {      
     for(int i = 0; i < 7; i++) {
       gc2.add(Calendar.DATE, -1);
     }
     
   }
   if(cmd == LAST_MONTH) {
     gc2.add(Calendar.MONTH, -1);      
   }
   ret[0] = sdf.format(gc2.getTime());
   return ret;
 }
 public static final String getDayString(int day) {
   switch (day) {
     case Calendar.SUNDAY:
       return "SUNDAY";      
     case Calendar.MONDAY:
       return "MONDAY";
     case Calendar.TUESDAY:
       return "TUESDAY";
     case Calendar.WEDNESDAY:
       return "WEDNESDAY";
     case Calendar.THURSDAY:
       return "THURSDAY";
     case Calendar.FRIDAY:
       return "FRIDAY";
     case Calendar.SATURDAY:
       return "SATURDAY";
   }
   return "";
 }

}


 </source>
   
  
 
  



ISO8601 Date Time Format

   <source lang="java">
  

//revised from skaringa import java.text.DateFormat; import java.text.FieldPosition; import java.text.ParsePosition; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; /**

* Format and parse an ISO 8601 DateTimeFormat used in XML documents.
* This lexical representation is the ISO 8601
* extended format CCYY-MM-DDThh:mm:ss
* where "CC" represents the century, "YY" the year, "MM" the month
* and "DD" the day,
* preceded by an optional leading "-" sign to indicate a negative number.
* If the sign is omitted, "+" is assumed.
* The letter "T" is the date/time separator
* and "hh", "mm", "ss" represent hour, minute and second respectively.
* This representation may be immediately followed by a "Z" to indicate
* Coordinated Universal Time (UTC) or, to indicate the time zone,
* i.e. the difference between the local time and Coordinated Universal Time,
* immediately followed by a sign, + or -,
* followed by the difference from UTC represented as hh:mm.
*
*/

public class ISO8601DateTimeFormat extends DateFormat {

 /**
  * Construct a new ISO8601DateTimeFormat using the default time zone.
  *
  */
 public ISO8601DateTimeFormat() {
   setCalendar(Calendar.getInstance());
 }
 /**
  * Construct a new ISO8601DateTimeFormat using a specific time zone.
  * @param tz The time zone used to format and parse the date.
  */
 public ISO8601DateTimeFormat(TimeZone tz) {
   setCalendar(Calendar.getInstance(tz));
 }
 /**
  * @see DateFormat#parse(String, ParsePosition)
  */
 public Date parse(String text, ParsePosition pos) {
   int i = pos.getIndex();
   try {
     int year = Integer.valueOf(text.substring(i, i + 4)).intValue();
     i += 4;
     if (text.charAt(i) != "-") {
       throw new NumberFormatException();
     }
     i++;
     int month = Integer.valueOf(text.substring(i, i + 2)).intValue() - 1;
     i += 2;
     if (text.charAt(i) != "-") {
       throw new NumberFormatException();
     }
     i++;
     int day = Integer.valueOf(text.substring(i, i + 2)).intValue();
     i += 2;
     if (text.charAt(i) != "T") {
       throw new NumberFormatException();
     }
     i++;
     int hour = Integer.valueOf(text.substring(i, i + 2)).intValue();
     i += 2;
     if (text.charAt(i) != ":") {
       throw new NumberFormatException();
     }
     i++;
     int mins = Integer.valueOf(text.substring(i, i + 2)).intValue();
     i += 2;
     int secs = 0;
     if (i < text.length() && text.charAt(i) == ":") {
       // handle seconds flexible
       i++;
       secs = Integer.valueOf(text.substring(i, i + 2)).intValue();
       i += 2;
     }
     calendar.set(year, month, day, hour, mins, secs);
     calendar.set(Calendar.MILLISECOND, 0); // no parts of a second
     i = parseTZ(i, text);
   }
   catch (NumberFormatException ex) {
     pos.setErrorIndex(i);
     return null;
   }
   catch (IndexOutOfBoundsException ex) {
     pos.setErrorIndex(i);
     return null;
   }
   finally {
     pos.setIndex(i);
   }
   return calendar.getTime();
 }
 /**
  * Parse the time zone.
  * @param i The position to start parsing.
  * @param text The text to parse.
  * @return The position after parsing has finished.
  */
 protected final int parseTZ(int i, String text) {
   if (i < text.length()) {
     // check and handle the zone/dst offset
     int offset = 0;
     if (text.charAt(i) == "Z") {
       offset = 0;
       i++;
     }
     else {
       int sign = 1;
       if (text.charAt(i) == "-") {
         sign = -1;
       }
       else if (text.charAt(i) != "+") {
         throw new NumberFormatException();
       }
       i++;
       int offsetHour = Integer.valueOf(text.substring(i, i + 2)).intValue();
       i += 2;
       if (text.charAt(i) != ":") {
         throw new NumberFormatException();
       }
       i++;
       int offsetMin = Integer.valueOf(text.substring(i, i + 2)).intValue();
       i += 2;
       offset = ((offsetHour * 60) + offsetMin) * 60000 * sign;
     }
     int offsetCal =
       calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
     calendar.add(Calendar.MILLISECOND, offsetCal - offset);
   }
   return i;
 }
 /**
  * @see DateFormat#format(Date, StringBuffer, FieldPosition)
  */
 public StringBuffer format(
   Date date,
   StringBuffer sbuf,
   FieldPosition fieldPosition) {
   calendar.setTime(date);
   writeCCYYMM(sbuf);
   sbuf.append("T");
   writehhmmss(sbuf);
   writeTZ(sbuf);
   return sbuf;
 }
 /**
  * Write the time zone string.
  * @param sbuf The buffer to append the time zone.
  */
 protected final void writeTZ(StringBuffer sbuf) {
   int offset =
     calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
   if (offset == 0) {
     sbuf.append("Z");
   }
   else {
     int offsetHour = offset / 3600000;
     int offsetMin = (offset % 3600000) / 60000;
     if (offset >= 0) {
       sbuf.append("+");
     }
     else {
       sbuf.append("-");
       offsetHour = 0 - offsetHour;
       offsetMin = 0 - offsetMin;
     }
     appendInt(sbuf, offsetHour, 2);
     sbuf.append(":");
     appendInt(sbuf, offsetMin, 2);
   }
 }
 /**
  * Write hour, minutes, and seconds.
  * @param sbuf The buffer to append the string.
  */
 protected final void writehhmmss(StringBuffer sbuf) {
   int hour = calendar.get(Calendar.HOUR_OF_DAY);
   appendInt(sbuf, hour, 2);
   sbuf.append(":");
   int mins = calendar.get(Calendar.MINUTE);
   appendInt(sbuf, mins, 2);
   sbuf.append(":");
   int secs = calendar.get(Calendar.SECOND);
   appendInt(sbuf, secs, 2);
 }
 /**
  * Write century, year, and months.
  * @param sbuf The buffer to append the string.
  */
 protected final void writeCCYYMM(StringBuffer sbuf) {
   int year = calendar.get(Calendar.YEAR);
   appendInt(sbuf, year, 4);
   String month;
   switch (calendar.get(Calendar.MONTH)) {
     case Calendar.JANUARY :
       month = "-01-";
       break;
     case Calendar.FEBRUARY :
       month = "-02-";
       break;
     case Calendar.MARCH :
       month = "-03-";
       break;
     case Calendar.APRIL :
       month = "-04-";
       break;
     case Calendar.MAY :
       month = "-05-";
       break;
     case Calendar.JUNE :
       month = "-06-";
       break;
     case Calendar.JULY :
       month = "-07-";
       break;
     case Calendar.AUGUST :
       month = "-08-";
       break;
     case Calendar.SEPTEMBER :
       month = "-09-";
       break;
     case Calendar.OCTOBER :
       month = "-10-";
       break;
     case Calendar.NOVEMBER :
       month = "-11-";
       break;
     case Calendar.DECEMBER :
       month = "-12-";
       break;
     default :
       month = "-NA-";
       break;
   }
   sbuf.append(month);
   int day = calendar.get(Calendar.DAY_OF_MONTH);
   appendInt(sbuf, day, 2);
 }
 /**
  * Write an integer value with leading zeros.
  * @param buf The buffer to append the string.
  * @param value The value to write.
  * @param length The length of the string to write.
  */
 protected final void appendInt(StringBuffer buf, int value, int length) {
   int len1 = buf.length();
   buf.append(value);
   int len2 = buf.length();
   for (int i = len2; i < len1 + length; ++i) {
     buf.insert(len1, "0");
   }
 }

}


 </source>
   
  
 
  



Returns a formatted String from time

   <source lang="java">
  

/**

* $Revision: 10205 $
* $Date: 2008-04-11 15:48:27 -0700 (Fri, 11 Apr 2008) $
*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/

import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.BreakIterator; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /**

* Utility class to peform common String manipulation algorithms.
*/

public class StringUtils {

   // Constants used by escapeHTMLTags
   private static final char[] QUOTE_ENCODE = """.toCharArray();
   private static final char[] AMP_ENCODE = "&".toCharArray();
   private static final char[] LT_ENCODE = "<".toCharArray();
   private static final char[] GT_ENCODE = ">".toCharArray();
   private StringUtils() {
       // Not instantiable.
   }
   /**
    * Returns a formatted String from time.
    *
    * @param diff the amount of elapsed time.
    * @return the formatte String.
    */
   public static String getTimeFromLong(long diff) {
       final String HOURS = "h";
       final String MINUTES = "min";
       final String SECONDS = "sec";
       final long MS_IN_A_DAY = 1000 * 60 * 60 * 24;
       final long MS_IN_AN_HOUR = 1000 * 60 * 60;
       final long MS_IN_A_MINUTE = 1000 * 60;
       final long MS_IN_A_SECOND = 1000;
       Date currentTime = new Date();
       long numDays = diff / MS_IN_A_DAY;
       diff = diff % MS_IN_A_DAY;
       long numHours = diff / MS_IN_AN_HOUR;
       diff = diff % MS_IN_AN_HOUR;
       long numMinutes = diff / MS_IN_A_MINUTE;
       diff = diff % MS_IN_A_MINUTE;
       long numSeconds = diff / MS_IN_A_SECOND;
       diff = diff % MS_IN_A_SECOND;
       long numMilliseconds = diff;
       StringBuffer buf = new StringBuffer();
       if (numHours > 0) {
           buf.append(numHours + " " + HOURS + ", ");
       }
       if (numMinutes > 0) {
           buf.append(numMinutes + " " + MINUTES);
       }
       //buf.append(numSeconds + " " + SECONDS);
       String result = buf.toString();
       if (numMinutes < 1) {
           result = "< 1 minute";
       }
       return result;
   }

}


 </source>
   
  
 
  



Returns the given date with the time values cleared

   <source lang="java">
  

import java.util.Calendar; import java.util.Date; public class DateUtils {

   /**
*

Checks if two dates are on the same day ignoring time.

    * @param date1  the first date, not altered, not null
    * @param date2  the second date, not altered, not null
    * @return true if they represent the same day
    * @throws IllegalArgumentException if either date is null
    */
   public static boolean isSameDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isSameDay(cal1, cal2);
   }
   
   /**
*

Checks if two calendars represent the same day ignoring time.

    * @param cal1  the first calendar, not altered, not null
    * @param cal2  the second calendar, not altered, not null
    * @return true if they represent the same day
    * @throws IllegalArgumentException if either calendar is null
    */
   public static boolean isSameDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
               cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
               cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
   }
   
   /**
*

Checks if a date is today.

    * @param date the date, not altered, not null.
    * @return true if the date is today.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isToday(Date date) {
       return isSameDay(date, Calendar.getInstance().getTime());
   }
   
   /**
*

Checks if a calendar date is today.

    * @param cal  the calendar, not altered, not null
    * @return true if cal date is today
    * @throws IllegalArgumentException if the calendar is null
    */
   public static boolean isToday(Calendar cal) {
       return isSameDay(cal, Calendar.getInstance());
   }
   
   /**
*

Checks if the first date is before the second date ignoring time.

    * @param date1 the first date, not altered, not null
    * @param date2 the second date, not altered, not null
    * @return true if the first date day is before the second date day.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isBeforeDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isBeforeDay(cal1, cal2);
   }
   
   /**
*

Checks if the first calendar date is before the second calendar date ignoring time.

    * @param cal1 the first calendar, not altered, not null.
    * @param cal2 the second calendar, not altered, not null.
    * @return true if cal1 date is before cal2 date ignoring time.
    * @throws IllegalArgumentException if either of the calendars are null
    */
   public static boolean isBeforeDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       if (cal1.get(Calendar.ERA) < cal2.get(Calendar.ERA)) return true;
       if (cal1.get(Calendar.ERA) > cal2.get(Calendar.ERA)) return false;
       if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) return true;
       if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) return false;
       return cal1.get(Calendar.DAY_OF_YEAR) < cal2.get(Calendar.DAY_OF_YEAR);
   }
   
   /**
*

Checks if the first date is after the second date ignoring time.

    * @param date1 the first date, not altered, not null
    * @param date2 the second date, not altered, not null
    * @return true if the first date day is after the second date day.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isAfterDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isAfterDay(cal1, cal2);
   }
   
   /**
*

Checks if the first calendar date is after the second calendar date ignoring time.

    * @param cal1 the first calendar, not altered, not null.
    * @param cal2 the second calendar, not altered, not null.
    * @return true if cal1 date is after cal2 date ignoring time.
    * @throws IllegalArgumentException if either of the calendars are null
    */
   public static boolean isAfterDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       if (cal1.get(Calendar.ERA) < cal2.get(Calendar.ERA)) return false;
       if (cal1.get(Calendar.ERA) > cal2.get(Calendar.ERA)) return true;
       if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) return false;
       if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) return true;
       return cal1.get(Calendar.DAY_OF_YEAR) > cal2.get(Calendar.DAY_OF_YEAR);
   }
   
   /**
*

Checks if a date is after today and within a number of days in the future.

    * @param date the date to check, not altered, not null.
    * @param days the number of days.
    * @return true if the date day is after today and within days in the future .
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isWithinDaysFuture(Date date, int days) {
       if (date == null) {
           throw new IllegalArgumentException("The date must not be null");
       }
       Calendar cal = Calendar.getInstance();
       cal.setTime(date);
       return isWithinDaysFuture(cal, days);
   }
   
   /**
*

Checks if a calendar date is after today and within a number of days in the future.

    * @param cal the calendar, not altered, not null
    * @param days the number of days.
    * @return true if the calendar date day is after today and within days in the future .
    * @throws IllegalArgumentException if the calendar is null
    */
   public static boolean isWithinDaysFuture(Calendar cal, int days) {
       if (cal == null) {
           throw new IllegalArgumentException("The date must not be null");
       }
       Calendar today = Calendar.getInstance();
       Calendar future = Calendar.getInstance();
       future.add(Calendar.DAY_OF_YEAR, days);
       return (isAfterDay(cal, today) && ! isAfterDay(cal, future));
   }
   
   /** Returns the given date with the time set to the start of the day. */
   public static Date getStart(Date date) {
       return clearTime(date);
   }
   
   /** Returns the given date with the time values cleared. */
   public static Date clearTime(Date date) {
       if (date == null) {
           return null;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       c.set(Calendar.HOUR_OF_DAY, 0);
       c.set(Calendar.MINUTE, 0);
       c.set(Calendar.SECOND, 0);
       c.set(Calendar.MILLISECOND, 0);
       return c.getTime();
   }    
   /** Determines whether or not a date has any time values (hour, minute, 
    * seconds or millisecondsReturns the given date with the time values cleared. */
   /**
    * Determines whether or not a date has any time values.
    * @param date The date.
    * @return true iff the date is not null and any of the date"s hour, minute,
    * seconds or millisecond values are greater than zero.
    */
   public static boolean hasTime(Date date) {
       if (date == null) {
           return false;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       if (c.get(Calendar.HOUR_OF_DAY) > 0) {
           return true;
       }
       if (c.get(Calendar.MINUTE) > 0) {
           return true;
       }
       if (c.get(Calendar.SECOND) > 0) {
           return true;
       }
       if (c.get(Calendar.MILLISECOND) > 0) {
           return true;
       }
       return false;
   }
   /** Returns the given date with time set to the end of the day */
   public static Date getEnd(Date date) {
       if (date == null) {
           return null;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       c.set(Calendar.HOUR_OF_DAY, 23);
       c.set(Calendar.MINUTE, 59);
       c.set(Calendar.SECOND, 59);
       c.set(Calendar.MILLISECOND, 999);
       return c.getTime();
   }
   /** 
    * Returns the maximum of two dates. A null date is treated as being less
    * than any non-null date. 
    */
   public static Date max(Date d1, Date d2) {
       if (d1 == null && d2 == null) return null;
       if (d1 == null) return d2;
       if (d2 == null) return d1;
       return (d1.after(d2)) ? d1 : d2;
   }
   
   /** 
    * Returns the minimum of two dates. A null date is treated as being greater
    * than any non-null date. 
    */
   public static Date min(Date d1, Date d2) {
       if (d1 == null && d2 == null) return null;
       if (d1 == null) return d2;
       if (d2 == null) return d1;
       return (d1.before(d2)) ? d1 : d2;
   }
   /** The maximum date possible. */
   public static Date MAX_DATE = new Date(Long.MAX_VALUE);
   

}


 </source>
   
  
 
  



Returns the given date with time set to the end of the day

   <source lang="java">
  

import java.util.Calendar; import java.util.Date; public class DateUtils {

   /**
*

Checks if two dates are on the same day ignoring time.

    * @param date1  the first date, not altered, not null
    * @param date2  the second date, not altered, not null
    * @return true if they represent the same day
    * @throws IllegalArgumentException if either date is null
    */
   public static boolean isSameDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isSameDay(cal1, cal2);
   }
   
   /**
*

Checks if two calendars represent the same day ignoring time.

    * @param cal1  the first calendar, not altered, not null
    * @param cal2  the second calendar, not altered, not null
    * @return true if they represent the same day
    * @throws IllegalArgumentException if either calendar is null
    */
   public static boolean isSameDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
               cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
               cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
   }
   
   /**
*

Checks if a date is today.

    * @param date the date, not altered, not null.
    * @return true if the date is today.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isToday(Date date) {
       return isSameDay(date, Calendar.getInstance().getTime());
   }
   
   /**
*

Checks if a calendar date is today.

    * @param cal  the calendar, not altered, not null
    * @return true if cal date is today
    * @throws IllegalArgumentException if the calendar is null
    */
   public static boolean isToday(Calendar cal) {
       return isSameDay(cal, Calendar.getInstance());
   }
   
   /**
*

Checks if the first date is before the second date ignoring time.

    * @param date1 the first date, not altered, not null
    * @param date2 the second date, not altered, not null
    * @return true if the first date day is before the second date day.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isBeforeDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isBeforeDay(cal1, cal2);
   }
   
   /**
*

Checks if the first calendar date is before the second calendar date ignoring time.

    * @param cal1 the first calendar, not altered, not null.
    * @param cal2 the second calendar, not altered, not null.
    * @return true if cal1 date is before cal2 date ignoring time.
    * @throws IllegalArgumentException if either of the calendars are null
    */
   public static boolean isBeforeDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       if (cal1.get(Calendar.ERA) < cal2.get(Calendar.ERA)) return true;
       if (cal1.get(Calendar.ERA) > cal2.get(Calendar.ERA)) return false;
       if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) return true;
       if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) return false;
       return cal1.get(Calendar.DAY_OF_YEAR) < cal2.get(Calendar.DAY_OF_YEAR);
   }
   
   /**
*

Checks if the first date is after the second date ignoring time.

    * @param date1 the first date, not altered, not null
    * @param date2 the second date, not altered, not null
    * @return true if the first date day is after the second date day.
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isAfterDay(Date date1, Date date2) {
       if (date1 == null || date2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       Calendar cal1 = Calendar.getInstance();
       cal1.setTime(date1);
       Calendar cal2 = Calendar.getInstance();
       cal2.setTime(date2);
       return isAfterDay(cal1, cal2);
   }
   
   /**
*

Checks if the first calendar date is after the second calendar date ignoring time.

    * @param cal1 the first calendar, not altered, not null.
    * @param cal2 the second calendar, not altered, not null.
    * @return true if cal1 date is after cal2 date ignoring time.
    * @throws IllegalArgumentException if either of the calendars are null
    */
   public static boolean isAfterDay(Calendar cal1, Calendar cal2) {
       if (cal1 == null || cal2 == null) {
           throw new IllegalArgumentException("The dates must not be null");
       }
       if (cal1.get(Calendar.ERA) < cal2.get(Calendar.ERA)) return false;
       if (cal1.get(Calendar.ERA) > cal2.get(Calendar.ERA)) return true;
       if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) return false;
       if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) return true;
       return cal1.get(Calendar.DAY_OF_YEAR) > cal2.get(Calendar.DAY_OF_YEAR);
   }
   
   /**
*

Checks if a date is after today and within a number of days in the future.

    * @param date the date to check, not altered, not null.
    * @param days the number of days.
    * @return true if the date day is after today and within days in the future .
    * @throws IllegalArgumentException if the date is null
    */
   public static boolean isWithinDaysFuture(Date date, int days) {
       if (date == null) {
           throw new IllegalArgumentException("The date must not be null");
       }
       Calendar cal = Calendar.getInstance();
       cal.setTime(date);
       return isWithinDaysFuture(cal, days);
   }
   
   /**
*

Checks if a calendar date is after today and within a number of days in the future.

    * @param cal the calendar, not altered, not null
    * @param days the number of days.
    * @return true if the calendar date day is after today and within days in the future .
    * @throws IllegalArgumentException if the calendar is null
    */
   public static boolean isWithinDaysFuture(Calendar cal, int days) {
       if (cal == null) {
           throw new IllegalArgumentException("The date must not be null");
       }
       Calendar today = Calendar.getInstance();
       Calendar future = Calendar.getInstance();
       future.add(Calendar.DAY_OF_YEAR, days);
       return (isAfterDay(cal, today) && ! isAfterDay(cal, future));
   }
   
   /** Returns the given date with the time set to the start of the day. */
   public static Date getStart(Date date) {
       return clearTime(date);
   }
   
   /** Returns the given date with the time values cleared. */
   public static Date clearTime(Date date) {
       if (date == null) {
           return null;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       c.set(Calendar.HOUR_OF_DAY, 0);
       c.set(Calendar.MINUTE, 0);
       c.set(Calendar.SECOND, 0);
       c.set(Calendar.MILLISECOND, 0);
       return c.getTime();
   }    
   /** Determines whether or not a date has any time values (hour, minute, 
    * seconds or millisecondsReturns the given date with the time values cleared. */
   /**
    * Determines whether or not a date has any time values.
    * @param date The date.
    * @return true iff the date is not null and any of the date"s hour, minute,
    * seconds or millisecond values are greater than zero.
    */
   public static boolean hasTime(Date date) {
       if (date == null) {
           return false;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       if (c.get(Calendar.HOUR_OF_DAY) > 0) {
           return true;
       }
       if (c.get(Calendar.MINUTE) > 0) {
           return true;
       }
       if (c.get(Calendar.SECOND) > 0) {
           return true;
       }
       if (c.get(Calendar.MILLISECOND) > 0) {
           return true;
       }
       return false;
   }
   /** Returns the given date with time set to the end of the day */
   public static Date getEnd(Date date) {
       if (date == null) {
           return null;
       }
       Calendar c = Calendar.getInstance();
       c.setTime(date);
       c.set(Calendar.HOUR_OF_DAY, 23);
       c.set(Calendar.MINUTE, 59);
       c.set(Calendar.SECOND, 59);
       c.set(Calendar.MILLISECOND, 999);
       return c.getTime();
   }
   /** 
    * Returns the maximum of two dates. A null date is treated as being less
    * than any non-null date. 
    */
   public static Date max(Date d1, Date d2) {
       if (d1 == null && d2 == null) return null;
       if (d1 == null) return d2;
       if (d2 == null) return d1;
       return (d1.after(d2)) ? d1 : d2;
   }
   
   /** 
    * Returns the minimum of two dates. A null date is treated as being greater
    * than any non-null date. 
    */
   public static Date min(Date d1, Date d2) {
       if (d1 == null && d2 == null) return null;
       if (d1 == null) return d2;
       if (d2 == null) return d1;
       return (d1.before(d2)) ? d1 : d2;
   }
   /** The maximum date possible. */
   public static Date MAX_DATE = new Date(Long.MAX_VALUE);
   

}


 </source>
   
  
 
  



Returns time string

   <source lang="java">
  

/**

* Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
* 
* Project: OpenSubsystems
* 
* $Id: DateUtils.java,v 1.7 2007/01/07 06:14:00 bastafidli Exp $
* 
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License. 
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
*/

import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar;

/**

* Collection of useful utilities to work with dates. 
* 
* @version $Id: DateUtils.java,v 1.7 2007/01/07 06:14:00 bastafidli Exp $
* @author Miro Halas
* @code.reviewer Miro Halas
* @code.reviewed 1.5 2005/09/13 13:23:15 bastafidli
*/

public final class DateUtils {

  // Constants ////////////////////////////////////////////////////////////////
  
  /**
   * One second in milliseconds.
   */
  public static final long ONE_SECOND = 1000L;
  
  /**
   * One minute in milliseconds.
   */
  public static final long ONE_MINUTE = ONE_SECOND * 60L;
  
  /**
   * One hour in milliseconds.
   */
  public static final long ONE_HOUR = ONE_MINUTE * 60L;
  
  /**
   * One day in milliseconds.
   */
  public static final long ONE_DAY = ONE_HOUR * 24L;
  
  /**
   * Separator we used to separate time from the nanosecond portion of the 
   * timestamp when converted to string.
   */
  public static final char NANO_SEPARATOR = ":";
  
  /**
   * Constant for timing type
   */
  public static final int TIMING_NEVER = 0;
  /**
   * Constant for timing type
   */
  public static final int TIMING_MINUTES = 1;
  /**
   * Constant for timing type
   */
  public static final int TIMING_HOURS = 2;
  /**
   * Constant for timing type
   */
  public static final int TIMING_DAYS = 3;
  /**
   * Constant for timing type
   */
  public static final int TIMING_WEEKS = 4;
  /**
   * Constant for timing type
   */
  public static final int TIMING_MONTHS = 5;
  /**
   * Constant for timing type
   */
  public static final int TIMING_YEARS = 6;
  
  /**
   * Constant for timing type
   */
  public static final int TIMING_NONE = 7;
  /**
   * Constant for current date code used in date/time formulas 
   */
  public static final String CURRENT_DATE_CODE = "now";
  
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char YEAR_CODE = "y";
  
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char MONTH_CODE = "M";
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char WEEK_CODE = "w";
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char DAY_CODE = "d";
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char HOUR_CODE = "h";
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char MINUTE_CODE = "m";
  
  /**
   * Constant for dynamic date code used in date/time formulas
   */
  public static final char SECOND_CODE = "s";
  /**
   * constant for date type DATE
   */
  public static final int DATE_TYPE_DATE = 1;
  /**
   * constant for date type TIME
   */
  public static final int DATE_TYPE_TIME = 2;
  /**
   * constant for date type DATETIME
   */
  public static final int DATE_TYPE_DATETIME = 3;
  
  // Constants for period start types /////////////////////////////////////////

// TODO: For Miro: Remove this code once all the code which referred to these // constants was fixed // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_NONE = 0; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_CREATION = 1; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_COMPLETION = 2; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_APPROVAL = 3; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_ACTIVATION = 4; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_INACTIVATION = 5; // // /** // * constant for period type // */ // public static final int PERIOD_START_TYPE_DYNAMIC = 6; // // /** // * constant for period type code // */ // public static final int PERIOD_TYPE_CODE = 99; // // /** // * constant for period type object // */ // public static final Integer PERIOD_TYPE_OBJ = new Integer(PERIOD_TYPE_CODE);

  // Cached variables /////////////////////////////////////////////////////////
  
  /**
   * static SimpleDateFormat for date format to display on UI and in messages.
   */
  public static final SimpleDateFormat DATE_FORMAT 
                         = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT);
  
  /**
   * static SimpleDateFormat for time format to display on UI and in messages.
   */
  public static final SimpleDateFormat TIME_FORMAT 
                         = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.MEDIUM);
  
  /**
   * static SimpleDateFormat for datetime format to display on UI and in messages.
   */
  public static final SimpleDateFormat DATETIME_FORMAT 
                         = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, 
                                                          DateFormat.MEDIUM); 
  /**
   * static SimpleDateFormat for date format to store date as string so that
   * it is stored consistently.
   */
  public static final SimpleDateFormat DATE_STORE_FORMAT
                         = new SimpleDateFormat("MM/dd/yyyy");
  
  /**
   * static SimpleDateFormat for time format to store time as string so that
   * it is stored consistently.
   */
  public static final SimpleDateFormat TIME_STORE_FORMAT 
                         = new SimpleDateFormat("HH:mm:ss");
  
  /**
   * static SimpleDateFormat for datetime format to store date and time as 
   * string so that it is stored consistently.
   */
  public static final SimpleDateFormat DATETIME_STORE_FORMAT 
                         = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
  /**
   * static SimpleDateFormat for date format for sql date
   */
  public static final SimpleDateFormat DATE_SQL_FORMAT
                         = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
  
  /**
   * static SimpleDateFormat for time format for sql time
   */
  public static final SimpleDateFormat TIME_SQL_FORMAT 
                         = new SimpleDateFormat("1970-01-01 HH:mm:ss");
  
  /**
   * static SimpleDateFormat for datetime format for sql date and time
   */
  public static final SimpleDateFormat DATETIME_SQL_FORMAT 
                         = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  // Constructors /////////////////////////////////////////////////////////////
  
  /** 
   * Private constructor since this class cannot be instantiated
   */
  private DateUtils(
  )
  {
     // Do nothing
  }
  
  // Public methods ///////////////////////////////////////////////////////////
  
  /**
   * Check if two dates equals regardless of the time. Two null dates are equal. 
   * Null and not null dates are not equal.
   * 
   * @param  dtFirst - first date to compare, can be null
   * @param  dtSecond - second date to compare, can be null 
   * @return boolean - true if two dates equals regardless of what the time is 
   */
  public static boolean dateEquals(
     Date dtFirst,
     Date dtSecond
  )
  {
     boolean  bReturn = false;
     
     // If they are the same object, they are equals
     bReturn = (dtFirst == dtSecond);
     if (!bReturn)
     {
        if (dtFirst == null)
        {
           // Two null dates are the same
           bReturn = (dtSecond == null);
        }
        else
        {
           if (dtSecond != null)
           {
              Calendar compCalendar;
              int      iEra;
              int      iYear;
              int      iMonth;
              int      iDay;
              
              compCalendar = Calendar.getInstance();
              compCalendar.setTime(dtFirst);
              iEra   = compCalendar.get(Calendar.ERA);
              iYear  = compCalendar.get(Calendar.YEAR);
              iMonth = compCalendar.get(Calendar.MONTH);
              iDay   = compCalendar.get(Calendar.DATE);
              compCalendar.setTime(dtSecond);
        
              bReturn = ((iEra == compCalendar.get(Calendar.ERA))
                        && (iYear == compCalendar.get(Calendar.YEAR))
                        && (iMonth == compCalendar.get(Calendar.MONTH))
                        && (iDay == compCalendar.get(Calendar.DATE)));
           }
        }
     } 
           
     return bReturn;            
  }
  
  /**
   * Check if two times equals regardless of the date. Two null times are equal. 
   * Null and not null times are not equal.
   * 
   * @param  dtFirst - first time to compare, can be null
   * @param  dtSecond - second time to compare, can be null
   * @param  bIgnoreMilliseconds - if true milliseconds will be ignored in comparison
   * @return boolean - true if two time equals regardless of what the date is 
   */
  public static boolean timeEquals(
     Date    dtFirst,
     Date    dtSecond,
     boolean bIgnoreMilliseconds
  )
  {
     boolean  bReturn = false;
     
     // If they are the same object, they are equals
     bReturn = (dtFirst == dtSecond);
     if (!bReturn)
     {
        if (dtFirst == null)
        {
           // Two null dates are the same
           bReturn = (dtSecond == null);
        }
        else
        {
           if (dtSecond != null)
           {
              Calendar compCalendar;
              int      iHour;
              int      iMinute;
              int      iSecond;
              int      iMili;
              
              compCalendar = Calendar.getInstance();
              compCalendar.setTime(dtFirst);
              iHour   = compCalendar.get(Calendar.HOUR_OF_DAY);
              iMinute = compCalendar.get(Calendar.MINUTE);
              iSecond = compCalendar.get(Calendar.SECOND);
              iMili   = compCalendar.get(Calendar.MILLISECOND);
              compCalendar.setTime(dtSecond);
        
              bReturn = ((iHour == compCalendar.get(Calendar.HOUR_OF_DAY))
                        && (iMinute == compCalendar.get(Calendar.MINUTE))
                        && (iSecond == compCalendar.get(Calendar.SECOND))
                        && ((bIgnoreMilliseconds) 
                           || (iMili == compCalendar.get(Calendar.MILLISECOND))));
           }
        }
     } 
           
     return bReturn;            
  }
  /**
   * Check if two dates and times are equal. Two null dates are equal. Null 
   * and not null dates are not equal.
   * 
   * @param  dtFirst - first date time to compare, can be null
   * @param  dtSecond - second date time to compare, can be null
   * @return boolean - true if two date and times are equal 
   */
  public static boolean dateAndTimeEquals(
     Date dtFirst,
     Date dtSecond
  )
  {
     boolean bReturn = false;
     
     // If they are the same object, they are equals
     bReturn = (dtFirst == dtSecond);
     if (!bReturn)
     {
        if (dtFirst == null)
        {
           // Two null dates are the same
           bReturn = (dtSecond == null);
        }
        else
        {
           if (dtSecond != null)
           {
              // They are both not null so they have to match to millisecond
              // (actually to nanosecond since the getTime takes nanoseconds
              // into account)
              bReturn = (dtFirst.getTime() == dtSecond.getTime());                               
           }
        }
     }
           
     return bReturn;            
  }
  /**
   * Check if String representing date is function or date. Date is a function
   * (formula) if it starts with the current date/time variable which can be 
   * followed by expression describing period from current date.
   *
   * @param strValue - string representation of date or date function
   * @return boolean - date function flag
   */
  public static boolean isFunction(
     String   strValue
  )
  {
     boolean bReturn = false;
     if ((strValue != null) && (strValue.length() > 0) 
        && (strValue.trim().startsWith(CURRENT_DATE_CODE)))
     {
        bReturn = true;
     }
     
     return bReturn;
  }
  
  /**
   * Parse date time value from given string resolving any functions or formulas
   * the string can contain. This method  can be therefore used if the passed 
   * string contains string representation date, time or timestamp or a formula
   * such as now + 3h - 1m + 4d. 
   *
   * @param strValue - string representation of date or date function
   * @param iDateType - date type code, one of the DATE_TYPE_XXX constants
   * @param stored - flag if Date should be parsed using format used for 
   *                 storage or for display
   * @return Timestamp - parsed date or null if date was null
   * @throws OSSInvalidDataException - error during parsing
   */
  public static Timestamp parseDateTime(
     String   strValue,
     int      iDateType,
     boolean  stored
  )
  {
     Timestamp tsReturn = null;
     Calendar workCal = GregorianCalendar.getInstance();
     
     if (strValue != null && strValue.length() > 0)
     {
        strValue = strValue.trim();
        if (strValue.startsWith(CURRENT_DATE_CODE))
        {
           strValue = strValue.replaceAll("[ ]", "");
           // If the user specified "UseCurrent", then substitute the
           // current date/time in the value
           workCal.setTime(new Date());

// Log.getInstance().debug("Parsing current date " + strValue);

           // Parse the date math
           int iBeginIndex = CURRENT_DATE_CODE.length();
           int iMaxLength = strValue.length();
           int iSign = 1;
           int iNumberIndex;
           int iValue;
           char cChar = " ";
           while (iBeginIndex < iMaxLength)
           {
              // This has to be sign
              if (strValue.charAt(iBeginIndex) == "+")
              {
                 iSign = 1;
              }
              else if (strValue.charAt(iBeginIndex) == "-")
              {
                 iSign = -1;
              }
              else
              {
                 // Incorrect String
                 throw new RuntimeException(
                          "Date function is in incorrect format: "
                          + strValue + " at " + strValue.substring(iBeginIndex));
              }
              iBeginIndex++;
              // Now we have to have number
              iNumberIndex = iBeginIndex;
              
              while (((iBeginIndex == iNumberIndex) || Character.isDigit(cChar)) 
                    && (iBeginIndex < iMaxLength))
              {
                 cChar = strValue.charAt(iBeginIndex++);
              }
              // We have to go one back because we should stop on modifier (e.g 1m)
              iBeginIndex--;
              try
              {
                 iValue = Integer.parseInt(strValue.substring(iNumberIndex, iBeginIndex));
              }
              catch (NumberFormatException nmeExc)
              {
                 // Incorrect String
                 throw new RuntimeException(
                          "Date function is in incorrect format: "
                          + strValue + " at " + strValue.substring(iNumberIndex));
              }
              // This has to be modifier: y - year, M - month, w - week, 
              // d - day, h - hour, m - minute, s - second
              cChar = strValue.charAt(iBeginIndex);
              switch(cChar)
              {
                 case(YEAR_CODE):
                 {
                    if (iDateType == DATE_TYPE_TIME)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used YEAR modifier for TIME type");
                    }
                    workCal.add(Calendar.YEAR, iSign * iValue);
                    break;
                 }
                 case(MONTH_CODE):
                 {
                    if (iDateType == DATE_TYPE_TIME)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used MONTH modifier for TIME type");
                    }
                    workCal.add(Calendar.MONTH, iSign * iValue);
                    break;
                 }
                 case(WEEK_CODE):
                 {
                    if (iDateType == DATE_TYPE_TIME)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used WEEK modifier for TIME type");
                    }
                    workCal.add(Calendar.WEEK_OF_YEAR, iSign * iValue);
                    break;
                 }
                 case(DAY_CODE):
                 {
                    if (iDateType == DATE_TYPE_TIME)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used DAY modifier for TIME type");
                    }
                    workCal.add(Calendar.DATE, iSign * iValue);
                    break;
                 }
                 case(HOUR_CODE):
                 {
                    if (iDateType == DATE_TYPE_DATE)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used HOUR modifier for DATE type");
                    }
                    workCal.add(Calendar.HOUR, iSign * iValue);
                    break;
                 }
                 case(MINUTE_CODE):
                 {
                    if (iDateType == DATE_TYPE_DATE)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used MINUTE modifier for DATE type");
                    }
                    workCal.add(Calendar.MINUTE, iSign * iValue);
                    break;
                 }
                 case(SECOND_CODE):
                 {
                    if (iDateType == DATE_TYPE_DATE)
                    {
                       throw new RuntimeException(
                          "Date function is in incorrect format: " +
                          "used SECOND modifier for DATE type");
                    }
                    workCal.add(Calendar.SECOND, iSign * iValue);
                    break;
                 }
                 default:
                 {
                    // Incorrect String
                    throw new RuntimeException(
                          "Date function is in incorrect format: "
                          + strValue + " at " + strValue.substring(iBeginIndex));
                 }
              }
              iBeginIndex++;
           }
           
           tsReturn = new Timestamp(workCal.getTimeInMillis());
           
        }
        else
        {
           try
           {
              if (stored)
              {
                 switch (iDateType)
                 {
                    case (DATE_TYPE_DATE) :
                    {
                       tsReturn = new Timestamp(DATE_STORE_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    case (DATE_TYPE_TIME) :
                    {
                       tsReturn = new Timestamp(TIME_STORE_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    case (DATE_TYPE_DATETIME) :
                    {
                       tsReturn = new Timestamp(DATETIME_STORE_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    default:
                    {
                       assert false : "Unknown date type " + iDateType;
                    }
                 }                  
              }
              else
              {
                 switch (iDateType)
                 {
                    case (DATE_TYPE_DATE) :
                    {
                       tsReturn = new Timestamp(DATE_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    case (DATE_TYPE_TIME) :
                    {
                       tsReturn = new Timestamp(TIME_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    case (DATE_TYPE_DATETIME) :
                    {
                       tsReturn = new Timestamp(DATETIME_FORMAT.parse(strValue).getTime());
                       break;   
                    }
                    default:
                    {
                       assert false : "Unknown date type " + iDateType;
                    }                  
                 }                  
              }
           }
           catch (ParseException peExc)
           {
              throw new RuntimeException(
                    "Date is in incorrect format. Problems with parsing.",
                    peExc);
           }
        }
     }
     return tsReturn;
  }
  
  /**
   * Parse the specified period into string displaying number of days the 
   * period represents. 
   * 
   * @param lPeriod - period in miliseconds
   * @return String - period in format "x day(s)" or "" if not valid period
   */
  public static String parseDayPeriod(
     long lPeriod
  )
  {
     StringBuffer sbReturn = new StringBuffer();
     long lDays = 0L;
     
     if (lPeriod > 0)
     {
        // we will count each started day as counted day 
        lPeriod = lPeriod + DateUtils.ONE_DAY - 1;
        
        lDays = lPeriod / DateUtils.ONE_DAY;
        sbReturn.append(lDays);
        if (lDays == 1L)
        {
           sbReturn.append(" day");
        }
        else
        {
           sbReturn.append(" days");
        }
     }
     else
     {
        sbReturn.append("0 days");
     }
     return sbReturn.toString();
  }
  
  /**
   * Parse the specified period into string displaying date and time the 
   * period represents. 
   * 
   * @param lPeriod - preiod in miliseconds
   * @return String - period in format "x day(s) y hour(s) z minute(s)" 
   *                  or "" if not valid period
   */
  public static String parseDayTimePeriod(
     long lPeriod
  )
  {
     StringBuffer sbReturn = new StringBuffer();
     long lHelp = 0L;
     
     
     if (lPeriod > 0)
     {
        lPeriod = lPeriod + DateUtils.ONE_MINUTE - 1;
        // we will count each started day as counted day 
        lHelp = lPeriod / DateUtils.ONE_DAY;
        if (lHelp > 0)
        {
           sbReturn.append(lHelp);
           if (lHelp == 1L)
           {
              sbReturn.append(" d ");
           }
           else
           {
              sbReturn.append(" d ");
           }
        }
        lPeriod = lPeriod % DateUtils.ONE_DAY;
        lHelp = lPeriod / DateUtils.ONE_HOUR;
        if (lHelp > 0 || sbReturn.length() > 0)
        {
           sbReturn.append(lHelp);
           if (lHelp == 1L)
           {
              sbReturn.append(" h ");
           }
           else
           {
              sbReturn.append(" h ");
           }
        }
        lPeriod = lPeriod % DateUtils.ONE_HOUR;
        lHelp = lPeriod / DateUtils.ONE_MINUTE;
        if (lHelp > 0 || sbReturn.length() > 0)
        {
           sbReturn.append(lHelp);
           if (lHelp == 1L)
           {
              sbReturn.append(" min");
           }
           else
           {
              sbReturn.append(" min");
           }
        }
     }
     else
     {
        sbReturn.append("0 min");
     }
     return sbReturn.toString();
  }
  

// TODO: For Miro: Remove this code once all the code which referred to these // was fixed. These should be moved to a GUI related class. // /** // * Method for list of timing types. // * // * @return List - list of timing types // */ // public static List getTimingTypes( // ) // { // List lstTimingTypes = new ArrayList(); // // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_MINUTES), // "Minute(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_HOURS), "Hour(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_DAYS), "Day(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_WEEKS), "Week(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_MONTHS), "Month(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_YEARS), "Year(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_NEVER), "Never")); // // return lstTimingTypes; // } // /** // * Method for list of timing types with None option. // * // * @return List - list of timing types // */ // public static List getTimingTypesWithNone( // ) // { // List lstTimingTypes = new ArrayList(); // // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_NONE), "None")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_MINUTES), // "Minute(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_HOURS), "Hour(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_DAYS), "Day(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_WEEKS), "Week(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_MONTHS), "Month(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_YEARS), "Year(s)")); // lstTimingTypes.add(new SelectOption(Integer.toString(DateUtils.TIMING_NEVER), "Never")); // // return lstTimingTypes; // } // /** // * Method for getting string name of the timing type. // * // * @param iTimingType - timing type constant // * @return String - string name of timing type // */ // public static String getTimingTypeName( // int iTimingType // ) // { // String outTimingTypeName = "Never"; // switch (iTimingType) // { // case (DateUtils.TIMING_NEVER): // { // outTimingTypeName = "Never"; // break; // } // case (DateUtils.TIMING_MINUTES): // { // outTimingTypeName = "Minute(s)"; // break; // } // case (DateUtils.TIMING_HOURS): // { // outTimingTypeName = "Hour(s)"; // break; // } // case (DateUtils.TIMING_DAYS): // { // outTimingTypeName = "Day(s)"; // break; // } // case (DateUtils.TIMING_WEEKS): // { // outTimingTypeName = "Week(s)"; // break; // } // case (DateUtils.TIMING_MONTHS): // { // outTimingTypeName = "Month(s)"; // break; // } // case (DateUtils.TIMING_YEARS): // { // outTimingTypeName = "Year(s)"; // break; // } // case (DateUtils.TIMING_NONE): // { // outTimingTypeName = "None"; // break; // } // } // // return outTimingTypeName; // }

  /**
   * Get expiration timestamp from start date, period type and duration. For 
   * example if the start date is now, period type is hour and duration is 2
   * then the result will be timestamp representing now + 2 hours.  
   * 
   * @param tsStartDate - start date of period counting
   * @param iPeriodType - one of the period type constant TIMING_XXX 
   * @param iPeriodDuration - period duration, number of time units specified 
   *                          by period type
   * @return Timestamp - date of period expiration or null if any problem
   */
  public static Timestamp getPeriodExpiration(
     Timestamp tsStartDate,
     int       iPeriodType,
     int       iPeriodDuration
  )
  {
     Timestamp tsReturn = null;
     Calendar calHelp;
     if (tsStartDate != null && iPeriodDuration > 0 
           && iPeriodType > TIMING_NEVER && iPeriodType < TIMING_NONE)
     {
        calHelp = Calendar.getInstance();
        calHelp.setTime(tsStartDate);
        
        switch (iPeriodType)
        {
           case (TIMING_MINUTES) :
           {
              calHelp.add(Calendar.MINUTE, iPeriodDuration);
              break;
           }
           case (TIMING_HOURS) :
           {
              calHelp.add(Calendar.HOUR, iPeriodDuration);
              break;
           }
           case (TIMING_DAYS) :
           {
              calHelp.add(Calendar.DATE, iPeriodDuration);
              break;
           }
           case (TIMING_WEEKS) :
           {
              calHelp.add(Calendar.WEEK_OF_YEAR, iPeriodDuration);
              break;
           }
           case (TIMING_MONTHS) :
           {
              calHelp.add(Calendar.MONTH, iPeriodDuration);
              break;
           }
           case (TIMING_YEARS) :
           {
              calHelp.add(Calendar.YEAR, iPeriodDuration);
              break;
           }
           default :
           {
              assert false : "Not supported Timing type " + iPeriodType;
           } 
        }
        tsReturn = new Timestamp(calHelp.getTimeInMillis());
     }
     
     return tsReturn;
  }
  
  /**
   * Method to compare time periods
   * 
   * @param iPeriodType1 - first period type, one of the period type constant 
   *                       TIMING_XXX
   * @param iPeriodDuration1 - first period duration
   * @param iPeriodType2 - second period type, one of the period type constant 
   *                       TIMING_XXX
   * @param iPeriodDuration2 - second period duration
   * @return int - 1 - first period is longer
   *               0 - periods are same
   *              -1 - first period is shorter
   */
  public static int comparePeriods(
     int iPeriodType1,
     int iPeriodDuration1,
     int iPeriodType2,
     int iPeriodDuration2
  )
  {
     int iReturn = 0;
     
     if ((iPeriodType1 != TIMING_NEVER) && (iPeriodType1 != TIMING_NONE) 
        && (iPeriodType2 != TIMING_NEVER) && (iPeriodType2 != TIMING_NONE))
     {
        Timestamp tsTimestamp1 = getPeriodExpiration(
              new Timestamp(0), iPeriodType1, iPeriodDuration1);
        Timestamp tsTimestamp2 = getPeriodExpiration(
              new Timestamp(0), iPeriodType2, iPeriodDuration2);
        
        // TODO: Improve: When would any of these be null?
        if ((tsTimestamp1 != null) && (tsTimestamp2 != null))
        {
           if (tsTimestamp1.after(tsTimestamp2))
           {
              iReturn = 1;
           }
           else if (tsTimestamp2.after(tsTimestamp1))
           {
              iReturn = -1;
           }
        }
     }
     else
     {
        if (iPeriodType1 != iPeriodType2)
        {
           if (iPeriodType1 == TIMING_NEVER)
           {
              iReturn = 1;
           }
           else if (iPeriodType1 == TIMING_NONE)
           {
              iReturn = -1;
           }
           else if (iPeriodType2 == TIMING_NEVER)
           {
              iReturn = -1;
           }
           else if (iPeriodType2 == TIMING_NONE)
           {
              iReturn = 1;
           }
        }
     }
     return iReturn;      
  }
  
  /**
   * Convert timestamp to string including it"s nanosecond portion so that it 
   * can be safely stored in variable of web page.
   * 
   * @param tsTimestamp - timestamp to convert
   * @return String - text containing time and nanosecond portion of timestamp
   */
  public static String getTimestampAsString(
     Timestamp tsTimestamp
  )
  {
     StringBuffer sbTimestamp = new StringBuffer();
     
     sbTimestamp.append(tsTimestamp.getTime());
     sbTimestamp.append(NANO_SEPARATOR);
     sbTimestamp.append(tsTimestamp.getNanos());
     
     return sbTimestamp.toString();
  }
  
  /**
   * Function returns time string in the form MM:SS.MS from the input specified in miliseconds. 
   * 
   * @param lTimeInMiliseconds - time in miliseconds
   * @return String - string representation of miliseconds in the form MM:SS.MS
   */
  public static String getStringTime(
     long lTimeInMiliseconds
  )
  {
     long lTotalMS   = lTimeInMiliseconds;
     long lMS        = lTotalMS % 1000;
     long lTotalSecs = lTotalMS / 1000;
     long lSecs      = lTotalSecs % 60;
     long lTotalMins = lTotalSecs / 60;
     long lMinutes   = lTotalMins % 60;
     long lHours     = lTotalMins / 60;
     StringBuffer sbBuffer = new StringBuffer();
     if (lHours > 0)
     {
        sbBuffer.append(lHours);
        sbBuffer.append(":");
        sbBuffer.append(lMinutes);
        sbBuffer.append(":");
        sbBuffer.append(lSecs);
        sbBuffer.append(".");
        sbBuffer.append(lMS);
     }
     else if (lMinutes > 0)
     {
        sbBuffer.append(lMinutes);
        sbBuffer.append(":");
        sbBuffer.append(lSecs);
        sbBuffer.append(".");
        sbBuffer.append(lMS);
     }
     else if (lSecs > 0)
     {
        sbBuffer.append(lSecs);
        sbBuffer.append(".");
        sbBuffer.append(lMS);
        sbBuffer.append(" seconds");
     }
     else
     {
        sbBuffer.append(lMS);
        sbBuffer.append(" ms");
     }
     
     return sbBuffer.toString();
  }

// TODO: For Miro: Remove this code once all the code which referred to these // was fixed. These should be moved to a GUI or business logic related class. // /** // * Method to check if valid period settings // * // * @param iPeriod - period length // * @param iPeriodType - period type // * @param iPeriodStartType - period start type // * @param iAttributeId - attribute ID for dynamic period start type // * @param bPeriodException - period exception flag // * @param strPeriodName - period name used for exception message // * @param bAdvancePeriodType - flag if advanced period type (includes also start type) // * @param bfideException - invalid data exception // */ // public static void validatePeriod( // int iPeriod, // int iPeriodType, // int iPeriodStartType, // int iAttributeId, // boolean bPeriodException, // String strPeriodName, // boolean bAdvancePeriodType, // OSSInvalidDataException messageException // ) // { // if ((iPeriod > 0) // || ((iPeriodType != TIMING_NONE) && (iPeriodType != TIMING_NEVER)) // || (bPeriodException) || (iPeriodStartType != PERIOD_START_TYPE_NONE)) // { // if (iPeriod <= 0) // { // if (messageException == null) // { // messageException = new OSSInvalidDataException(); // } // messageException.getErrorMessages().addMessage( // PERIOD_TYPE_OBJ, // "You have to set valid period length for " + strPeriodName + " type." // ); // } // else if ((iPeriodType == TIMING_NONE) || (iPeriodType == TIMING_NEVER)) // { // if (messageException == null) // { // messageException = new OSSInvalidDataException(); // } // messageException.getErrorMessages().addMessage( // PERIOD_TYPE_OBJ, // "You have to set valid period type for " + strPeriodName + " type." // ); // } // else if ((bAdvancePeriodType) && (iPeriodStartType == PERIOD_START_TYPE_NONE)) // { // if (messageException == null) // { // messageException = new OSSInvalidDataException(); // } // messageException.getErrorMessages().addMessage( // PERIOD_TYPE_OBJ, // "You have to set valid period start type for " + strPeriodName + " type." // ); // } // else if ((bAdvancePeriodType) // && (iPeriodStartType == PERIOD_START_TYPE_DYNAMIC) // && (iAttributeId == DataObject.NEW_ID)) // { // if (messageException == null) // { // messageException = new OSSInvalidDataException(); // } // messageException.getErrorMessages().addMessage( // PERIOD_TYPE_OBJ, // "You have to set valid period dynamic start attribute for " // + strPeriodName + " type." // ); // } // } // } }


 </source>
   
  
 
  



Tells you if the date part of a datetime is in a certain time range

   <source lang="java">
  

/*

* Copyright Javelin Software, All rights reserved.
*/

import java.util.*; import java.text.*; /**

* The DateUtil is used as a Utility Class for Dates.
* 
* @author Robin Sharp
*/

public class DateUtil {

   public final static long SECOND_MILLIS = 1000;
   public final static long MINUTE_MILLIS = SECOND_MILLIS*60;
   public final static long HOUR_MILLIS = MINUTE_MILLIS*60;
   public final static long DAY_MILLIS = HOUR_MILLIS*24;
   public final static long YEAR_MILLIS = DAY_MILLIS*365;
   public static DateFormat OUT_DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
   public static DateFormat OUT_TIME_FORMAT = new SimpleDateFormat("H:mm:ss");
   public static DateFormat OUT_DATETIME_FORMAT = new SimpleDateFormat("d/M/yyyy H:mm:ss");
   public static DateFormat OUT_TIMESTAMP_FORMAT = new SimpleDateFormat("d/M/yy H:mm:ss.SSS");
   
   public static DateFormat IN_DATE_FORMAT = new SimpleDateFormat("d/M/yy");
   public static DateFormat IN_TIME_FORMAT = new SimpleDateFormat("H:mm:ss");
   public static DateFormat IN_DATETIME_FORMAT = new SimpleDateFormat("d/M/yy H:mm:ss");
   public static DateFormat IN_TIMESTAMP_FORMAT = new SimpleDateFormat("d/M/yy H:mm:ss.SSS");
   
   public static DateFormat DATE_TIME_FORMAT= new SimpleDateFormat( "yyyyMMddkkmmss" );  
   public static Calendar calendar = new GregorianCalendar();
   static
   {
       IN_DATE_FORMAT.setLenient(false);
       IN_TIME_FORMAT.setLenient(false);
       IN_DATETIME_FORMAT.setLenient(false);
   }
   /**
    * Create a new DateTime. To the last second. This will not create any 
    * extra-millis-seconds, which may cause bugs when writing to stores such as
    * databases that round milli-seconds up and down. 
    */
   public static java.util.Date newDateTime()
   {
       return new java.util.Date( (System.currentTimeMillis()/SECOND_MILLIS)*SECOND_MILLIS);
   }
   /**
    * Create a new Date. To the last day.
    */
   public static java.sql.Date newDate()
   {
       return new java.sql.Date( (System.currentTimeMillis()/DAY_MILLIS)*DAY_MILLIS);
   }
   
   /**
    * Create a new Time, with no date component. 
    */
   public static java.sql.Time newTime()
   {
       return new java.sql.Time( System.currentTimeMillis()%DAY_MILLIS);
   }
   
   /**
    * Create a new Timestamp. 
    */
   public static java.sql.Timestamp newTimestamp()
   {
       return new java.sql.Timestamp( System.currentTimeMillis() );
   }
   
   /**
    * Get the seconds difference
    */
   public static int secondsDiff( Date earlierDate, Date laterDate )
   {
       if( earlierDate == null || laterDate == null ) return 0;
       
       return (int)((laterDate.getTime()/SECOND_MILLIS) - (earlierDate.getTime()/SECOND_MILLIS));
   }
   /**
    * Get the minutes difference
    */
   public static int minutesDiff( Date earlierDate, Date laterDate )
   {
       if( earlierDate == null || laterDate == null ) return 0;
       
       return (int)((laterDate.getTime()/MINUTE_MILLIS) - (earlierDate.getTime()/MINUTE_MILLIS));
   }
   
   /**
    * Get the hours difference
    */
   public static int hoursDiff( Date earlierDate, Date laterDate )
   {
       if( earlierDate == null || laterDate == null ) return 0;
       
       return (int)((laterDate.getTime()/HOUR_MILLIS) - (earlierDate.getTime()/HOUR_MILLIS));
   }
   
   /**
    * Get the days difference
    */
   public static int daysDiff( Date earlierDate, Date laterDate )
   {
       if( earlierDate == null || laterDate == null ) return 0;
       
       return (int)((laterDate.getTime()/DAY_MILLIS) - (earlierDate.getTime()/DAY_MILLIS));
   }
   
  /**
   * Roll the java.util.Time forward or backward.
   * @param startDate - The start date
   * @period Calendar.YEAR etc
   * @param amount - Negative to rollbackwards.
   */
   public static java.sql.Time rollTime( java.util.Date startDate, int period, int amount )
   {
       GregorianCalendar gc = new GregorianCalendar();
       gc.setTime(startDate);
       gc.add(period, amount);
       return new java.sql.Time(gc.getTime().getTime());
   }
   
  /**
   * Roll the java.util.Date forward or backward.
   * @param startDate - The start date
   * @period Calendar.YEAR etc
   * @param amount - Negative to rollbackwards.
   */
   public static java.util.Date rollDateTime( java.util.Date startDate, int period, int amount )
   {
       GregorianCalendar gc = new GregorianCalendar();
       gc.setTime(startDate);
       gc.add(period, amount);
       return new java.util.Date(gc.getTime().getTime());
   }
   
  /**
   * Roll the java.sql.Date forward or backward.
   * @param startDate - The start date
   * @period Calendar.YEAR etc
   * @param amount - Negative to rollbackwards.
   */
   public static java.sql.Date rollDate( java.util.Date startDate, int period, int amount )
   {
       GregorianCalendar gc = new GregorianCalendar();
       gc.setTime(startDate);
       gc.add(period, amount);
       return new java.sql.Date(gc.getTime().getTime());
   }
   
  /**
   * Roll the years forward or backward.
   * @param startDate - The start date
   * @param years - Negative to rollbackwards.
   */
   public static java.sql.Date rollYears( java.util.Date startDate, int years )
   {
       return rollDate( startDate, Calendar.YEAR, years );
   }
  /**
   * Roll the days forward or backward.
   * @param startDate - The start date
   * @param months - Negative to rollbackwards.
   */
   public static java.sql.Date rollMonths( java.util.Date startDate, int months )
   {
       return rollDate( startDate, Calendar.MONTH, months );
   }
  /**
   * Roll the days forward or backward.
   * @param startDate - The start date
   * @param days - Negative to rollbackwards.
   */
   public static java.sql.Date rollDays( java.util.Date startDate, int days )
   {
       return rollDate( startDate, Calendar.DATE, days );
   }
   
    /**
     * Checks the day, month and year are equal.
     */
    public static boolean dateEquals( java.util.Date d1, java.util.Date d2 )
    {
       if( d1 == null || d2 == null ) return false;
       
       return d1.getDate() == d2.getDate() &&
              d1.getMonth() == d2.getMonth() &&
              d1.getYear() == d2.getYear();
    }
    
    /**
     * Checks the hour, minute and second are equal.
     */
    public static boolean timeEquals( java.util.Date d1, java.util.Date d2 )
    {
       if( d1 == null || d2 == null ) return false;
       
       return d1.getHours() == d2.getHours() &&
              d1.getMinutes() == d2.getMinutes() &&
              d1.getSeconds() == d2.getSeconds();
    }
   /**
     * Checks the second, hour, month, day, month and year are equal.
     */
    public static boolean dateTimeEquals( java.util.Date d1, java.util.Date d2 )
    {
       if( d1 == null || d2 == null ) return false;               
       
       return d1.getDate() == d2.getDate() &&
              d1.getMonth() == d2.getMonth() &&
              d1.getYear() == d2.getYear() &&
              d1.getHours() == d2.getHours() &&
              d1.getMinutes() == d2.getMinutes() &&
              d1.getSeconds() == d2.getSeconds();
    }
    
    /**
    * Convert an Object of type Classs to an Object.
    */
   public static Object toObject( Class clazz, Object value ) throws ParseException
   {
       if( value == null ) return null;
       if( clazz == null ) return value;
       
       if( java.sql.Date.class.isAssignableFrom( clazz ) ) return toDate( value );
       if( java.sql.Time.class.isAssignableFrom( clazz ) ) return toTime( value );
       if( java.sql.Timestamp.class.isAssignableFrom( clazz ) ) return toTimestamp( value );
       if( java.util.Date.class.isAssignableFrom( clazz ) ) return toDateTime( value );
       
       return value;
   }
   
   /**
    * Convert an Object to a DateTime, without an Exception
    */
   public static java.util.Date getDateTime( Object value )
   {
       try
       {
           return toDateTime( value );
       }
       catch( ParseException pe )
       {
           pe.printStackTrace();
           return null;
       }
   }
   
   /**
    * Convert an Object to a DateTime.
    */
   public static java.util.Date toDateTime( Object value ) throws ParseException
   {
       if( value == null ) return null;        
       if( value instanceof java.util.Date ) return (java.util.Date)value;
       if( value instanceof String )
       {
           if( "".equals( (String)value ) ) return null;
           return IN_DATETIME_FORMAT.parse( (String)value );
       }
               
       return IN_DATETIME_FORMAT.parse( value.toString() );
   }
   
   /**
    * Convert an Object to a Date, without an Exception
    */
   public static java.sql.Date getDate( Object value )
   {
       try
       {
           return toDate( value );
       }
       catch( ParseException pe )
       {
           pe.printStackTrace();
           return null;
       }
   }
   /**
    * Convert an Object to a Date.
    */
   public static java.sql.Date toDate( Object value ) throws ParseException
   {
       if( value == null ) return null;        
       if( value instanceof java.sql.Date ) return (java.sql.Date)value;
       if( value instanceof String )
       {
           if( "".equals( (String)value ) ) return null;
           return new java.sql.Date( IN_DATE_FORMAT.parse( (String)value ).getTime() );
       }
               
       return new java.sql.Date( IN_DATE_FORMAT.parse( value.toString() ).getTime() );
   }
   
   /**
    * Convert an Object to a Time, without an Exception
    */
   public static java.sql.Time getTime( Object value )
   {
       try
       {
           return toTime( value );
       }
       catch( ParseException pe )
       {
           pe.printStackTrace();
           return null;
       }
   }
   
   /**
    * Convert an Object to a Time.
    */
   public static java.sql.Time toTime( Object value ) throws ParseException
   {
       if( value == null ) return null;        
       if( value instanceof java.sql.Time ) return (java.sql.Time)value;
       if( value instanceof String )
       {
           if( "".equals( (String)value ) ) return null;
           return new java.sql.Time( IN_TIME_FORMAT.parse( (String)value ).getTime() );
       }
               
       return new java.sql.Time( IN_TIME_FORMAT.parse( value.toString() ).getTime() );
   }
   
   /**
    * Convert an Object to a Timestamp, without an Exception
    */
   public static java.sql.Timestamp getTimestamp( Object value )
   {
       try
       {
           return toTimestamp( value );
       }
       catch( ParseException pe )
       {
           pe.printStackTrace();
           return null;
       }
   }
   /**
    * Convert an Object to a Timestamp.
    */
   public static java.sql.Timestamp toTimestamp( Object value ) throws ParseException
   {
       if( value == null ) return null;        
       if( value instanceof java.sql.Timestamp ) return (java.sql.Timestamp)value;
       if( value instanceof String )
       {
           if( "".equals( (String)value ) ) return null;
           return new java.sql.Timestamp( IN_TIMESTAMP_FORMAT.parse( (String)value ).getTime() );
       }
               
       return new java.sql.Timestamp( IN_TIMESTAMP_FORMAT.parse( value.toString() ).getTime() );
   }
   
   /**
    * Tells you if the date part of a datetime is in a certain time range.
    */
   public static boolean isTimeInRange( java.sql.Time start, java.sql.Time end, java.util.Date d )
   {
       d=new java.sql.Time(d.getHours(),d.getMinutes(),d.getSeconds());
       
       if (start==null || end==null)
       {
           return false;
       }
       
       if (start.before(end)&&(!(d.after(start)&&d.before(end))))
       {
           return false;
       }
       
       if (end.before(start)&&(!(d.after(end)||d.before(start))))
       {
           return false;
       }   
       return true;
   }
   public static  int getYear( Date date )
   {
       calendar.setTime( date );
       return calendar.get( Calendar.YEAR );
   }
   public static int getMonth( Date date )
   {
       calendar.setTime( date );
       return calendar.get( Calendar.MONTH );
   }
   public static int getDate( Date date )
   {
       calendar.setTime( date );
       return calendar.get( Calendar.DATE );
   }
   public static int getHour( Date date )
   {
       calendar.setTime( date );
       return calendar.get( Calendar.HOUR );
   }
   public static int getMinute( Date date )
   {
       calendar.setTime( date );
       return calendar.get( Calendar.MINUTE );
   }
   public static int getSeconds( Date date )
   {
       calendar.setTime( date );
       return calendar.get( Calendar.SECOND );
   }
   public static int getMillisecond( Date date )
   {
       calendar.setTime( date );
       return calendar.get( Calendar.MILLISECOND );
   }
   
   /**
    * Convert an Object to a String using Dates
    */
   public static String toString( Object date )
   {
       if( date == null ) return null;
       
       if( java.sql.Timestamp.class.isAssignableFrom( date.getClass() ) )
       {
           return OUT_TIMESTAMP_FORMAT.format( date );
       }
       if( java.sql.Time.class.isAssignableFrom( date.getClass() ) )
       {
           return OUT_TIME_FORMAT.format( date );
       }
       if( java.sql.Date.class.isAssignableFrom( date.getClass() ) )
       {
           return OUT_DATE_FORMAT.format( date );
       }
       if( java.util.Date.class.isAssignableFrom( date.getClass() ) )
       {
           return OUT_DATETIME_FORMAT.format( date );
       }
       
       throw new IllegalArgumentException( "Unsupported type " + date.getClass() );
   }

}


 </source>
   
  
 
  



Time Format

   <source lang="java">
  

import java.text.DateFormat; import java.text.FieldPosition; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; /**

* TimeStampFormatter.
* <p/>
* Date: Sep 17, 2005
* Time: 1:01:13 PM
*
* @author 
*/

public class TimeFormat extends DateFormat {

   private static final long ONE_SECOND = 1000l;
   private static final long ONE_MINUTE = ONE_SECOND * 60l;
   private static final long ONE_HOUR = ONE_MINUTE * 60l;
   private static final long ONE_DAY = ONE_HOUR * 24l;
   private SimpleDateFormat secondsFormat = new SimpleDateFormat("s"s"");
   private SimpleDateFormat minuteFormat = new SimpleDateFormat("m"m"");
   private SimpleDateFormat hourFormat = new SimpleDateFormat("H"h"");
   private DateFormat fullFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
   public TimeFormat() {
       final TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
       minuteFormat.setTimeZone(utcTimeZone);
       hourFormat.setTimeZone(utcTimeZone);
   }
   public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
       long time = date.getTime();
       if (time >= ONE_DAY * 365) {
           return fullFormat.format(date, toAppendTo, fieldPosition);
       }
       if (time >= ONE_DAY * 3) {
           toAppendTo.append(time / ONE_DAY);
           toAppendTo.append("d");
           if (time % ONE_DAY != 0) {
               hourFormat.format(date, toAppendTo, fieldPosition);
           }
       }
       else if (time >= ONE_HOUR) {
           toAppendTo.append(time / ONE_HOUR);
           toAppendTo.append("h");
       }
       if (time >= ONE_MINUTE && time % ONE_HOUR !=0) {
           minuteFormat.format(date, toAppendTo, fieldPosition);
       }
       if (time >= ONE_SECOND && time % ONE_MINUTE !=0) {
           secondsFormat.format(date, toAppendTo, fieldPosition);
       }
       return toAppendTo;
   }
   public Date parse(String source, ParsePosition pos) {
       throw new RuntimeException("Not implemented.");
   }

}


 </source>
   
  
 
  



Time Formatter

   <source lang="java">
  

// TimeFormatter.java // $Id: TimeFormatter.java,v 1.5 2000/08/16 21:37:58 ylafon Exp $ // (c) COPYRIGHT MIT and INRIA, 1996. // Please first read the full copyright statement in file COPYRIGHT.html

import java.util.Date; /**

* This class does date formatting using the same format strings accepted by the
* strftime(3) UNIX call. This class has static methods only.
* @author 
*/

public class TimeFormatter {

   private static String[] fullWeekDays =
   {
 "Sunday",
 "Monday",
 "Tuesday",
 "Wednesday",
 "Thursday",
 "Friday",
 "Saturday"
   } ;
   private static String[] abrWeekDays =
   {
 "Sun",
 "Mon",
 "Tue",
 "Wed",
 "Thu",
 "Fri",
 "Sat"
   } ;
   private static String[] fullMonths =
   {
 "January",
 "February",
 "March",
 "April",
 "May",
 "June",
 "July",
 "August",
 "September",
 "October",
 "November",
 "December"
   } ;
   private static String[] abrMonths =
   {
 "Jan",
 "Feb",
 "Mar",
 "Apr",
 "May",
 "Jun",
 "Jul",
 "Aug",
 "Sep",
 "Oct",
 "Nov",
 "Dec"
   } ;
 
   /**
    * Format the given date as a string, according to the given
    * format string.
    * The format string is of the form used by the strftime(3) UNIX
    * call.
    * @param date The date to format
    * @param format The formatting string
    * @return the String with the formatted date.  */
   public static String format(Date date,String format) {
 StringBuffer buf = new StringBuffer(50) ;
 char ch;
 for(int i=0;i<format.length();i++) {
     ch = format.charAt(i) ;
     if(ch == "%") {
   ++i ;
   if(i == format.length()) break ;
   ch = format.charAt(i) ;
   if(ch == "E") {
       // Alternate Era
       ++i;
   } else if(ch == "Q") {
       // Alternate numeric symbols
       ++i;
   }
   if(i == format.length()) break ;
   ch = format.charAt(i) ;
   switch(ch) {
     case "A":
         buf.append(fullWeekDays[date.getDay()]) ;
         break ;
     case "a":
         buf.append(abrWeekDays[date.getDay()]) ;
         break ;
     case "B":
         buf.append(fullMonths[date.getMonth()]) ;
         break ;
     case "b":
     case "h":
         buf.append(abrMonths[date.getMonth()]) ;
         break ;
     case "C":
         appendPadded(buf,(date.getYear()+1900) / 100, 2) ;
         break ;
     case "c":
         buf.append(date.toLocaleString()) ;
         break ;
     case "D":
         buf.append(TimeFormatter.format(date,"%m/%d/%y"));
         break;
         
     case "d":
         appendPadded(buf,date.getDate(),2) ;
         break;
     case "e":
         appendPadded(buf,date.getMonth()+1,2," ") ;
         break;
     case "H":
         appendPadded(buf,date.getHours(),2) ;
         break ;
     case "I":
     case "l":
         int a = date.getHours() % 12 ;
         if(a==0) a = 12 ;
         appendPadded(buf,a,2,ch=="I" ? "0" : " ") ;
         break ;
     case "j":
         buf.append("[?]") ;
         // No simple way to get this as of now
         break ;
     case "k":
         appendPadded(buf,date.getHours(),2," ") ;
         break ;
     case "M":
         appendPadded(buf,date.getMinutes(),2) ;
         break ;
     case "m":
         appendPadded(buf,date.getMonth()+1,2) ;
         break ;
     case "n":
         buf.append("\n") ;
         break ;
     case "p":
         buf.append(date.getHours()<12 ? "am" : "pm") ;
         break;
     case "R":
         buf.append(TimeFormatter.format(date,"%H:%M")) ;
         break ;
     case "r":
         buf.append(TimeFormatter.format(date,"%l:%M%p")) ;
         break ;
     case "S":
         appendPadded(buf,date.getSeconds(),2) ;
         break ;
         
     case "T":
         buf.append(TimeFormatter.format(date,"%H:%M:%S"));
         break ;
     case "t":
         buf.append("\t") ;
         break ;
     case "U":
     case "u":
     case "V":
     case "W":
         buf.append("[?]");
         // Weekdays are a pain, especially
         // without day of year (0-365) ;
         break ;
     case "w":
         buf.append(date.getDay()) ;
         break ;
     case "X":
         buf.append(TimeFormatter.format(date,"%H:%M:%S"));
         break ;
     case "x":
         buf.append(TimeFormatter.format(date,"%B %e, %Y")) ;
         break ;
     case "y":
         appendPadded(buf,(date.getYear()+1900) % 100,2) ;
         break ;
     case "Y":
         appendPadded(buf,(date.getYear()+1900),4) ;
         break ;
     case "Z":
         String strdate = date.toString() ;
         buf.append(strdate.substring(20,23)) ;
         // (!)
         // There should be a better way
         // to do this...
         break ;
     case "%":
         buf.append("%") ;
         break ;
         
   }
     } else {
   buf.append(ch) ;
     }
 }
 return buf.toString() ;
   }
   private static void appendPadded(StringBuffer buf,
            int n,
            int digits,
            char pad) {
 String foo = String.valueOf(n).trim() ;
 for(int i=0;i<digits-foo.length();i++) 
     buf.append(pad);
 buf.append(foo) ;
   }
   private static final void appendPadded(StringBuffer buf,
            int n,
            int digits) {
 appendPadded(buf,n,digits,"0") ;
   }
   /**
    * For testing purposes
    */
   public static void main(String[] args) {
 try {
     System.out.println(TimeFormatter
            .format(new Date(),args[0])) ;
 } catch(Exception ex) {
     ex.printStackTrace() ;
 }
   }

}


 </source>
   
  
 
  



Time library

   <source lang="java">
  

//revised from prefuse import java.lang.reflect.Constructor; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; /**

* Library routines for dealing with times and time spans. All time values
* are given as long values, indicating the number of milliseconds since
* the epoch (January 1, 1970). This is the same time format returned
* by the {@link java.lang.System#currentTimeMillis()} method.
* 
* @author jeffrey heer
*/

public class TimeLib {

   /** Represents a millenium, 1000 years. */
   public static final int MILLENIUM = -1000;
   /** Represents a century, 100 years */
   public static final int CENTURY   = -100;
   /** Represents a decade, 10 years */
   public static final int DECADE    = -10;
   
   private static final double SECOND_MILLIS    = 1000;
   private static final double MINUTE_MILLIS    = SECOND_MILLIS*60;
   private static final double HOUR_MILLIS      = MINUTE_MILLIS*60;
   private static final double DAY_MILLIS       = HOUR_MILLIS * 24.0015;
   private static final double WEEK_MILLIS      = DAY_MILLIS * 7;
   private static final double MONTH_MILLIS     = DAY_MILLIS * 30.43675;
   private static final double YEAR_MILLIS      = WEEK_MILLIS * 52.2;
   private static final double DECADE_MILLIS    = YEAR_MILLIS * 10;
   private static final double CENTURY_MILLIS   = DECADE_MILLIS * 10;
   private static final double MILLENIUM_MILLIS = CENTURY_MILLIS * 10;
   
   private static final int[] CALENDAR_FIELDS = {
       Calendar.YEAR, Calendar.MONTH, Calendar.DATE, Calendar.HOUR_OF_DAY,
       Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND    
   };
   
   private TimeLib() {
       // prevent instantiation
   }
   
   /**
    * Get the number of time units between the two given timestamps.
    * @param t0 the first timestamp (as a long)
    * @param t1 the second timestamp (as a long)
    * @param field the time unit to use, one of the {@link java.util.Calendar}
    * fields, or one of the extended fields provided by this class
    * (MILLENIUM, CENTURY, or DECADE).
    * @return the number of time units between the two timestamps
    */
   public static int getUnitsBetween(long t0, long t1, int field) {
       boolean negative = false;
       if ( t1 < t0 ) {
           long tmp = t1; t1 = t0; t0 = tmp; // swap
           negative = true;
       }
       GregorianCalendar gc1 = new GregorianCalendar();
       GregorianCalendar gc2 = new GregorianCalendar();
       gc1.setTimeInMillis(t0);
       gc2.setTimeInMillis(t1);
       
       // add 2 units less than the estimate to 1st date,
       // then serially add units till we exceed 2nd date
       int est = estimateUnitsBetween(t0, t1, field);
       boolean multiYear = isMultiYear(field);
       if ( multiYear ) {
           gc1.add(Calendar.YEAR, -field*(est-2));
           est = -field*est;
       } else {
           gc1.add(field, est-2);
       }
       int f = multiYear ? Calendar.YEAR : field;
       int inc = multiYear ? -field : 1;
       for( int i=est-inc; ; i+=inc ) {
           gc1.add(f, inc);
           if( gc1.after(gc2) ) {
               return negative ? inc-i : i-inc;
           }
       }
   }
   
   /**
    * Based on code posted at
    *  http://forum.java.sun.ru/thread.jspa?threadID=488676&messageID=2292012
    */
   private static int estimateUnitsBetween(long t0, long t1, int field) {
       long d = t1-t0;
       switch (field) {
       case Calendar.MILLISECOND:
           return (int)d; // this could be very inaccurate. TODO: use long instead of int?
       case Calendar.SECOND:
           return (int)(d / SECOND_MILLIS + .5);
       case Calendar.MINUTE:
           return (int)(d / MINUTE_MILLIS + .5);
       case Calendar.HOUR_OF_DAY:
       case Calendar.HOUR:
           return (int)(d / HOUR_MILLIS + .5);
       case Calendar.DAY_OF_WEEK_IN_MONTH :
       case Calendar.DAY_OF_MONTH :
       // case Calendar.DATE : // codes to same int as DAY_OF_MONTH
           return (int) (d / DAY_MILLIS + .5);
       case Calendar.WEEK_OF_YEAR :
           return (int) (d / WEEK_MILLIS + .5);
       case Calendar.MONTH :
           return (int) (d / MONTH_MILLIS + .5);
       case Calendar.YEAR :
           return (int) (d / YEAR_MILLIS + .5);
       case DECADE:
           return (int) (d / DECADE_MILLIS + .5);
       case CENTURY:
           return (int) (d / CENTURY_MILLIS + .5);
       case MILLENIUM:
           return (int) (d / MILLENIUM_MILLIS + .5);
       default:
           return 0;
       }
   }
       
   /**
    * Increment a calendar by a given number of time units.
    * @param c the calendar to increment
    * @param field the time unit to increment, one of the
    * {@link java.util.Calendar} fields, or one of the extended fields
    * provided by this class (MILLENIUM, CENTURY, or DECADE).
    * @param val the number of time units to increment by
    */
   public static void increment(Calendar c, int field, int val) {
       if ( isMultiYear(field) ) {
           c.add(Calendar.YEAR, -field*val);
       } else {
           c.add(field, val);
       }
   }
   
   /**
    * Get the value of the given time field for a Calendar. Just like the
    * {@link java.util.Calendar#get(int)} method, but include support for
    * the extended fields provided by this class (MILLENIUM, CENTURY, or
    * DECADE).
    * @param c the Calendar
    * @param field the time field
    * @return the value of the time field for the given calendar
    */
   public static int get(Calendar c, int field) {
       if ( isMultiYear(field) ) {
           int y = c.get(Calendar.YEAR);
           return -field * (y/-field);
       } else {
           return c.get(field);
       }
   }
   
   // ------------------------------------------------------------------------
   // Date Access
   
   /**
    * Get the timestamp for the given year, month, and, day.
    * @param c a Calendar to use to help compute the result. The state of the
    * Calendar will be overwritten.
    * @param year the year to look up
    * @param month the month to look up (months start at 0==January)
    * @param day the day to look up
    * @return the timestamp for the given date
    */
   public static long getDate(Calendar c, int year, int month, int day) {
       c.clear(Calendar.MILLISECOND);
       c.set(year, month, day, 0, 0, 0);
       return c.getTimeInMillis();
   }
   /**
    * Get a timestamp for the given hour, minute, and second. The date will
    * be assumed to be January 1, 1970.
    * @param c a Calendar to use to help compute the result. The state of the
    * Calendar will be overwritten.
    * @param hour the hour, on a 24 hour clock
    * @param minute the minute value
    * @param second the seconds value
    * @return the timestamp for the given date
    */
   public static long getTime(Calendar c, int hour, int minute, int second) {
       c.clear(Calendar.MILLISECOND);
       c.set(1970, 0, 1, hour, minute, second);
       return c.getTimeInMillis();
   }
   
   /**
    * Get a new Date instance of the specified subclass and given long value.
    * @param type the concrete subclass of the Date instance, must be an
    * instance of subclass of java.util.Date
    * @param d the date/time value as a long
    * @return the new Date instance, or null if the class type is not valid
    */
   public static Date getDate(Class type, long d) {
       try {
           Constructor c = type.getConstructor(new Class[] {long.class});
           return (Date)c.newInstance(new Object[] {new Long(d)});
       } catch ( Exception e ) {
           e.printStackTrace();
           return null;
       }
   }
   
   // ------------------------------------------------------------------------
   // Date Normalization
   
   /**
    * Get the timestamp resulting from clearing (setting to zero) all time
    * values less than or equal to that of the given field. For example,
    * clearing to {@link Calendar#HOUR} will floor the time to nearest
    * hour which occurred before or at the given time (e.g., 1:32
    * --> 1:30).
    * @param t the reference time
    * @param c a Calendar instance used to help compute the value, the
    * state of the Calendar will be overwritten.
    * @param field the time field to clear to, one of the
    * {@link java.util.Calendar} fields, or one of the extended fields
    * provided by this class (MILLENIUM, CENTURY, or DECADE).
    * @return the cleared time
    */
   public static long getClearedTime(long t, Calendar c, int field) {
       c.setTimeInMillis(t);
       TimeLib.clearTo(c, field);
       return c.getTimeInMillis();
   }
   
   /**
    * Clear the given calendar, setting to zero all time
    * values less than or equal to that of the given field. For example,
    * clearing to {@link Calendar#HOUR} will floor the time to nearest
    * hour which occurred before or at the given time (e.g., 1:32
    * --> 1:30).
    * @param c the Calendar to clear
    * @param field the time field to clear to, one of the
    * {@link java.util.Calendar} fields, or one of the extended fields
    * provided by this class (MILLENIUM, CENTURY, or DECADE).
    * @return the original Calendar reference, now set to the cleared time
    */
   public static Calendar clearTo(Calendar c, int field) {
       int i = CALENDAR_FIELDS.length-1;
       for ( ; i>=1 && field != CALENDAR_FIELDS[i]; i-- ) {
           int val = (CALENDAR_FIELDS[i]==Calendar.DATE?1:0);
           c.set(CALENDAR_FIELDS[i],val);
       }
       if ( isMultiYear(field) ) {
           int y = c.get(Calendar.YEAR);
           y = -field * (y/-field);
           c.set(Calendar.YEAR, y);
       }
       return c;
   }
   
   /**
    * Indicates if a field value indicates a timespan greater than one
    * year. These multi-year spans are the extended fields introduced by
    * this class (MILLENIUM, CENTURY, and DECADE).
    * @param field the time field
    * @return true if the field is multi-year, false otherwise
    */
   public static boolean isMultiYear(int field) {
       return ( field == DECADE || field == CENTURY || field == MILLENIUM );
   }
   

} // end of class TimeLib


 </source>