Java/Development Class/Time

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

Compare both times and dates

   
/**
 * 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."
//            );
//         }
//      }
//   }
}





Convert milliseconds to readable string

   
/*
    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");
    }
  }
}





Convert the time to the midnight of the currently set date

   
/*
 * 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);
    }
}





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

   

import java.util.Calendar;
import java.util.Date;
public class DateUtils {
    
    /**
     * <p>Checks if two dates are on the same day ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if two calendars represent the same day ignoring time.</p>
     * @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 <code>null</code>
     */
    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));
    }
    
    /**
     * <p>Checks if a date is today.</p>
     * @param date the date, not altered, not null.
     * @return true if the date is today.
     * @throws IllegalArgumentException if the date is <code>null</code>
     */
    public static boolean isToday(Date date) {
        return isSameDay(date, Calendar.getInstance().getTime());
    }
    
    /**
     * <p>Checks if a calendar date is today.</p>
     * @param cal  the calendar, not altered, not null
     * @return true if cal date is today
     * @throws IllegalArgumentException if the calendar is <code>null</code>
     */
    public static boolean isToday(Calendar cal) {
        return isSameDay(cal, Calendar.getInstance());
    }
    
    /**
     * <p>Checks if the first date is before the second date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first calendar date is before the second calendar date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first date is after the second date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first calendar date is after the second calendar date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if a date is after today and within a number of days in the future.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if a calendar date is after today and within a number of days in the future.</p>
     * @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 <code>null</code>
     */
    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);
    
}





Get Time From Date

   
/*******************************************************************************
 * 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 "";
  }
}





ISO8601 Date Time Format

   
//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");
    }
  }
}





Returns a formatted String from time

   
/**
 * $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 = "&quot;".toCharArray();
    private static final char[] AMP_ENCODE = "&amp;".toCharArray();
    private static final char[] LT_ENCODE = "&lt;".toCharArray();
    private static final char[] GT_ENCODE = "&gt;".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;
    }
}





Returns the given date with the time values cleared

   

import java.util.Calendar;
import java.util.Date;
public class DateUtils {
    
    /**
     * <p>Checks if two dates are on the same day ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if two calendars represent the same day ignoring time.</p>
     * @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 <code>null</code>
     */
    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));
    }
    
    /**
     * <p>Checks if a date is today.</p>
     * @param date the date, not altered, not null.
     * @return true if the date is today.
     * @throws IllegalArgumentException if the date is <code>null</code>
     */
    public static boolean isToday(Date date) {
        return isSameDay(date, Calendar.getInstance().getTime());
    }
    
    /**
     * <p>Checks if a calendar date is today.</p>
     * @param cal  the calendar, not altered, not null
     * @return true if cal date is today
     * @throws IllegalArgumentException if the calendar is <code>null</code>
     */
    public static boolean isToday(Calendar cal) {
        return isSameDay(cal, Calendar.getInstance());
    }
    
    /**
     * <p>Checks if the first date is before the second date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first calendar date is before the second calendar date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first date is after the second date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first calendar date is after the second calendar date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if a date is after today and within a number of days in the future.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if a calendar date is after today and within a number of days in the future.</p>
     * @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 <code>null</code>
     */
    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);
    
}





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

   

import java.util.Calendar;
import java.util.Date;
public class DateUtils {
    
    /**
     * <p>Checks if two dates are on the same day ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if two calendars represent the same day ignoring time.</p>
     * @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 <code>null</code>
     */
    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));
    }
    
    /**
     * <p>Checks if a date is today.</p>
     * @param date the date, not altered, not null.
     * @return true if the date is today.
     * @throws IllegalArgumentException if the date is <code>null</code>
     */
    public static boolean isToday(Date date) {
        return isSameDay(date, Calendar.getInstance().getTime());
    }
    
    /**
     * <p>Checks if a calendar date is today.</p>
     * @param cal  the calendar, not altered, not null
     * @return true if cal date is today
     * @throws IllegalArgumentException if the calendar is <code>null</code>
     */
    public static boolean isToday(Calendar cal) {
        return isSameDay(cal, Calendar.getInstance());
    }
    
    /**
     * <p>Checks if the first date is before the second date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first calendar date is before the second calendar date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first date is after the second date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if the first calendar date is after the second calendar date ignoring time.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if a date is after today and within a number of days in the future.</p>
     * @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 <code>null</code>
     */
    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);
    }
    
    /**
     * <p>Checks if a calendar date is after today and within a number of days in the future.</p>
     * @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 <code>null</code>
     */
    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);
    
}





Returns time string

   
/**
 * 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."
//            );
//         }
//      }
//   }
}





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

   
/*
 * 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() );
    }
}





Time Format

   

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.");
    }
}





Time Formatter

   
// 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() ;
  }
    }
}





Time library

   
//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