Java/Data Type/Date

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

A formatter that formats dates to show the elapsed time relative to some base date.

   <source lang="java">
  

/*

* JFreeChart : a free chart library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
*
* Project Info:  http://www.jfree.org/jfreechart/index.html
*
* 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 Street, Fifth Floor, Boston, MA  02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -----------------------
* RelativeDateFormat.java
* -----------------------
* (C) Copyright 2006-2008, by Object Refinery Limited and Contributors.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   Michael Siemer;
*
* Changes:
* --------
* 01-Nov-2006 : Version 1 (DG);
* 23-Nov-2006 : Added argument checks, updated equals(), added clone() and
*               hashCode() (DG);
* 15-Feb-2008 : Applied patch 1873328 by Michael Siemer, with minor
*               modifications (DG);
* 01-Sep-2008 : Added new fields for hour and minute formatting, based on
*               patch 2033092 (DG);
*
*/

import java.text.DateFormat; import java.text.DecimalFormat; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParsePosition; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; /**

* A formatter that formats dates to show the elapsed time relative to some
* base date.
*
* @since 1.0.3
*/

public class RelativeDateFormat extends DateFormat {

   /** The base milliseconds for the elapsed time calculation. */
   private long baseMillis;
   /**
    * A flag that controls whether or not a zero day count is displayed.
    */
   private boolean showZeroDays;
   /**
    * A flag that controls whether or not a zero hour count is displayed.
    *
    * @since 1.0.10
    */
   private boolean showZeroHours;
   /**
    * A formatter for the day count (most likely not critical until the
    * day count exceeds 999).
    */
   private NumberFormat dayFormatter;
   /**
    * A prefix prepended to the start of the format if the relative date is
    * positive.
    *
    * @since 1.0.10
    */
   private String positivePrefix;
   /**
    * A string appended after the day count.
    */
   private String daySuffix;
   /**
    * A formatter for the hours.
    *
    * @since 1.0.11
    */
   private NumberFormat hourFormatter;
   /**
    * A string appended after the hours.
    */
   private String hourSuffix;
   /**
    * A formatter for the minutes.
    *
    * @since 1.0.11
    */
   private NumberFormat minuteFormatter;
   /**
    * A string appended after the minutes.
    */
   private String minuteSuffix;
   /**
    * A formatter for the seconds (and milliseconds).
    */
   private NumberFormat secondFormatter;
   /**
    * A string appended after the seconds.
    */
   private String secondSuffix;
   /**
    * A constant for the number of milliseconds in one hour.
    */
   private static long MILLISECONDS_IN_ONE_HOUR = 60 * 60 * 1000L;
   /**
    * A constant for the number of milliseconds in one day.
    */
   private static long MILLISECONDS_IN_ONE_DAY = 24 * MILLISECONDS_IN_ONE_HOUR;
   /**
    * Creates a new instance with base milliseconds set to zero.
    */
   public RelativeDateFormat() {
       this(0L);
   }
   /**
    * Creates a new instance.
    *
    * @param time  the date/time (null not permitted).
    */
   public RelativeDateFormat(Date time) {
       this(time.getTime());
   }
   /**
    * Creates a new instance.
    *
    * @param baseMillis  the time zone (null not permitted).
    */
   public RelativeDateFormat(long baseMillis) {
       super();
       this.baseMillis = baseMillis;
       this.showZeroDays = false;
       this.showZeroHours = true;
       this.positivePrefix = "";
       this.dayFormatter = NumberFormat.getNumberInstance();
       this.daySuffix = "d";
       this.hourFormatter = NumberFormat.getNumberInstance();
       this.hourSuffix = "h";
       this.minuteFormatter = NumberFormat.getNumberInstance();
       this.minuteSuffix = "m";
       this.secondFormatter = NumberFormat.getNumberInstance();
       this.secondFormatter.setMaximumFractionDigits(3);
       this.secondFormatter.setMinimumFractionDigits(3);
       this.secondSuffix = "s";
       // we don"t use the calendar or numberFormat fields, but equals(Object)
       // is failing without them being non-null
       this.calendar = new GregorianCalendar();
       this.numberFormat = new DecimalFormat("0");
   }
   /**
    * Returns the base date/time used to calculate the elapsed time for
    * display.
    *
    * @return The base date/time in milliseconds since 1-Jan-1970.
    *
    * @see #setBaseMillis(long)
    */
   public long getBaseMillis() {
       return this.baseMillis;
   }
   /**
    * Sets the base date/time used to calculate the elapsed time for display.
    * This should be specified in milliseconds using the same encoding as
    * java.util.Date.
    *
    * @param baseMillis  the base date/time in milliseconds.
    *
    * @see #getBaseMillis()
    */
   public void setBaseMillis(long baseMillis) {
       this.baseMillis = baseMillis;
   }
   /**
    * Returns the flag that controls whether or not zero day counts are
    * shown in the formatted output.
    *
    * @return The flag.
    *
    * @see #setShowZeroDays(boolean)
    */
   public boolean getShowZeroDays() {
       return this.showZeroDays;
   }
   /**
    * Sets the flag that controls whether or not zero day counts are shown
    * in the formatted output.
    *
    * @param show  the flag.
    *
    * @see #getShowZeroDays()
    */
   public void setShowZeroDays(boolean show) {
       this.showZeroDays = show;
   }
   /**
    * Returns the flag that controls whether or not zero hour counts are
    * shown in the formatted output.
    *
    * @return The flag.
    *
    * @see #setShowZeroHours(boolean)
    *
    * @since 1.0.10
    */
   public boolean getShowZeroHours() {
       return this.showZeroHours;
   }
   /**
    * Sets the flag that controls whether or not zero hour counts are shown
    * in the formatted output.
    *
    * @param show  the flag.
    *
    * @see #getShowZeroHours()
    *
    * @since 1.0.10
    */
   public void setShowZeroHours(boolean show) {
       this.showZeroHours = show;
   }
   /**
    * Returns the string that is prepended to the format if the relative time
    * is positive.
    *
    * @return The string (never null).
    *
    * @see #setPositivePrefix(String)
    *
    * @since 1.0.10
    */
   public String getPositivePrefix() {
       return this.positivePrefix;
   }
   /**
    * Sets the string that is prepended to the format if the relative time is
    * positive.
    *
    * @param prefix  the prefix (null not permitted).
    *
    * @see #getPositivePrefix()
    *
    * @since 1.0.10
    */
   public void setPositivePrefix(String prefix) {
       if (prefix == null) {
           throw new IllegalArgumentException("Null "prefix" argument.");
       }
       this.positivePrefix = prefix;
   }
   /**
    * Sets the formatter for the days.
    *
    * @param formatter  the formatter (null not permitted).
    *
    * @since 1.0.11
    */
   public void setDayFormatter(NumberFormat formatter) {
       if (formatter == null) {
           throw new IllegalArgumentException("Null "formatter" argument.");
       }
       this.dayFormatter = formatter;
   }
   /**
    * Returns the string that is appended to the day count.
    *
    * @return The string.
    *
    * @see #setDaySuffix(String)
    */
   public String getDaySuffix() {
       return this.daySuffix;
   }
   /**
    * Sets the string that is appended to the day count.
    *
    * @param suffix  the suffix (null not permitted).
    *
    * @see #getDaySuffix()
    */
   public void setDaySuffix(String suffix) {
       if (suffix == null) {
           throw new IllegalArgumentException("Null "suffix" argument.");
       }
       this.daySuffix = suffix;
   }
   /**
    * Sets the formatter for the hours.
    *
    * @param formatter  the formatter (null not permitted).
    *
    * @since 1.0.11
    */
   public void setHourFormatter(NumberFormat formatter) {
       if (formatter == null) {
           throw new IllegalArgumentException("Null "formatter" argument.");
       }
       this.hourFormatter = formatter;
   }
   /**
    * Returns the string that is appended to the hour count.
    *
    * @return The string.
    *
    * @see #setHourSuffix(String)
    */
   public String getHourSuffix() {
       return this.hourSuffix;
   }
   /**
    * Sets the string that is appended to the hour count.
    *
    * @param suffix  the suffix (null not permitted).
    *
    * @see #getHourSuffix()
    */
   public void setHourSuffix(String suffix) {
       if (suffix == null) {
           throw new IllegalArgumentException("Null "suffix" argument.");
       }
       this.hourSuffix = suffix;
   }
   /**
    * Sets the formatter for the minutes.
    *
    * @param formatter  the formatter (null not permitted).
    *
    * @since 1.0.11
    */
   public void setMinuteFormatter(NumberFormat formatter) {
       if (formatter == null) {
           throw new IllegalArgumentException("Null "formatter" argument.");
       }
       this.minuteFormatter = formatter;
   }
   /**
    * Returns the string that is appended to the minute count.
    *
    * @return The string.
    *
    * @see #setMinuteSuffix(String)
    */
   public String getMinuteSuffix() {
       return this.minuteSuffix;
   }
   /**
    * Sets the string that is appended to the minute count.
    *
    * @param suffix  the suffix (null not permitted).
    *
    * @see #getMinuteSuffix()
    */
   public void setMinuteSuffix(String suffix) {
       if (suffix == null) {
           throw new IllegalArgumentException("Null "suffix" argument.");
       }
       this.minuteSuffix = suffix;
   }
   /**
    * Returns the string that is appended to the second count.
    *
    * @return The string.
    *
    * @see #setSecondSuffix(String)
    */
   public String getSecondSuffix() {
       return this.secondSuffix;
   }
   /**
    * Sets the string that is appended to the second count.
    *
    * @param suffix  the suffix (null not permitted).
    *
    * @see #getSecondSuffix()
    */
   public void setSecondSuffix(String suffix) {
       if (suffix == null) {
           throw new IllegalArgumentException("Null "suffix" argument.");
       }
       this.secondSuffix = suffix;
   }
   /**
    * Sets the formatter for the seconds and milliseconds.
    *
    * @param formatter  the formatter (null not permitted).
    */
   public void setSecondFormatter(NumberFormat formatter) {
       if (formatter == null) {
           throw new IllegalArgumentException("Null "formatter" argument.");
       }
       this.secondFormatter = formatter;
   }
   /**
    * Formats the given date as the amount of elapsed time (relative to the
    * base date specified in the constructor).
    *
    * @param date  the date.
    * @param toAppendTo  the string buffer.
    * @param fieldPosition  the field position.
    *
    * @return The formatted date.
    */
   public StringBuffer format(Date date, StringBuffer toAppendTo,
                              FieldPosition fieldPosition) {
       long currentMillis = date.getTime();
       long elapsed = currentMillis - this.baseMillis;
       String signPrefix;
       if (elapsed < 0) {
           elapsed *= -1L;
           signPrefix = "-";
       }
       else {
           signPrefix = this.positivePrefix;
       }
       long days = elapsed / MILLISECONDS_IN_ONE_DAY;
       elapsed = elapsed - (days * MILLISECONDS_IN_ONE_DAY);
       long hours = elapsed / MILLISECONDS_IN_ONE_HOUR;
       elapsed = elapsed - (hours * MILLISECONDS_IN_ONE_HOUR);
       long minutes = elapsed / 60000L;
       elapsed = elapsed - (minutes * 60000L);
       double seconds = elapsed / 1000.0;
       toAppendTo.append(signPrefix);
       if (days != 0 || this.showZeroDays) {
           toAppendTo.append(this.dayFormatter.format(days) + getDaySuffix());
       }
       if (hours != 0 || this.showZeroHours) {
           toAppendTo.append(this.hourFormatter.format(hours)
                   + getHourSuffix());
       }
       toAppendTo.append(this.minuteFormatter.format(minutes)
               + getMinuteSuffix());
       toAppendTo.append(this.secondFormatter.format(seconds)
               + getSecondSuffix());
       return toAppendTo;
   }
   /**
    * Parses the given string (not implemented).
    *
    * @param source  the date string.
    * @param pos  the parse position.
    *
    * @return null, as this method has not been implemented.
    */
   public Date parse(String source, ParsePosition pos) {
       return null;
   }
   /**
    * Tests this formatter for equality with an arbitrary object.
    *
    * @param obj  the object (null permitted).
    *
    * @return A boolean.
    */
   public boolean equals(Object obj) {
       if (obj == this) {
           return true;
       }
       if (!(obj instanceof RelativeDateFormat)) {
           return false;
       }
       if (!super.equals(obj)) {
           return false;
       }
       RelativeDateFormat that = (RelativeDateFormat) obj;
       if (this.baseMillis != that.baseMillis) {
           return false;
       }
       if (this.showZeroDays != that.showZeroDays) {
           return false;
       }
       if (this.showZeroHours != that.showZeroHours) {
           return false;
       }
       if (!this.positivePrefix.equals(that.positivePrefix)) {
           return false;
       }
       if (!this.daySuffix.equals(that.daySuffix)) {
           return false;
       }
       if (!this.hourSuffix.equals(that.hourSuffix)) {
           return false;
       }
       if (!this.minuteSuffix.equals(that.minuteSuffix)) {
           return false;
       }
       if (!this.secondSuffix.equals(that.secondSuffix)) {
           return false;
       }
       if (!this.dayFormatter.equals(that.dayFormatter)) {
           return false;
       }
       if (!this.hourFormatter.equals(that.hourFormatter)) {
           return false;
       }
       if (!this.minuteFormatter.equals(that.minuteFormatter)) {
           return false;
       }
       if (!this.secondFormatter.equals(that.secondFormatter)) {
           return false;
       }
       return true;
   }
   /**
    * Returns a hash code for this instance.
    *
    * @return A hash code.
    */
   public int hashCode() {
       int result = 193;
       result = 37 * result
               + (int) (this.baseMillis ^ (this.baseMillis >>> 32));
       result = 37 * result + this.positivePrefix.hashCode();
       result = 37 * result + this.daySuffix.hashCode();
       result = 37 * result + this.hourSuffix.hashCode();
       result = 37 * result + this.minuteSuffix.hashCode();
       result = 37 * result + this.secondSuffix.hashCode();
       result = 37 * result + this.secondFormatter.hashCode();
       return result;
   }
   /**
    * Returns a clone of this instance.
    *
    * @return A clone.
    */
   public Object clone() {
       RelativeDateFormat clone = (RelativeDateFormat) super.clone();
       clone.dayFormatter = (NumberFormat) this.dayFormatter.clone();
       clone.secondFormatter = (NumberFormat) this.secondFormatter.clone();
       return clone;
   }
   /**
    * Some test code.
    *
    * @param args  ignored.
    */
   public static void main(String[] args) {
       GregorianCalendar c0 = new GregorianCalendar(2006, 10, 1, 0, 0, 0);
       GregorianCalendar c1 = new GregorianCalendar(2006, 10, 1, 11, 37, 43);
       c1.set(Calendar.MILLISECOND, 123);
       System.out.println("Default: ");
       RelativeDateFormat rdf = new RelativeDateFormat(c0.getTime().getTime());
       System.out.println(rdf.format(c1.getTime()));
       System.out.println();
       System.out.println("Hide milliseconds: ");
       rdf.setSecondFormatter(new DecimalFormat("0"));
       System.out.println(rdf.format(c1.getTime()));
       System.out.println();
       System.out.println("Show zero day output: ");
       rdf.setShowZeroDays(true);
       System.out.println(rdf.format(c1.getTime()));
       System.out.println();
       System.out.println("Alternative suffixes: ");
       rdf.setShowZeroDays(false);
       rdf.setDaySuffix(":");
       rdf.setHourSuffix(":");
       rdf.setMinuteSuffix(":");
       rdf.setSecondSuffix("");
       System.out.println(rdf.format(c1.getTime()));
       System.out.println();
   }

}


 </source>
   
  
 
  



Check if a String is a valid date

   <source lang="java">
   

import java.text.ParseException; import java.text.SimpleDateFormat; public class Main {

 public static boolean isValidDate(String inDate) {
   SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
   dateFormat.setLenient(false);
   try {
     dateFormat.parse(inDate.trim());
   } catch (ParseException pe) {
     return false;
   }
   return true;
 }
 public static void main(String[] args) {
   System.out.println(isValidDate("2004-02-29"));
   System.out.println(isValidDate("2005-02-29"));
 }

} /* true false

  • /



 </source>
   
  
 
  



Collection of useful utilities to work with dates

   <source lang="java">
 

/*

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

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

/**

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

public final class DateUtils {

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

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

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

* Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
* 
* Project: OpenSubsystems
* 
* $Id: TimestampCopy.java,v 1.5 2007/01/07 06:14:01 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 
*/

/**

* Timestamp which adds copy constructor which correctly copies nanosecond 
* portion of the original timestamp. 
* 
* @version $Id: TimestampCopy.java,v 1.5 2007/01/07 06:14:01 bastafidli Exp $
* @author Miro Halas
* @code.reviewer Miro Halas
* @code.reviewed 1.3 2006/02/17 06:54:53 bastafidli
*/

class TimestampCopy extends Timestamp {

  // Attributes ///////////////////////////////////////////////////////////////
  
  /**
   * Generated serial version id for this class.
   */
  private static final long serialVersionUID = 135570135998694876L;
  // Constructors /////////////////////////////////////////////////////////////
  
  /**
   * Copy constructor which will create exact copy of the timestamp including
   * the nanosecond portion.
   * 
   * @param original - original timestamp to copy
   */
  public TimestampCopy(
     Timestamp original
  )
  {
     // Pass the time portion here
     super(original.getTime());
     // And now set the correct nanoseconds since it is required.
     setNanos(original.getNanos());
  }
  /**
   * Constructor which will create exact copy of the timestamp including
   * the nanosecond portion.
   * 
   * @param lTime - time portion of the timestamp
   * @param iNanos - nanosecond portion of the timestamp
   */
  public TimestampCopy(
     long lTime,
     int  iNanos
  )
  {
     // Pass the time portion here
     super(lTime);
     // And now set the correct nanoseconds since it is required.
     setNanos(iNanos);
  }

}


 </source>
   
  
 
  



Compare two Java Date objects using after method example

   <source lang="java">
   

import java.util.Date; public class Main {

 public static void main(String[] args) {
   Date d1 = new Date();
   Date d2 = new Date();
   System.out.println("First Date : " + d1);
   System.out.println("Second Date : " + d2);
   System.out.println("Is second date after first ? : " + d2.after(d1));
 }

}



 </source>
   
  
 
  



Compare two Java Date objects using before method example

   <source lang="java">
   

import java.util.Date; public class Main {

 public static void main(String[] args) {
   Date d1 = new Date();
   Date d2 = new Date();
   System.out.println("First Date : " + d1);
   System.out.println("Second Date : " + d2);
   System.out.println("Is first date before second ? : " + d1.before(d2));
 }

}



 </source>
   
  
 
  



Compare two Java Date objects using compareTo method example

   <source lang="java">
   

import java.util.Date; public class Main {

 public static void main(String[] args) {
   Date d1 = new Date();
   Date d2 = new Date();
   System.out.println("First Date : " + d1);
   System.out.println("Second Date : " + d2);
   int results = d1.rupareTo(d2);
   if (results > 0) {
     System.out.println("after");
   } else if (results < 0) {
     System.out.println("before");
   } else {
     System.out.println("Both dates are equal");
   }
 }

}



 </source>
   
  
 
  



Convert a String to Date

   <source lang="java">
   

import java.text.SimpleDateFormat; import java.util.Date; public class Main {

 public static void main(String[] args) throws Exception {
   SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
   Date theDate = dateFormat.parse("01/01/2009");
   System.out.println(dateFormat.format(theDate));
 }

} //01/01/2009



 </source>
   
  
 
  



Convert Date into milliseconds example

   <source lang="java">
   

import java.util.Date; public class Main {

 public static void main(String args[]) {
   Date date = new Date();
   System.out.println("Date is : " + date);
   System.out.println("Milliseconds since January 1, 1970, 00:00:00 GMT : " + date.getTime());
 }

}



 </source>
   
  
 
  



Convert date string from one format to another format using SimpleDateFormat

   <source lang="java">
   

import java.text.SimpleDateFormat; import java.util.Date; public class Main {

 public static void main(String[] args) throws Exception {
   SimpleDateFormat sdfSource = new SimpleDateFormat("dd/MM/yy");
   Date date = sdfSource.parse("12/11/09");
   SimpleDateFormat sdfDestination = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss");
   System.out.println(sdfDestination.format(date));
 }

}



 </source>
   
  
 
  



Convert string of time to time object

   <source lang="java">
   

import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; public class Main {

 public static void main(String[] args) throws Exception {
   String time = "15:30:18";
   DateFormat sdf = new SimpleDateFormat("hh:mm:ss");
   Date date = sdf.parse(time);
   System.out.println("Date and Time: " + date);
 }

}



 </source>
   
  
 
  



Convert String to Date object

   <source lang="java">
   

import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; public class Main {

 public static void main(String[] args) throws Exception{
   DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
   Date today = df.parse("20/12/2005");
   System.out.println("Today = " + df.format(today));
 }

}



 </source>
   
  
 
  



Create instance of java.sql.Date from Calendar.getTimeInMillis()

   <source lang="java">
   
   

import java.util.Calendar; public class Main {

 public static void main(String[] args) {
   int year = 2009;
   int month = 0; // January
   int date = 1;
   Calendar cal = Calendar.getInstance();
   cal.clear();
   cal.set(Calendar.YEAR, year);
   cal.set(Calendar.MONTH, month);
   cal.set(Calendar.DATE, date);
   java.sql.Date sqlDate = new java.sql.Date(cal.getTimeInMillis());
   System.out.println(sqlDate);
 }

} //2009-01-01



 </source>
   
  
 
  



Create java Date from specific time example

   <source lang="java">
   

import java.util.Date; public class Main {

 public static void main(String[] args) {
   Date d = new Date(365L * 24L * 60L * 60L * 1000L);
   System.out.println(d);
 }

}



 </source>
   
  
 
  



Creating a Date Object for a Particular Date

   <source lang="java">
   

import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class Main {

 public static void main(String[] argv) throws Exception {
   Calendar xmas = new GregorianCalendar(1998, Calendar.DECEMBER, 25);
   Date date = xmas.getTime();
 }

}



 </source>
   
  
 
  



Date utility class

   <source lang="java">
 

/*

*    D E E P B L A C K    B L O G    L I C E N S E
* 
*
* Copyright (c) 2001-2003 Timothy J. Kettering  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The names "deepBlack" must not be used to endorse or promote 
*    products derived from this software without prior written 
*    permission. For written permission, please contact 
*    the copyright holder at tim@blackcore.ru.
*
* 
* THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* 
*/

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

* Date utility class file.
* @author timster@blackcore.ru
* Nov 17, 2002
*
* @todo - Only the timestamp parameter methods have been tested somewhat
* extensively to be sure they return correct timestamps.  The string
* and integer parameter methods need to be refined for accurate behavior, and
* better failsafes.
* 
*/

public class DateUtility {

 /**
  * Returns a primitive long which represents the timestamp of the first millisecond
  * of the month matching the supplied parameters.  This method assumes the
  * default timezone.
  * @param year
  * @param month
  * @return long
  */
 static public long getFirstMilliOfMonth(String year, String month)
 {
   return getFirstMilliOfMonth(year, month, TimeZone.getDefault());
 }
 /**
  * Returns a primitive long which represents the timestamp of the last millisecond
  * of the month matching the supplied parameters.  This method assumes the
  * default timezone.
  * @param year
  * @param month
  * @return long
  */ 
 static public long getLastMilliOfMonth(String year, String month)
 {
   return getLastMilliOfMonth(year, month, TimeZone.getDefault());
 } 
 /**
  * This utility returns the first millsecond 
  * of the month, and year, and timezone supplied as arguments.
  *
  * @param String month
  * @param String year
  * @param TimeZone tz
  * @return long
  */
 static public long getFirstMilliOfMonth(String year, String month, TimeZone tz)
 {
   return getFirstMilliOfMonth(Integer.parseInt(year), Integer.parseInt(month), tz);
 }
 /**
  * This utility returns the first millsecond 
  * of the month, and year, and timezone supplied as arguments.
  *
  * @param int month
  * @param int year
  * @param TimeZone tz
  * @return long
  */
 static public long getFirstMilliOfMonth(int year, int month, TimeZone tz)
 {
   GregorianCalendar cal = new GregorianCalendar(year, (month - 1), 1);
   cal.setTimeZone(tz);
   return cal.getTime().getTime();
 }
 
 /**
  * This will retun the first millisecond of the month 
  * that contains the timestamp provided
  * @param timestamp
  * @return long
  */
 static public long getFirstMilliOfMonth(long timestamp, TimeZone tz)
 {
   GregorianCalendar cal = new GregorianCalendar();
   cal.setTimeZone(tz);
   cal.setTime(new Date(timestamp));
   cal.set(Calendar.DAY_OF_MONTH, 1);
   cal.set(Calendar.HOUR_OF_DAY, 0);
   cal.set(Calendar.MINUTE, 0);
   cal.set(Calendar.SECOND, 0);
   cal.set(Calendar.MILLISECOND, 0);
   
   Date date = cal.getTime();
   
   return date.getTime();
 }
 
 /**
  * Gets the last millsecond of the month, according to the timestamp and 
  * timezone arguments.
  * @param timestamp
  * @param tz
  * @return long
  */
 static public long getLastMilliOfMonth(long timestamp, TimeZone tz)
 {
   timestamp = getFirstMilliOfMonth(timestamp, tz);
   
   GregorianCalendar cal = new GregorianCalendar();
   cal.setTimeZone(tz);
   cal.setTime(new Date(timestamp));
   // now we"ll roll the calendar forward one month.
   // in the case of december, we need to roll forward the year too    
   if(cal.get(GregorianCalendar.MONTH) == GregorianCalendar.DECEMBER)
   {
     cal.roll(GregorianCalendar.YEAR, true);
   }
   
   cal.roll(GregorianCalendar.MONTH, true);
   
   long date = cal.getTime().getTime();
   
   date = date - 1L;
   return date;
 }
 
 /**
  * This utility returns the last millsecond 
  * of the month, and year, and timezone supplied as arguments.
  *
  * @param String month
  * @param String year
  * @param TimeZone tz
  * @return long
  */
 static public long getLastMilliOfMonth(String year, String month, TimeZone tz)
 {
   long time = getLastMilliOfMonth(Integer.parseInt(year), Integer.parseInt(month), tz);
   return time;
 } 
 
 /**
  * This utility returns the last millsecond 
  * of the month, and year, and timezone supplied as arguments.
  *
  * @param int month
  * @param int year
  * @param TimeZone tz
  * @return long
  */
 static public long getLastMilliOfMonth(int year, int month, TimeZone tz)
 {     
   GregorianCalendar cal = new GregorianCalendar(year, (month - 1), 1);
   cal.setTimeZone(tz);
   
   // set the maximum last day
   int lastday = cal.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
   cal.set(GregorianCalendar.DAY_OF_MONTH, lastday);
   // set other calendar maximums.  - we should do this programatically
   // too but i"m too lazy, and i dont think they"re gonna change the gregorian
   // calendar anytime soon.. eh?
   cal.set(GregorianCalendar.HOUR_OF_DAY, 23);
   cal.set(GregorianCalendar.MINUTE, 59);
   cal.set(GregorianCalendar.SECOND, 59);
   cal.set(GregorianCalendar.MILLISECOND, 999);
   long time = cal.getTime().getTime();
   return time;
 } 

}


 </source>
   
  
 
  



Date Utils

   <source lang="java">
 

/*

    • Caramel - Non-GUI Java Addons
    • Copyright (c) 2001, 2002, 2003 by Gerald Bauer
    • This program is free software.
    • You may redistribute it and/or modify it under the terms of the GNU
    • Lesser General Public License as published by the Free Software Foundation.
    • Version 2.1 of the license should be included with this distribution in
    • the file LICENSE, as well as License.html. If the license is not
    • included with this distribution, you may find a copy at the FSF web
    • site at "www.gnu.org" or "www.fsf.org", or you may write to the
    • Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
    • THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
    • NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
    • OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
    • CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
    • REDISTRIBUTION OF THIS SOFTWARE.
  • /

import java.text.*; import java.util.*; public class DateUtils {

  /**
   *  RFC 1123 date format example: Mon, 06 May 1996 04:57:00 GMT - days: Mon,
   *  Tue, Wed, Thu, Fri, Sat, Sun - months: Jan, Feb, Mar, Apr, May, Jun, Jul,
   *  Aug, Sep, Oct, Nov, Dec
   */
  private static SimpleDateFormat _df;
  public static String getDate()
  {
     Calendar cal = Calendar.getInstance();
     cal.setTime( new Date() );
     int year = cal.get( Calendar.YEAR );
     int month = cal.get( Calendar.MONTH ) + 1;
     int day = cal.get( Calendar.DAY_OF_MONTH );
     return "" + year
            + "-" + month
            + "-" + day;
  }
  /**
   *  convienence method returns current timestamp
   */
  public static String getHttpDate()
  {
     return getHttpDate( new Date() );
  }
  public static String getHttpDate( long timestamp )
  {
     return getHttpDate( new Date( timestamp ) );
  }
  public static String getHttpDate( Date date )
  {
     return _df.format( date );
  }
  public static String getTime()
  {
     Calendar cal = Calendar.getInstance();
     cal.setTime( new Date() );
     int hours = cal.get( Calendar.HOUR_OF_DAY );
     // use 24 hour clock
     int minutes = cal.get( Calendar.MINUTE );
     int seconds = cal.get( Calendar.SECOND );
     int milli = cal.get( Calendar.MILLISECOND );
     return formatTime( hours, minutes, seconds, milli );
  }
  public static String getTimestamp()
  {
     Calendar cal = Calendar.getInstance();
     cal.setTime( new Date() );
     int year = cal.get( Calendar.YEAR );
     int month = cal.get( Calendar.MONTH ) + 1;
     int day = cal.get( Calendar.DAY_OF_MONTH );
     int hours = cal.get( Calendar.HOUR_OF_DAY );
     // use 24 hour clock
     int minutes = cal.get( Calendar.MINUTE );
     int seconds = cal.get( Calendar.SECOND );
     int milli = cal.get( Calendar.MILLISECOND );
     return "" + year
            + "-" + month
            + "-" + day
            + "_" + formatTime( hours, minutes, seconds, milli );
  }
  private static String formatTime( int hours, int minutes, int seconds, int milli )
  {
     StringBuffer buf = new StringBuffer();
     buf.append( "" + hours );
     buf.append( "." );
     if( minutes < 10 )
        buf.append( "0" + minutes );
     else
        buf.append( "" + minutes );
     buf.append( "." );
     if( seconds < 10 )
        buf.append( "0" + seconds );
     else
        buf.append( "" + seconds );
     buf.append( "-" );
     if( milli < 10 )
        buf.append( "00" + milli );
     else if( milli < 100 )
        buf.append( "0" + milli );
     else
        buf.append( "" + milli );
     return buf.toString();
  }
  static
  {
     _df = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US );
     _df.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
  }

}


 </source>
   
  
 
  



Encapsulates a truck-load of commonly used date functions

   <source lang="java">
 

/*

* Copyright (C) 2007 The Android Open Source Project
* 
* 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.util.Calendar; /**

* Encapsulates a truck-load of commonly used date functions.
* 
* @author barclay
*/

public final class DateUtil {

 private Calendar mCal;
 private DateUtil.Period mSpan;
 private int mSpanOffset = 0;
 private boolean mUnitChange = false;
 /** Number of milliseconds in a second */
 public static final long SECOND_MS = 1000;
 /** Number of milliseconds in a minute */
 public static final long MINUTE_MS = SECOND_MS * 60;
 /** Number of milliseconds in an hour */
 public static final long HOUR_MS = MINUTE_MS * 60;
 /** Number of milliseconds in a morning or evening (1/2 day) */
 public static final long AMPM_MS = HOUR_MS * 12;
 /** Number of milliseconds in a day */
 public static final long DAY_MS = HOUR_MS * 24;
 /** Number of milliseconds in a week */
 public static final long WEEK_MS = DAY_MS * 7;
 /** Number of milliseconds in a year */
 public static final long YEAR_MS = WEEK_MS * 52;
 /** Number of milliseconds in a quarter (as defined by 1/4 of a year) */
 public static final long QUARTER_MS = WEEK_MS * 13;
 /** Number of milliseconds in a month (as defined by 1/12 of a year) */
 public static final long MONTH_MS = YEAR_MS / 12;
 /**
  * Encapsulation of a date broken down by both milliseconds since epoch (as
  * defined by the system), and year, month, day, hour, minute, and second. The
  * reason for storing both is essentially to cache information and glue the
  * variable together into a single item. Purely convenience.
  * 
  * @author barclay
  */
 public static class DateItem {
   public int mYear = 0;
   public int mMonth = 0;
   public int mDay = 0;
   public int mHour = 0;
   public int mMinute = 0;
   public int mSecond = 0;
   public long mMillis = 0;
   /**
    * Set all the fields of the DateItem to the date/time represented by the
    * current value of the Calendar passed in.
    * 
    * @param c
    *          The Calendar that"s the source data.
    */
   public void setTo(Calendar c) {
     mYear = c.get(Calendar.YEAR);
     mMonth = c.get(Calendar.MONTH);
     mDay = c.get(Calendar.DAY_OF_MONTH);
     mHour = c.get(Calendar.HOUR_OF_DAY);
     mMinute = c.get(Calendar.MINUTE);
     mSecond = c.get(Calendar.SECOND);
     mMillis = c.getTimeInMillis();
   }
   /**
    * Compares all the fields of the DateItem to another DateItem. All fields
    * are compared, instead of just the millisecond field, in the event that
    * all the fields are not in sync for some reason.
    * 
    * @param other
    * @return true if the two DateItems are equal in all fields, else false.
    */
   public boolean isEqual(DateItem other) {
     if (this.mYear == other.mYear && this.mMonth == other.mMonth
         && this.mDay == other.mDay && this.mHour == other.mHour
         && this.mMinute == other.mMinute && this.mSecond == other.mSecond
         && this.mMillis == other.mMillis)
       return true;
     return false;
   }
 }
 private DateItem mBase;
 private DateItem mCursor;
 /**
  * Code shoulder reference these Periods when refering to spans of time
  * instead of Calendar.*, as Calendar doesn"t support the notion of a strict
  * QUARTER, and we use WEEK slightly differently.
  * 
  * @author barclay
  */
 public enum Period {
   MINUTE, HOUR, AMPM, DAY, WEEK, MONTH, QUARTER, YEAR
 }
 public Period[] PERIODS = { Period.MINUTE, Period.HOUR, Period.AMPM,
     Period.DAY, Period.WEEK, Period.MONTH, Period.QUARTER, Period.YEAR };
 public static final String[] MONTHS = { "Jan", "Feb", "Mar", "Apr", "May",
     "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 public static final String[] DAYS = { "Sun", "M", "Tu", "W", "Th", "F",
     "Sat", };
 public static final String[] QUARTERS = { "Q1", "Q2", "Q3", "Q4", };
 /**
  * Constructor. Instantiates a Calendar member variable to prevent having to
  * continually fetch an instance, which is moderately expensive, and create
  * cursor used to walk a timeline.
  */
 public DateUtil() {
   mCal = Calendar.getInstance();
   mBase = new DateItem();
   mCursor = new DateItem();
 }
 /**
  * Returns the internal Calendar object in it"s current state.
  * 
  * @return The Calendar.
  */
 public Calendar getCalendar() {
   return mCal;
 }
 /**
  * Used when going to stride along a timeline. This sets the start time of the
  * walk.
  * 
  * @param ms
  *          The start time in milliseconds since epoch.
  */
 public void setBaseTime(long ms) {
   mBase.mMillis = ms;
   millisToComponent(mBase);
   copyDate(mBase, mCursor);
 }
 /**
  * Returns the milliseconds until the next Period, as based on the difference
  * between the current cursor and the Period. If the current cursor is at the
  * start of a Period, ignoring milliseconds, 0 is returned.
  * 
  * @param u
  * @return milliseconds until next period.
  */
 public long msToNextPeriod(Period u) {
   long ms = 0;
   switch (u) {
     case YEAR:
       mCal.set(mCursor.mYear + 1, 0, 0, 0, 0, 0);
       ms = mCal.getTimeInMillis() - mCursor.mMillis;
       if (ms == YEAR_MS)
         ms = 0;
       break;
     case QUARTER:
       if (mCursor.mMonth >= 9)
         mCal.set(mCursor.mYear + 1, 0, 0, 0, 0, 0);
       else if (mCursor.mMonth >= 6)
         mCal.set(mCursor.mYear, 9, 0, 0, 0, 0);
       else if (mCursor.mMonth >= 3)
         mCal.set(mCursor.mYear, 6, 0, 0, 0, 0);
       else
         mCal.set(mCursor.mYear, 3, 0, 0, 0, 0);
       ms = mCal.getTimeInMillis() - mCursor.mMillis;
       if (ms == QUARTER_MS)
         ms = 0;
       break;
     case MONTH:
       if (mCursor.mMonth == 11)
         mCal.set(mCursor.mYear + 1, 0, 0, 0, 0, 0);
       else
         mCal.set(mCursor.mYear, mCursor.mMonth + 1, 0, 0, 0, 0);
       ms = mCal.getTimeInMillis() - mCursor.mMillis;
       if (ms == MONTH_MS)
         ms = 0;
       break;
     case WEEK:
       mCal.setTimeInMillis(mCursor.mMillis);
       int first = mCal.getFirstDayOfWeek();
       mCal.add(Calendar.WEEK_OF_YEAR, 1);
       mCal.set(Calendar.DAY_OF_WEEK, first);
       mCal.set(Calendar.HOUR_OF_DAY, 0);
       mCal.set(Calendar.MINUTE, 0);
       mCal.set(Calendar.SECOND, 0);
       mCal.set(Calendar.MILLISECOND, 0);
       ms = mCal.getTimeInMillis() - mCursor.mMillis;
       if (ms == WEEK_MS)
         ms = 0;
       break;
     case DAY:
       if (mCursor.mMinute == 0 && mCursor.mHour == 0)
         return 0;
       ms = ((60 - mCursor.mMinute) + (60 * (24 - mCursor.mHour))) * MINUTE_MS;
       break;
     case AMPM:
       if (mCursor.mMinute == 0 && (mCursor.mHour == 0 || mCursor.mHour == 12))
         return 0;
       ms = ((60 - mCursor.mMinute) + (60 * (24 - (mCursor.mHour % 12))))
           * MINUTE_MS;
       break;
     case HOUR:
       if (mCursor.mMinute == 0)
         return 0;
       ms = (60 - mCursor.mMinute) * MINUTE_MS;
       break;
     case MINUTE:
     default:
       if (mCursor.mSecond == 0)
         return 0;
       ms = (60 - mCursor.mSecond) * SECOND_MS;
       break;
   }
   return ms;
 }
 /**
  * Sets an offset of the internal marker recording the class of time spanned
  * (as a Period). This offset is indexes into the Period enum, e.g., if the
  * span is calculated to be Period.YEAR with an offset of 0, then it will be
  * calculated to be Period.MONTH with an offset of -2.
  * 
  * @param milliStart
  *          The milliseconds since epoch in start time, inclusive.
  * @param milliEnd
  *          The milliseconds since epoch in end time, inclusive.
  */
 public void setSpanOffset(int offset) {
   mSpanOffset = offset;
 }
 /**
  * Sets the internal marker recording the class of time spanned (as a Period)
  * for the range of time specified. This is used to determine how to generate
  * labels while striding through time. If milliStart == milliEnd, the span
  * will be set to the smallest known span.
  * 
  * @param milliStart
  *          The milliseconds since epoch in start time, inclusive.
  * @param milliEnd
  *          The milliseconds since epoch in end time, inclusive.
  */
 public void setSpan(long milliStart, long milliEnd) {
   int index = 0;
   long range = milliEnd - milliStart;
   if (range == 0)
     range = 1;
   if (range < 0)
     range = -range;
   if (range > (long) (DateUtil.YEAR_MS * 3)) {
     index = DateUtil.Period.YEAR.ordinal();
   } else if (range > (long) (DateUtil.QUARTER_MS * 6)) {
     index = DateUtil.Period.QUARTER.ordinal();
   } else if (range > (long) (DateUtil.MONTH_MS * 6)) {
     index = DateUtil.Period.MONTH.ordinal();
   } else if (range > (long) (DateUtil.WEEK_MS * 4)) {
     index = DateUtil.Period.WEEK.ordinal();
   } else if (range > (long) (DateUtil.DAY_MS * 5)) {
     index = DateUtil.Period.DAY.ordinal();
   } else if (range > (long) (DateUtil.HOUR_MS * 24)) {
     index = DateUtil.Period.AMPM.ordinal();
   } else if (range > (long) (DateUtil.HOUR_MS * 5)) {
     index = DateUtil.Period.HOUR.ordinal();
   } else {
     index = DateUtil.Period.MINUTE.ordinal();
   }
   index += mSpanOffset;
   if (index < 0)
     index = 0;
   else if (index >= PERIODS.length)
     index = PERIODS.length - 1;
   mSpan = PERIODS[index];
   return;
 }
 /**
  * Returns the span calculated by {@link #setSpan(long, long)}
  * 
  * @return The span as a DateUtil.Period
  * @see DateUtil#Period
  */
 public DateUtil.Period getSpan() {
   return mSpan;
 }
 /**
  * Returns the selected Calendar.* field of the time under the current cursor
  * when striding.
  * 
  * @param p
  *          The Period in which to format the output.
  * @return The field datum.
  */
 public int get(int field) {
   return mCal.get(field);
 }
 /**
  * Returns an array of two strings yielding a textual representation of the
  * time under the current cursor when striding. Neither string will be null,
  * but either may be the empty ("") string. Typically, the second string will
  * be empty rather than the first, and will contain additional information
  * about the label, such as the the month when the days roll over into the
  * next month, or the day of the week. This method sets an internal marker
  * recording if current label has rolled past a period boundary, such as from
  * one week to the next or one year to the next, which is queryable via
  * {@link #isUnitChanged()}
  * 
  * @param p
  *          The Period in which to format the output.
  * @return String[2], containing two description strings of the date/time. The
  *         first string will be withing the Period p, and the
  *         second is typically auxiliary information.
  */
 public String[] getLabel(Period p) {
   String[] strings = new String[2];
   int minute;
   int hour;
   int day;
   int month;
   int year;
   int dow;
   mUnitChange = false;
   switch (p) {
     case YEAR:
       strings[0] = "" + mCal.get(Calendar.YEAR);
       strings[1] = "";
       break;
     case QUARTER:
       year = mCal.get(Calendar.YEAR);
       month = mCal.get(Calendar.MONTH);
       if (month >= 9)
         strings[0] = QUARTERS[3];
       else if (month >= 6)
         strings[0] = QUARTERS[2];
       else if (month >= 3)
         strings[0] = QUARTERS[1];
       else
         strings[0] = QUARTERS[0];
       strings[1] = "";
       if (year != mBase.mYear) {
         strings[1] = "" + mCal.get(Calendar.YEAR);
         mUnitChange = true;
       }
       break;
     case MONTH:
       year = mCal.get(Calendar.YEAR);
       month = mCal.get(Calendar.MONTH);
       strings[0] = MONTHS[month];
       if (year != mBase.mYear) {
         strings[1] = "" + mCal.get(Calendar.YEAR);
         mUnitChange = true;
       } else {
         strings[1] = "";
       }
       break;
     case WEEK:
     case DAY:
       month = mCal.get(Calendar.MONTH);
       day = mCal.get(Calendar.DAY_OF_MONTH);
       strings[0] = "" + day;
       if (month != mBase.mMonth) {
         strings[1] = MONTHS[month];
         mUnitChange = true;
       } else {
         dow = mCal.get(Calendar.DAY_OF_WEEK);
         strings[1] = DAYS[dow - 1];
         if (dow == 1)
           mUnitChange = true;
       }
       break;
     case AMPM:
     case HOUR:
       day = mCal.get(Calendar.DAY_OF_MONTH);
       hour = mCal.get(Calendar.HOUR_OF_DAY);
       if (hour == 0) {
         strings[0] = "12a";
         strings[1] = "midnight";
       } else if (hour == 12) {
         strings[0] = "12p";
         strings[1] = "noon";
       } else if (hour > 11) {
         strings[0] = (hour - 12) + "p";
         strings[1] = "";
       } else {
         strings[0] = hour + "a";
         strings[1] = "";
       }
       if (day != mBase.mDay) {
         dow = mCal.get(Calendar.DAY_OF_WEEK);
         strings[0] = mCal.get(Calendar.MONTH) + 1 + "/" + day;
         strings[1] = DAYS[dow - 1];
         mUnitChange = true;
       }
       break;
     case MINUTE:
     default:
       minute = mCal.get(Calendar.MINUTE);
       hour = mCal.get(Calendar.HOUR_OF_DAY);
       strings[0] = l2pad(minute);
       strings[1] = "";
       if (hour != mBase.mHour) {
         if (hour == 0) {
           day = mCal.get(Calendar.DAY_OF_MONTH);
           dow = mCal.get(Calendar.DAY_OF_WEEK);
           strings[0] = mCal.get(Calendar.MONTH) + 1 + "/" + day;
           strings[1] = DAYS[dow - 1];
         } else if (hour == 12) {
           strings[0] = "12";
           strings[1] = "noon";
         } else if (hour > 11) {
           strings[0] = (hour - 12) + "p";
         } else {
           strings[0] = hour + "a";
         }
         mUnitChange = true;
       } else
         break;
   }
   return strings;
 }
 /**
  * Advances the internal cursor milliseconds in time.
  * 
  * @param milliseconds
  *          The number of milliseconds to advance.
  */
 public void advanceInMs(long milliseconds) {
   copyDate(mCursor, mBase);
   mCal.setTimeInMillis(mCursor.mMillis);
   mCal.add(Calendar.MILLISECOND, (int) milliseconds);
   mCursor.mMillis = mCal.getTimeInMillis();
 }
 /**
  * Advances the internal cursor step units of Period
  * p in time. Note that for MONTH and QUARTER, this works out to
  * 1 and 3 months respectively, as defined by the Calendar class and based on
  * the current cursor, not precisely MONTH_MS or QUARTER_MS milliseconds.
  * 
  * @param p
  *          The DateUtil.Period unit.
  * @param step
  *          The number of Period units to advance.
  */
 public void advance(Period p, int step) {
   copyDate(mCursor, mBase);
   switch (p) {
     case YEAR:
       mCal.setTimeInMillis(mCursor.mMillis);
       mCal.add(Calendar.YEAR, step);
       break;
     case QUARTER:
       mCal.setTimeInMillis(mCursor.mMillis);
       mCal.add(Calendar.MONTH, step * 3);
       break;
     case MONTH:
       mCal.setTimeInMillis(mCursor.mMillis);
       mCal.add(Calendar.MONTH, step);
       break;
     case WEEK:
       mCal.setTimeInMillis(mCursor.mMillis);
       mCal.add(Calendar.WEEK_OF_YEAR, step);
       break;
     case DAY:
       mCal.setTimeInMillis(mCursor.mMillis);
       mCal.add(Calendar.DAY_OF_MONTH, step);
       break;
     case HOUR:
       mCal.setTimeInMillis(mCursor.mMillis);
       mCal.add(Calendar.HOUR_OF_DAY, step);
       break;
     case MINUTE:
     default:
       mCal.setTimeInMillis(mCursor.mMillis);
       mCal.add(Calendar.MINUTE, step);
       break;
   }
   mCursor.mMillis = mCal.getTimeInMillis();
   millisToComponent(mCursor);
   return;
 }
 /**
  * Return whether or not the last getLabel() noted a rollover from one period
  * to another, as determine by the Period passed to getLabel().
  * 
  * @return boolean
  * @see #getLabel(Period)
  */
 public boolean isUnitChanged() {
   return mUnitChange;
 }
 /**
  * Returns the average number of milliseconds in a Period. These are constant.
  * 
  * @param u
  * @return the number of millseconds
  * @see #YEAR_MS
  * @see #QUARTER_MS
  * @see #MONTH_MS
  * @see #DAY_MS
  * @see #HOUR_MS
  * @see #MINUTE_MS
  */
 public long msInPeriod(Period u) {
   long ms = 0;
   switch (u) {
     case YEAR:
       ms = YEAR_MS;
       break;
     case QUARTER:
       ms = QUARTER_MS;
       break;
     case MONTH:
       ms = MONTH_MS;
       break;
     case WEEK:
       ms = WEEK_MS;
       break;
     case DAY:
       ms = DAY_MS;
       break;
     case AMPM:
       ms = AMPM_MS;
       break;
     case HOUR:
       ms = HOUR_MS;
       break;
     case MINUTE:
     default:
       ms = MINUTE_MS;
       break;
   }
   return ms;
 }
 /**
  * Some external entities still use Calendar.* fields to do some of their own
  * date calculations, so this provides a mapping from DateUtil.*_MS to the
  * closest Calendar.* field. Note that if the milliseconds is not one of the
  * DateUtil constants, the smallest known field will be returned.
  * 
  * @param millis
  *          The DateUtil.*_MS field to map from.
  * @return The int representing the closest Calendar.* field.
  */
 public static int mapLongToCal(long millis) {
   if (millis == YEAR_MS)
     return Calendar.YEAR;
   else if (millis == QUARTER_MS)
     return Calendar.MONTH; // There is no Calendar.QUARTER, return MONTH
   else if (millis == MONTH_MS)
     return Calendar.MONTH;
   else if (millis == WEEK_MS)
     return Calendar.WEEK_OF_YEAR;
   else if (millis == DAY_MS)
     return Calendar.DAY_OF_MONTH;
   else if (millis == AMPM_MS)
     return Calendar.AM_PM;
   else if (millis == HOUR_MS)
     return Calendar.HOUR_OF_DAY;
   return Calendar.MINUTE;
 }
 /**
  * Provide a mapping from number of millisecond (DateUtil.*_MS) to a
  * DateUtil.Period. Note that if the milliseconds is not one of the DateUtil
  * constants, the smallest known field will be returned.
  * 
  * @param millis
  *          The DateUtil.*_MS field to map from.
  * @return The Period enum representing the associated DateUtil.Period.
  */
 public static Period mapLongToPeriod(long millis) {
   if (millis == YEAR_MS)
     return Period.YEAR;
   else if (millis == QUARTER_MS)
     return Period.QUARTER;
   else if (millis == MONTH_MS)
     return Period.MONTH;
   else if (millis == WEEK_MS)
     return Period.WEEK;
   else if (millis == DAY_MS)
     return Period.DAY;
   else if (millis == AMPM_MS)
     return Period.AMPM;
   else if (millis == HOUR_MS)
     return Period.HOUR;
   return Period.MINUTE;
 }
 /**
  * Provide a mapping from a Period to the number of millisecond
  * (DateUtil.*_MS)
  * 
  * @param The
  *          Period enum representing the associated DateUtil.Period.
  * @return A String describing the period..
  */
 public static String mapPeriodToString(Period p) {
   if (p == Period.YEAR)
     return "year";
   if (p == Period.QUARTER)
     return "quarter";
   if (p == Period.MONTH)
     return "month";
   if (p == Period.WEEK)
     return "week";
   if (p == Period.DAY)
     return "day";
   if (p == Period.AMPM)
     return "am/pm";
   if (p == Period.HOUR)
     return "hour";
   return "minute";
 }
 /**
  * Provide a mapping from string to a Period.
  * 
  * @param s
  *          The string to map from. Case insensitive.
  * @return The associated DateUtil.Period
  */
 public static Period mapStringToPeriod(String s) {
   if (s.toLowerCase().equals("year"))
     return Period.YEAR;
   if (s.toLowerCase().equals("quarter"))
     return Period.QUARTER;
   if (s.toLowerCase().equals("month"))
     return Period.MONTH;
   if (s.toLowerCase().equals("week"))
     return Period.WEEK;
   if (s.toLowerCase().equals("day"))
     return Period.DAY;
   if (s.toLowerCase().equals("am/pm"))
     return Period.AMPM;
   if (s.toLowerCase().equals("hour"))
     return Period.HOUR;
   return Period.MINUTE;
 }
 /**
  * Provide a mapping from a Period to the number of millisecond
  * (DateUtil.*_MS)
  * 
  * @param millis
  *          The DateUtil.*_MS field to map from.
  * @param The
  *          Period enum representing the associated DateUtil.Period.
  * @return the DateUtil.*_MS constant representing the number of milliseconds
  *         in the period.
  */
 public static long mapPeriodToLong(Period p) {
   if (p == Period.YEAR)
     return YEAR_MS;
   if (p == Period.QUARTER)
     return QUARTER_MS;
   if (p == Period.MONTH)
     return MONTH_MS;
   if (p == Period.WEEK)
     return WEEK_MS;
   if (p == Period.DAY)
     return DAY_MS;
   if (p == Period.AMPM)
     return AMPM_MS;
   if (p == Period.HOUR)
     return HOUR_MS;
   return MINUTE_MS;
 }
 /**
  * Returns a description of the milliseconds, scaled to the largest unit and
  * rounded to the default number of decimal places, with the associated label
  * (e.g., "years", "weeks", etc.)
  * 
  * @param millis
  *          The milliseconds since epoch to format.
  * @return The descriptive string.
  */
 public static String toString(float millis) {
   if (millis > YEAR_MS) {
     return Round(millis / YEAR_MS) + " years";
   } else if (millis > QUARTER_MS) {
     return Round(millis / QUARTER_MS) + " quarters";
   } else if (millis > MONTH_MS) {
     return Round(millis / MONTH_MS) + " months";
   } else if (millis > WEEK_MS) {
     return Round(millis / WEEK_MS) + " weeks";
   } else if (millis > DAY_MS) {
     return Round(millis / DAY_MS) + " days";
   } else if (millis > HOUR_MS) {
     return Round(millis / HOUR_MS) + " hours";
   } else { // if (millis > MINUTE_MS) {
     return Round(millis / MINUTE_MS) + " minutes";
   }
 }
 /**
  * Returns a description of the square root of the milliseconds, scaled to the
  * largest unit and rounded to the default number of decimal places, with the
  * associated label (e.g., "years", "weeks", etc.). Note this is only used for
  * displaying the variance, as the variance the a squared value, so this tests
  * (millis > (unit^2)) ? and displays the value (millis/(unit^2)). Otherwise
  * it is identical to {@link #toString(float)}.
  * 
  * @param millis
  *          The (squared) milliseconds since epoch to format.
  * @return The descriptive string.
  */
 public static String toStringSquared(float millis) {
   if (millis > (float) YEAR_MS * (float) YEAR_MS) {
     return Round(millis / ((float) YEAR_MS * (float) YEAR_MS))
         + " years";
   } else if (millis > (float) QUARTER_MS * (float) QUARTER_MS) {
     return Round(millis / ((float) QUARTER_MS * (float) QUARTER_MS))
         + " quarters";
   } else if (millis > (float) MONTH_MS * (float) MONTH_MS) {
     return Round(millis / ((float) MONTH_MS * (float) MONTH_MS))
         + " months";
   } else if (millis > (float) WEEK_MS * (float) WEEK_MS) {
     return Round(millis / ((float) WEEK_MS * (float) WEEK_MS))
         + " weeks";
   } else if (millis > (float) DAY_MS * (float) DAY_MS) {
     return Round(millis / ((float) DAY_MS * (float) DAY_MS)) + " days";
   } else if (millis > (float) HOUR_MS * (float) HOUR_MS) {
     return Round(millis / ((float) HOUR_MS * (float) HOUR_MS))
         + " hours";
   } else { // if (millis > MINUTE_MS) {
     return Round(millis / ((float) MINUTE_MS * (float) MINUTE_MS))
         + " minutes";
   }
 }
 /**
  * Default number of decimal places to round to:
  */
 public static final int DECIMAL_PLACES = 2;
 /**
  * Round a float to the default number of decimal places.
  * 
  * @param value
  *          The value to round.
  * @return The rounded value as a float.
  * @see #DECIMAL_PLACES
  */
 public static float Round(float value) {
   return Round(value, DECIMAL_PLACES);
 }
 /**
  * Round a float to the specified number of decimal places.
  * 
  * @param value
  *          The value to round.
  * @param places
  *          The number of decimal points.
  * @return The rounded value as a float.
  */
 public static float Round(float value, int places) {
   float p = (float) Math.pow(10, places);
   value = value * p;
   float tmp = Math.round(value);
   return (float) tmp / p;
 }
 /**
  * Returns the "timestamp" string representation of the time in milliseconds:
  * yyyy/mm/dd HH:MM:SS
  * 
  * @param millis
  *          The milliseconds since epoch to format.
  * @return The timestamp string.
  */
 public static String toTimestamp(long millis) {
   Calendar c = Calendar.getInstance();
   c.setTimeInMillis(millis);
   return DateUtil.toTimestamp(c);
 }
 /**
  * Returns the "short timestamp" string representation of the time in
  * milliseconds: HH:MM:SS
  * 
  * @param millis
  *          The milliseconds since epoch to format.
  * @return The short timestamp string.
  */
 public static String toShortTimestamp(long millis) {
   Calendar c = Calendar.getInstance();
   c.setTimeInMillis(millis);
   return DateUtil.toShortTimestamp(c);
 }
 /**
  * Utility routine for padding zeros on the left side of an integer out to two
  * digits, since string concatenations this small are much more efficient that
  * using String.format("%02d",foo).
  * 
  * @param i
  *          The integer to format.
  * @return A zero-padded string representation of the integer.
  */
 private static String l2pad(int i) {
   if (i < 10)
     return "0" + i;
   return "" + i;
 }
 /**
  * Returns a "timestamp" formated string representing the time:
  * "yyyy/mm/dd HH:MM:SS"
  * 
  * @param d
  *          The DateItem to format.
  * @return The timestamp string.
  */
 public static String toTimestamp(DateItem d) {
   return d.mYear + "/" + l2pad(d.mMonth + 1) + "/" + l2pad(d.mDay) + " "
       + l2pad(d.mHour) + ":" + l2pad(d.mMinute) + ":" + l2pad(d.mSecond);
 }
 /**
  * Returns a "timestamp" formated string representing the time:
  * "yyyy/mm/dd HH:MM:SS"
  * 
  * @param d
  *          The Calendar to format.
  * @return The timestamp string.
  */
 public static String toTimestamp(Calendar cal) {
   return cal.get(Calendar.YEAR) + "/" + l2pad(cal.get(Calendar.MONTH) + 1)
       + "/" + l2pad(cal.get(Calendar.DAY_OF_MONTH)) + " "
       + l2pad(cal.get(Calendar.HOUR_OF_DAY)) + ":"
       + l2pad(cal.get(Calendar.MINUTE)) + ":"
       + l2pad(cal.get(Calendar.SECOND));
 }
 /**
  * Returns a "short timestamp" formated string representing the time:
  * "HH:MM:SS"
  * 
  * @param d
  *          The Calendar to format.
  * @return The timestamp string.
  */
 public static String toShortTimestamp(Calendar cal) {
   return l2pad(cal.get(Calendar.HOUR_OF_DAY)) + ":"
       + l2pad(cal.get(Calendar.MINUTE)) + ":"
       + l2pad(cal.get(Calendar.SECOND));
 }
 /**
  * Returns a (generally) filesystem-safe formated string representing the
  * time: "yyyy-mm-dd_HH.MM.SS"
  * 
  * @param d
  *          The Calendar to format.
  * @return The timestamp string.
  */
 public static String toFSTimestamp(Calendar cal) {
   return cal.get(Calendar.YEAR) + "-" + l2pad(cal.get(Calendar.MONTH) + 1)
       + "-" + l2pad(cal.get(Calendar.DAY_OF_MONTH)) + "_"
       + l2pad(cal.get(Calendar.HOUR_OF_DAY)) + "."
       + l2pad(cal.get(Calendar.MINUTE)) + "."
       + l2pad(cal.get(Calendar.SECOND));
 }
 /**
  * Returns true if the two calendars represent dates that fall in the same
  * year, else false.
  * 
  * @param c1
  *          Calendar one.
  * @param c2
  *          Calendar two.
  * @return boolean.
  */
 public static boolean inSameYear(Calendar c1, Calendar c2) {
   if (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR))
     return true;
   return false;
 }
 /**
  * Returns true if the two calendars represent dates that fall in the same
  * quarter, else false. A quarter here is defined as the each group of three
  * consecutive months, starting with the month designated as the first month
  * by the Calendar package. Thus, it is not defined as the average number of
  * milliseconds in a quarter, which would be {@link #YEAR_MS}/4.
  * 
  * @param c1
  *          Calendar one.
  * @param c2
  *          Calendar two.
  * @return boolean.
  */
 public static boolean inSameQuarter(Calendar c1, Calendar c2) {
   if (inSameYear(c1, c2)) {
     int m1 = c1.get(Calendar.MONTH);
     int m2 = c2.get(Calendar.MONTH);
     if (m1 >= 9 && m2 >= 9)
       return true;
     if (m1 >= 6 && m1 < 9 && m2 >= 6 && m2 < 9)
       return true;
     if (m1 >= 3 && m1 < 6 && m2 >= 3 && m2 < 6)
       return true;
     if (m1 >= 0 && m1 < 3 && m2 >= 0 && m2 < 3)
       return true;
   }
   return false;
 }
 /**
  * Returns true if the two calendars represent dates that fall in the same
  * month, else false.
  * 
  * @param c1
  *          Calendar one.
  * @param c2
  *          Calendar two.
  * @return boolean.
  */
 public static boolean inSameMonth(Calendar c1, Calendar c2) {
   if (inSameYear(c1, c2)
       && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH)))
     return true;
   return false;
 }
 /**
  * Returns true if the two calendars represent dates that fall in the same
  * week, else false. A week here is defined by the Calendar.WEEK_OF_YEAR
  * package. Special provisions have been made to test weeks than may span the
  * end/beginning of a year, and returning true if the two calendars are
  * specifying dates within such a week, despite Calendar.WEEK_OF_YEAR being
  * unequal for the two Calendars.
  * 
  * @param c1
  *          Calendar one.
  * @param c2
  *          Calendar two.
  * @return boolean.
  */
 public static boolean inSameWeek(Calendar c1, Calendar c2) {
   if (inSameYear(c1, c2)
       && (c1.get(Calendar.WEEK_OF_YEAR) == c2.get(Calendar.WEEK_OF_YEAR)))
     return true;
   Calendar tmp;
   if (c1.before(c2)) {
     tmp = c2;
     c2 = c1;
     c1 = tmp;
   }
   int c1week = c1.get(Calendar.WEEK_OF_YEAR);
   int c2week = c1.get(Calendar.WEEK_OF_YEAR);
   if (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) + 1) {
     if (c1week == c1.getActualMinimum(Calendar.WEEK_OF_YEAR)
         && c2week == c2.getActualMaximum(Calendar.WEEK_OF_YEAR)) {
       tmp = (Calendar) c2.clone();
       tmp.add(Calendar.DAY_OF_YEAR, 7);
       if (tmp.get(Calendar.WEEK_OF_YEAR) > c1week)
         return true;
     }
   }
   return false;
 }
 /**
  * Returns true if the two calendars represent dates that fall in the same
  * day, else false.
  * 
  * @param c1
  *          Calendar one.
  * @param c2
  *          Calendar two.
  * @return boolean.
  */
 public static boolean inSameDay(Calendar c1, Calendar c2) {
   if (inSameYear(c1, c2)
       && (c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR)))
     return true;
   return false;
 }
 /**
  * Returns true if the two calendars represent dates that fall in the same
  * morning or evening, as defined by [midnight,noon) and [noon,midnight), else
  * false.
  * 
  * @param c1
  *          Calendar one.
  * @param c2
  *          Calendar two.
  * @return boolean.
  */
 public static boolean inSameAMPM(Calendar c1, Calendar c2) {
   if (inSameDay(c1, c2) && (c1.get(Calendar.AM_PM) == c2.get(Calendar.AM_PM)))
     return true;
   return false;
 }
 /**
  * Returns true if the two calendars represent dates that fall in the same
  * hour, else false.
  * 
  * @param c1
  *          Calendar one.
  * @param c2
  *          Calendar two.
  * @return boolean.
  */
 public static boolean inSameHour(Calendar c1, Calendar c2) {
   if (inSameDay(c1, c2)
       && (c1.get(Calendar.HOUR_OF_DAY) == c2.get(Calendar.HOUR_OF_DAY)))
     return true;
   return false;
 }
 /**
  * Returns true if the two calendars represent dates that fall in the same
  * period, else false.
  * 
  * @param aggregationMillis
  *          The period as specified in milliseconds, e.g., DateUtil.YEAR_MS
  * @param c1
  *          Calendar one.
  * @param c2
  *          Calendar two.
  * @return boolean.
  */
 public static boolean inSamePeriod(Calendar c1, Calendar c2,
     long aggregationMillis) {
   if (aggregationMillis == 0)
     return false;
   if ((aggregationMillis == YEAR_MS && inSameYear(c1, c2))
       || (aggregationMillis == QUARTER_MS && inSameQuarter(c1, c2))
       || (aggregationMillis == MONTH_MS && inSameMonth(c1, c2))
       || (aggregationMillis == WEEK_MS && inSameWeek(c1, c2))
       || (aggregationMillis == DAY_MS && inSameDay(c1, c2))
       || (aggregationMillis == AMPM_MS && inSameAMPM(c1, c2))
       || (aggregationMillis == HOUR_MS && inSameHour(c1, c2))) {
     return true;
   }
   return false;
 }
 /**
  * Sets the date/time of the Calendar object to the beginning of the Period by
  * setting all fields smaller than the specified period to the minimum value.
  * 
  * @param c
  *          The calendar to set.
  * @param p
  *          The DateUtil.Period to set.
  */
 public static void setToPeriodStart(Calendar c, Period p) {
   switch (p) {
     case YEAR:
       c.set(Calendar.MONTH, 0);
     case MONTH:
       c.set(Calendar.DAY_OF_MONTH, 1);
     case DAY:
       c.set(Calendar.HOUR_OF_DAY, 0);
     case HOUR:
       c.set(Calendar.MINUTE, 0);
     case MINUTE:
       c.set(Calendar.SECOND, 0);
       c.set(Calendar.MILLISECOND, 0);
       break;
     case WEEK:
       c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
       c.set(Calendar.HOUR_OF_DAY, 0);
       c.set(Calendar.MINUTE, 0);
       c.set(Calendar.SECOND, 0);
       c.set(Calendar.MILLISECOND, 0);
       break;
     case AMPM:
       if (c.get(Calendar.AM_PM) == Calendar.AM)
         c.set(Calendar.HOUR_OF_DAY, 0);
       else
         c.set(Calendar.HOUR_OF_DAY, 12);
       c.set(Calendar.MINUTE, 0);
       c.set(Calendar.SECOND, 0);
       c.set(Calendar.MILLISECOND, 0);
       break;
     case QUARTER:
       int month = c.get(Calendar.MONTH);
       if (month >= 9)
         c.set(Calendar.MONTH, 9);
       else if (month >= 9)
         c.set(Calendar.MONTH, 6);
       else if (month >= 9)
         c.set(Calendar.MONTH, 3);
       else
         c.set(Calendar.MONTH, 0);
       c.set(Calendar.DAY_OF_MONTH, 0);
       c.set(Calendar.HOUR_OF_DAY, 0);
       c.set(Calendar.MINUTE, 0);
       c.set(Calendar.SECOND, 0);
       c.set(Calendar.MILLISECOND, 0);
       break;
   }
   return;
 }
 /**
  * Utility routine to set each DateTime component field to that specified by
  * the DateItem"s millisecond field.
  * 
  * @param d
  *          The DateItem to modify.
  */
 private void millisToComponent(DateItem d) {
   mCal.setTimeInMillis(d.mMillis);
   d.mYear = mCal.get(Calendar.YEAR);
   d.mMonth = mCal.get(Calendar.MONTH);
   d.mDay = mCal.get(Calendar.DAY_OF_MONTH);
   d.mHour = mCal.get(Calendar.HOUR_OF_DAY);
   d.mMinute = mCal.get(Calendar.MINUTE);
 }
 /**
  * Copy all member variable of one DateItem to that of another DateItem.
  * 
  * @param src
  *          The DateItem to copy from.
  * @param dst
  *          The DateItem to copy to.
  */
 private void copyDate(DateItem src, DateItem dst) {
   dst.mYear = src.mYear;
   dst.mMonth = src.mMonth;
   dst.mDay = src.mDay;
   dst.mHour = src.mHour;
   dst.mMinute = src.mMinute;
   dst.mMillis = src.mMillis;
 }

}


 </source>
   
  
 
  



Return now as a string

   <source lang="java">
 

/*

* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licensing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/

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

* Utility functions related to date and time.
*
* @author Klaus Meffert
* @since 3.3.3
*/

public class DateKit {

 /** String containing the CVS revision. Read out via reflection!*/
 private final static String CVS_REVISION = "$Revision: 1.4 $";
 private static Calendar m_cal = Calendar.getInstance();
 public final static String DATEFORMAT_FULL_0 = "yyyyMMddHHmmssSSS";
 public final static String DATEFORMAT_FULL_1 = "yyyy/MM/dd HH:mm:ss:SSS";
 public final static String DATEFORMAT_NORMAL = "yyyy/MM/dd";
 private static SimpleDateFormat m_sdfNow = new SimpleDateFormat(DATEFORMAT_FULL_0);
 private static SimpleDateFormat m_sdfToday = new SimpleDateFormat("yyyyMMdd");
 /**
  * @return now as a string, including milliseconds
  *
  * @author Klaus Meffert
  * @since 3.3.3
  */
 public static String getNowAsString() {
   return m_sdfNow.format(m_cal.getTime());
 }
 /**
  * @return today as a string
  *
  * @author Klaus Meffert
  * @since 3.3.3
  */
 public static String getTodayAsString() {
   return m_sdfToday.format(m_cal.getTime());
 }
 /**
  * @param a_date the date to be returned in a specific format
  * @param a_dateFormat the desired format of the date
  *
  * @return date in given format
  *
  * @author Klaus Meffert
  * @since 3.3.4
  */
 public static String dateToString(Date a_date, String a_dateFormat) {
   SimpleDateFormat sdf = new SimpleDateFormat(a_dateFormat);
   return sdf.format(a_date);
 }
 /**
  * @return now
  *
  * @author Klaus Meffert
  * @since 3.3.3
  */
 public static Date now() {
   return new Date();
 }

}


 </source>
   
  
 
  



Return today as a string

   <source lang="java">
 

/*

* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licensing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/

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

* Utility functions related to date and time.
*
* @author Klaus Meffert
* @since 3.3.3
*/

public class DateKit {

 /** String containing the CVS revision. Read out via reflection!*/
 private final static String CVS_REVISION = "$Revision: 1.4 $";
 private static Calendar m_cal = Calendar.getInstance();
 public final static String DATEFORMAT_FULL_0 = "yyyyMMddHHmmssSSS";
 public final static String DATEFORMAT_FULL_1 = "yyyy/MM/dd HH:mm:ss:SSS";
 public final static String DATEFORMAT_NORMAL = "yyyy/MM/dd";
 private static SimpleDateFormat m_sdfNow = new SimpleDateFormat(DATEFORMAT_FULL_0);
 private static SimpleDateFormat m_sdfToday = new SimpleDateFormat("yyyyMMdd");
 /**
  * @return now as a string, including milliseconds
  *
  * @author Klaus Meffert
  * @since 3.3.3
  */
 public static String getNowAsString() {
   return m_sdfNow.format(m_cal.getTime());
 }
 /**
  * @return today as a string
  *
  * @author Klaus Meffert
  * @since 3.3.3
  */
 public static String getTodayAsString() {
   return m_sdfToday.format(m_cal.getTime());
 }
 /**
  * @param a_date the date to be returned in a specific format
  * @param a_dateFormat the desired format of the date
  *
  * @return date in given format
  *
  * @author Klaus Meffert
  * @since 3.3.4
  */
 public static String dateToString(Date a_date, String a_dateFormat) {
   SimpleDateFormat sdf = new SimpleDateFormat(a_dateFormat);
   return sdf.format(a_date);
 }
 /**
  * @return now
  *
  * @author Klaus Meffert
  * @since 3.3.3
  */
 public static Date now() {
   return new Date();
 }

}


 </source>
   
  
 
  



Sets the day of month field to a date returning a new object.

   <source lang="java">
 

import java.util.Calendar; import java.util.Date; /**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 //-----------------------------------------------------------------------
 /**
  * Sets the day of month field to a date returning a new object.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 public static Date setDays(Date date, int amount) {
     return set(date, Calendar.DAY_OF_MONTH, amount);
 }
 //-----------------------------------------------------------------------
 /**
  * Sets the specified field to a date returning a new object.  
  * This does not use a lenient calendar.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param calendarField  the calendar field to set the amount to
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 private static Date set(Date date, int calendarField, int amount) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     // getInstance() returns a new object, so this method is thread safe.
     Calendar c = Calendar.getInstance();
     c.setLenient(false);
     c.setTime(date);
     c.set(calendarField, amount);
     return c.getTime();
 }   

}


 </source>
   
  
 
  



Sets the hours field to a date returning a new object. Hours range from 0-23.

   <source lang="java">
 

import java.util.Calendar; import java.util.Date; /**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 //-----------------------------------------------------------------------
 /**
  * Sets the hours field to a date returning a new object.  Hours range 
  * from  0-23.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 public static Date setHours(Date date, int amount) {
     return set(date, Calendar.HOUR_OF_DAY, amount);
 }
 //-----------------------------------------------------------------------
 /**
  * Sets the specified field to a date returning a new object.  
  * This does not use a lenient calendar.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param calendarField  the calendar field to set the amount to
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 private static Date set(Date date, int calendarField, int amount) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     // getInstance() returns a new object, so this method is thread safe.
     Calendar c = Calendar.getInstance();
     c.setLenient(false);
     c.setTime(date);
     c.set(calendarField, amount);
     return c.getTime();
 }   

}


 </source>
   
  
 
  



Sets the miliseconds field to a date returning a new object.

   <source lang="java">
 

import java.util.Calendar; import java.util.Date; /**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 //-----------------------------------------------------------------------
 /**
  * Sets the miliseconds field to a date returning a new object.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 public static Date setMilliseconds(Date date, int amount) {
     return set(date, Calendar.MILLISECOND, amount);
 } 
 //-----------------------------------------------------------------------
 /**
  * Sets the specified field to a date returning a new object.  
  * This does not use a lenient calendar.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param calendarField  the calendar field to set the amount to
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 private static Date set(Date date, int calendarField, int amount) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     // getInstance() returns a new object, so this method is thread safe.
     Calendar c = Calendar.getInstance();
     c.setLenient(false);
     c.setTime(date);
     c.set(calendarField, amount);
     return c.getTime();
 }   

}


 </source>
   
  
 
  



Sets the minute field to a date returning a new object.

   <source lang="java">
 

import java.util.Calendar; import java.util.Date; /**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 //-----------------------------------------------------------------------
 /**
  * Sets the minute field to a date returning a new object.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 public static Date setMinutes(Date date, int amount) {
     return set(date, Calendar.MINUTE, amount);
 }
 //-----------------------------------------------------------------------
 /**
  * Sets the specified field to a date returning a new object.  
  * This does not use a lenient calendar.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param calendarField  the calendar field to set the amount to
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 private static Date set(Date date, int calendarField, int amount) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     // getInstance() returns a new object, so this method is thread safe.
     Calendar c = Calendar.getInstance();
     c.setLenient(false);
     c.setTime(date);
     c.set(calendarField, amount);
     return c.getTime();
 }   

}


 </source>
   
  
 
  



Sets the seconds field to a date returning a new object.

   <source lang="java">
 

import java.util.Calendar; import java.util.Date; /**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 //-----------------------------------------------------------------------
 /**
  * Sets the seconds field to a date returning a new object.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 public static Date setSeconds(Date date, int amount) {
     return set(date, Calendar.SECOND, amount);
 }
 //-----------------------------------------------------------------------
 /**
  * Sets the specified field to a date returning a new object.  
  * This does not use a lenient calendar.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param calendarField  the calendar field to set the amount to
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 private static Date set(Date date, int calendarField, int amount) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     // getInstance() returns a new object, so this method is thread safe.
     Calendar c = Calendar.getInstance();
     c.setLenient(false);
     c.setTime(date);
     c.set(calendarField, amount);
     return c.getTime();
 }   

}


 </source>
   
  
 
  



Sets the years field to a date returning a new object.

   <source lang="java">
 

import java.util.Calendar; import java.util.Date; /**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 //-----------------------------------------------------------------------
 /**
  * Sets the years field to a date returning a new object.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 public static Date setYears(Date date, int amount) {
     return set(date, Calendar.YEAR, amount);
 }
 //-----------------------------------------------------------------------
 /**
  * Sets the specified field to a date returning a new object.  
  * This does not use a lenient calendar.
  * The original date object is unchanged.
  *
  * @param date  the date, not null
  * @param calendarField  the calendar field to set the amount to
  * @param amount the amount to set
  * @return a new Date object set with the specified value
  * @throws IllegalArgumentException if the date is null
  * @since 2.4
  */
 private static Date set(Date date, int calendarField, int amount) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     // getInstance() returns a new object, so this method is thread safe.
     Calendar c = Calendar.getInstance();
     c.setLenient(false);
     c.setTime(date);
     c.set(calendarField, amount);
     return c.getTime();
 }   

}


 </source>
   
  
 
  



Truncate this date(Calendar), leaving the field specified as the most significant field.

   <source lang="java">
 

import java.util.Calendar; import java.util.Date; /**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 private static final int[][] fields = {
   {Calendar.MILLISECOND},
   {Calendar.SECOND},
   {Calendar.MINUTE},
   {Calendar.HOUR_OF_DAY, Calendar.HOUR},
   {Calendar.DATE, Calendar.DAY_OF_MONTH, Calendar.AM_PM 
       /* Calendar.DAY_OF_YEAR, Calendar.DAY_OF_WEEK, Calendar.DAY_OF_WEEK_IN_MONTH */
   },
   {Calendar.MONTH, DateUtils.SEMI_MONTH},
   {Calendar.YEAR},
   {Calendar.ERA}};
 /**
*

Truncate this date, leaving the field specified as the most * significant field.

  *
*

For example, if you had the datetime of 28 Mar 2002 * 13:45:01.231, if you passed with HOUR, it would return 28 Mar * 2002 13:00:00.000. If this was passed with MONTH, it would * return 1 Mar 2002 0:00:00.000.

  * 
  * @param date  the date to work with
  * @param field  the field from Calendar
  *  or SEMI_MONTH
  * @return the rounded date (a different object)
  * @throws IllegalArgumentException if the date is null
  * @throws ArithmeticException if the year is over 280 million
  */
 public static Calendar truncate(Calendar date, int field) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     Calendar truncated = (Calendar) date.clone();
     modify(truncated, field, false);
     return truncated;
 }
 //-----------------------------------------------------------------------
 /**
*

Internal calculation method.

  * 
  * @param val  the calendar
  * @param field  the field constant
  * @param round  true to round, false to truncate
  * @throws ArithmeticException if the year is over 280 million
  */
 private static void modify(Calendar val, int field, boolean round) {
     if (val.get(Calendar.YEAR) > 280000000) {
         throw new ArithmeticException("Calendar value too large for accurate calculations");
     }
     
     if (field == Calendar.MILLISECOND) {
         return;
     }
     // ----------------- Fix for LANG-59 ---------------------- START ---------------
     // see http://issues.apache.org/jira/browse/LANG-59
     //
     // Manually truncate milliseconds, seconds and minutes, rather than using
     // Calendar methods.
     Date date = val.getTime();
     long time = date.getTime();
     boolean done = false;
     // truncate milliseconds
     int millisecs = val.get(Calendar.MILLISECOND);
     if (!round || millisecs < 500) {
         time = time - millisecs;
     }
     if (field == Calendar.SECOND) {
         done = true;
     }
     // truncate seconds
     int seconds = val.get(Calendar.SECOND);
     if (!done && (!round || seconds < 30)) {
         time = time - (seconds * 1000L);
     }
     if (field == Calendar.MINUTE) {
         done = true;
     }
     // truncate minutes
     int minutes = val.get(Calendar.MINUTE);
     if (!done && (!round || minutes < 30)) {
         time = time - (minutes * 60000L);
     }
     // reset time
     if (date.getTime() != time) {
         date.setTime(time);
         val.setTime(date);
     }
     // ----------------- Fix for LANG-59 ----------------------- END ----------------
     boolean roundUp = false;
     for (int i = 0; i < fields.length; i++) {
         for (int j = 0; j < fields[i].length; j++) {
             if (fields[i][j] == field) {
                 //This is our field... we stop looping
                 if (round && roundUp) {
                     if (field == DateUtils.SEMI_MONTH) {
                         //This is a special case that"s hard to generalize
                         //If the date is 1, we round up to 16, otherwise
                         //  we subtract 15 days and add 1 month
                         if (val.get(Calendar.DATE) == 1) {
                             val.add(Calendar.DATE, 15);
                         } else {
                             val.add(Calendar.DATE, -15);
                             val.add(Calendar.MONTH, 1);
                         }
                     } else {
                         //We need at add one to this field since the
                         //  last number causes us to round up
                         val.add(fields[i][0], 1);
                     }
                 }
                 return;
             }
         }
         //We have various fields that are not easy roundings
         int offset = 0;
         boolean offsetSet = false;
         //These are special types of fields that require different rounding rules
         switch (field) {
             case DateUtils.SEMI_MONTH:
                 if (fields[i][0] == Calendar.DATE) {
                     //If we"re going to drop the DATE field"s value,
                     //  we want to do this our own way.
                     //We need to subtrace 1 since the date has a minimum of 1
                     offset = val.get(Calendar.DATE) - 1;
                     //If we"re above 15 days adjustment, that means we"re in the
                     //  bottom half of the month and should stay accordingly.
                     if (offset >= 15) {
                         offset -= 15;
                     }
                     //Record whether we"re in the top or bottom half of that range
                     roundUp = offset > 7;
                     offsetSet = true;
                 }
                 break;
             case Calendar.AM_PM:
                 if (fields[i][0] == Calendar.HOUR_OF_DAY) {
                     //If we"re going to drop the HOUR field"s value,
                     //  we want to do this our own way.
                     offset = val.get(Calendar.HOUR_OF_DAY);
                     if (offset >= 12) {
                         offset -= 12;
                     }
                     roundUp = offset > 6;
                     offsetSet = true;
                 }
                 break;
         }
         if (!offsetSet) {
             int min = val.getActualMinimum(fields[i][0]);
             int max = val.getActualMaximum(fields[i][0]);
             //Calculate the offset from the minimum allowed value
             offset = val.get(fields[i][0]) - min;
             //Set roundUp if this is more than half way between the minimum and maximum
             roundUp = offset > ((max - min) / 2);
         }
         //We need to remove this field
         if (offset != 0) {
             val.set(fields[i][0], val.get(fields[i][0]) - offset);
         }
     }
     throw new IllegalArgumentException("The field " + field + " is not supported");
 }

}


 </source>
   
  
 
  



Truncate this date, leaving the field specified as the most significant field.

   <source lang="java">
 

import java.util.Calendar; import java.util.Date; /**

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/


/**

*

A suite of utilities surrounding the use of the * {@link java.util.Calendar} and {@link java.util.Date} object.

* 
*

DateUtils contains a lot of common methods considering manipulations * of Dates or Calendars. Some methods require some extra explanation. * The truncate and round methods could be considered the Math.floor(), * Math.ceil() or Math.round versions for dates * This way date-fields will be ignored in bottom-up order. * As a complement to these methods we"ve introduced some fragment-methods. * With these methods the Date-fields will be ignored in top-down order. * Since a date without a year is not a valid date, you have to decide in what * kind of date-field you want your result, for instance milliseconds or days. *

*   
*   
*
* @author 
* @author Phil Steitz
* @author Robert Scholte
* @since 2.0
* @version $Id: DateUtils.java 634096 2008-03-06 00:58:11Z niallp $
*/

public class Main {

 private static final int[][] fields = {
   {Calendar.MILLISECOND},
   {Calendar.SECOND},
   {Calendar.MINUTE},
   {Calendar.HOUR_OF_DAY, Calendar.HOUR},
   {Calendar.DATE, Calendar.DAY_OF_MONTH, Calendar.AM_PM 
       /* Calendar.DAY_OF_YEAR, Calendar.DAY_OF_WEEK, Calendar.DAY_OF_WEEK_IN_MONTH */
   },
   {Calendar.MONTH, DateUtils.SEMI_MONTH},
   {Calendar.YEAR},
   {Calendar.ERA}};
 //-----------------------------------------------------------------------
 /**
*

Truncate this date, leaving the field specified as the most * significant field.

  *
*

For example, if you had the datetime of 28 Mar 2002 * 13:45:01.231, if you passed with HOUR, it would return 28 Mar * 2002 13:00:00.000. If this was passed with MONTH, it would * return 1 Mar 2002 0:00:00.000.

  * 
  * @param date  the date to work with
  * @param field  the field from Calendar
  *  or SEMI_MONTH
  * @return the rounded date
  * @throws IllegalArgumentException if the date is null
  * @throws ArithmeticException if the year is over 280 million
  */
 public static Date truncate(Date date, int field) {
     if (date == null) {
         throw new IllegalArgumentException("The date must not be null");
     }
     Calendar gval = Calendar.getInstance();
     gval.setTime(date);
     modify(gval, field, false);
     return gval.getTime();
 }
 //-----------------------------------------------------------------------
 /**
*

Internal calculation method.

  * 
  * @param val  the calendar
  * @param field  the field constant
  * @param round  true to round, false to truncate
  * @throws ArithmeticException if the year is over 280 million
  */
 private static void modify(Calendar val, int field, boolean round) {
     if (val.get(Calendar.YEAR) > 280000000) {
         throw new ArithmeticException("Calendar value too large for accurate calculations");
     }
     
     if (field == Calendar.MILLISECOND) {
         return;
     }
     // ----------------- Fix for LANG-59 ---------------------- START ---------------
     // see http://issues.apache.org/jira/browse/LANG-59
     //
     // Manually truncate milliseconds, seconds and minutes, rather than using
     // Calendar methods.
     Date date = val.getTime();
     long time = date.getTime();
     boolean done = false;
     // truncate milliseconds
     int millisecs = val.get(Calendar.MILLISECOND);
     if (!round || millisecs < 500) {
         time = time - millisecs;
     }
     if (field == Calendar.SECOND) {
         done = true;
     }
     // truncate seconds
     int seconds = val.get(Calendar.SECOND);
     if (!done && (!round || seconds < 30)) {
         time = time - (seconds * 1000L);
     }
     if (field == Calendar.MINUTE) {
         done = true;
     }
     // truncate minutes
     int minutes = val.get(Calendar.MINUTE);
     if (!done && (!round || minutes < 30)) {
         time = time - (minutes * 60000L);
     }
     // reset time
     if (date.getTime() != time) {
         date.setTime(time);
         val.setTime(date);
     }
     // ----------------- Fix for LANG-59 ----------------------- END ----------------
     boolean roundUp = false;
     for (int i = 0; i < fields.length; i++) {
         for (int j = 0; j < fields[i].length; j++) {
             if (fields[i][j] == field) {
                 //This is our field... we stop looping
                 if (round && roundUp) {
                     if (field == DateUtils.SEMI_MONTH) {
                         //This is a special case that"s hard to generalize
                         //If the date is 1, we round up to 16, otherwise
                         //  we subtract 15 days and add 1 month
                         if (val.get(Calendar.DATE) == 1) {
                             val.add(Calendar.DATE, 15);
                         } else {
                             val.add(Calendar.DATE, -15);
                             val.add(Calendar.MONTH, 1);
                         }
                     } else {
                         //We need at add one to this field since the
                         //  last number causes us to round up
                         val.add(fields[i][0], 1);
                     }
                 }
                 return;
             }
         }
         //We have various fields that are not easy roundings
         int offset = 0;
         boolean offsetSet = false;
         //These are special types of fields that require different rounding rules
         switch (field) {
             case DateUtils.SEMI_MONTH:
                 if (fields[i][0] == Calendar.DATE) {
                     //If we"re going to drop the DATE field"s value,
                     //  we want to do this our own way.
                     //We need to subtrace 1 since the date has a minimum of 1
                     offset = val.get(Calendar.DATE) - 1;
                     //If we"re above 15 days adjustment, that means we"re in the
                     //  bottom half of the month and should stay accordingly.
                     if (offset >= 15) {
                         offset -= 15;
                     }
                     //Record whether we"re in the top or bottom half of that range
                     roundUp = offset > 7;
                     offsetSet = true;
                 }
                 break;
             case Calendar.AM_PM:
                 if (fields[i][0] == Calendar.HOUR_OF_DAY) {
                     //If we"re going to drop the HOUR field"s value,
                     //  we want to do this our own way.
                     offset = val.get(Calendar.HOUR_OF_DAY);
                     if (offset >= 12) {
                         offset -= 12;
                     }
                     roundUp = offset > 6;
                     offsetSet = true;
                 }
                 break;
         }
         if (!offsetSet) {
             int min = val.getActualMinimum(fields[i][0]);
             int max = val.getActualMaximum(fields[i][0]);
             //Calculate the offset from the minimum allowed value
             offset = val.get(fields[i][0]) - min;
             //Set roundUp if this is more than half way between the minimum and maximum
             roundUp = offset > ((max - min) / 2);
         }
         //We need to remove this field
         if (offset != 0) {
             val.set(fields[i][0], val.get(fields[i][0]) - offset);
         }
     }
     throw new IllegalArgumentException("The field " + field + " is not supported");
 }

}


 </source>