TimeValue.java
/*
** Module :TimeValue.java
** Abstract :Time value holder.
**
** Copyright (c) 2005-2017, Golden Code Development Corporation.
**
** -#- -I- --Date-- -T- --JPRM-- ----------------Description-----------------
** 001 SIY 20050218 ADD @20051 Created initial version
** 002 SIY 20050310 CHG @20371 Organized imports and reordered methods.
** Fixed equals().
** 003 SIY 20050328 CHG @20589 Added "implements Comparable". Fixed comments.
** 004 NVS 20050426 CHG @20892 Class implements Serializable interface.
** 005 SIY 20050429 CHG @21034 Fixed comments and formatting.
** 006 EVL 20160223 Javadoc fixes to make compatible with Oracle Java 8 for
** Solaris 10.
** 007 IAS 20160331 Moved non-threadsafe format field to ThreadLocal
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** 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 Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.directory;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.io.Serializable;
/**
* The main purpose of this class is to hold time value for storing/saving it
* in the Directory. Also it allows to distinguish types during processing
* (this is not so simple for java.util.Date and derivatives). For the
* convenience it can be easily converted to/from java.util.Date class.
*
* @author SIY
* @version 1.0
*/
public class TimeValue
implements Comparable,
Serializable
{
/**
* Format used for <code>TimeValue</code> <-> <code>String</code>
* conversion.
*/
private static final ThreadLocal<SimpleDateFormat> format =
new ThreadLocal<SimpleDateFormat>()
{
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("HH:mm:ss");
}
};
/** Date/Time storage/manipulation back-end */
private Calendar calendar;
/**
* Constructs an instance of the <code>TimeValue</code> from the
* <code>Date</code> instance.
*
* @param other
* An instance which is used as a source of data.
*/
public TimeValue(Date other)
{
calendar = Calendar.getInstance();
enforceDate(other);
}
/**
* Constructs an instance of the TimeValue from hours and minutes. Other
* fields are set to 0
*
* @param hours
* Hours filed for the new instance.
* @param minutes
* Minutes value for the new instance.
*/
public TimeValue(int hours, int minutes)
{
this(hours, minutes, 0);
}
/**
* Constructs an instance with all fields (hours, minutes, and seconds)
* defined.
*
* @param hours
* Hours value for the new instance.
* @param minutes
* Minutes value for the new instance.
* @param seconds
* Seconds value for the new instance.
*/
public TimeValue(int hours, int minutes, int seconds)
{
calendar = Calendar.getInstance();
calendar.set(0, 0, 0, hours, minutes, seconds);
enforceDate(calendar.getTime());
}
/**
* Constructs an instance of the <code>TimeValue</code> from the other
* instance.
*
* @param other
* An instance which is used as a source of data.
*/
public TimeValue(TimeValue other)
{
calendar = Calendar.getInstance();
enforceDate(other.getDate());
}
/**
* Parse <code>String</code> like HH:MM:SS and create an instance of
* <code>TimeValue</code>.
*
* @param str
* Source string.
* @return new <code>TimeValue</code> instance or <code>null</code> if
* source string does not contain properly formatted time.
*/
public static TimeValue valueOf(String str)
{
try
{
return new TimeValue(format.get().parse(str, new ParsePosition(0)));
}
catch (Exception e)
{
return null;
}
}
/**
* Compares this instance with instance of <code>Date</code> for
* ordering. Note that argument must have date part reset to <code>0</code>
* because it is involved into comparison.
*
* @param other
* The instance of <code>Date</code> to be compared.
* @return <code>0</code> if times are equal; a value less than
* <code>0</code> if this instance time is before time of the
* passed parameter; a value greater than <code>0</code> if this
* instance time is after time of the parameter.
*/
public int compareTo(Date other)
{
return calendar.getTime().compareTo(other);
}
/**
* Compare this instance with other object.
*
* @param other
* The instance of <code>Date</code> to be compared.
* @return <code>0</code> if times are equal; a value less than
* <code>0</code> if this instance time is before time of the
* passed parameter; a value greater than <code>0</code> if this
* instance time is after time of the parameter.
* @throws ClassCastException
* if argument is not instance of <code>Date</code> or
* <code>TimeValue</code>.
*/
public int compareTo(Object other)
{
if (other instanceof Date)
return calendar.getTime().compareTo((Date) other);
return compareTo((TimeValue) other);
}
/**
* Compares two instances for ordering.
*
* @param other
* The instance to be compared.
* @return <code>0</code> if instances are equal; a value less than
* <code>0</code> if this instance time is before time of the
* instance passed as a parameter; a value greater than
* <code>0</code> if this instance time is after time of the
* instance passed as a parameter.
*/
public int compareTo(TimeValue other)
{
return calendar.getTime().compareTo(other.getDate());
}
/**
* Compares two objects for equality. Call <code>Calendar.equals()</code>
* or <code>Date.equals()</code> if possible. Otherwise return
* <code>false</code>.
*
* @param o
* Object to compare with.
* @return <code>true</code> if instances are equal and
* <code>false</code> otherwise.
*/
public boolean equals(Object o)
{
if (o instanceof TimeValue || o instanceof Calendar)
{
Calendar other;
if (o instanceof TimeValue)
other = ((TimeValue) o).calendar;
else
other = (Calendar) o;
if (calendar.get(Calendar.HOUR_OF_DAY) ==
other.get(Calendar.HOUR_OF_DAY)
&& calendar.get(Calendar.MINUTE) == other.get(Calendar.MINUTE)
&& calendar.get(Calendar.SECOND) == other.get(Calendar.SECOND))
{
return true;
}
return false;
}
if (o instanceof Date)
return calendar.getTime().equals(o);
return false;
}
/**
* Return current time as instance of the <code>Date</code>.
*
* @return An instance of <code>java.util.Date</code>.
*/
public Date getDate()
{
return calendar.getTime();
}
/**
* Return a hash code for the instance. Use <code>Date.hashCode()</code>
* for real computation.
*
* @return Hash code for the instance.
*/
public int hashCode()
{
return calendar.getTime().hashCode();
}
/**
* Set current value using instance of <code>Date</code> as a source.
*
* @param date
* Source instance of <code>Date</code> to get values from.
*/
public void setDate(Date date)
{
enforceDate(date);
}
/**
* Convert <code>TimeValue</code> instance into <code>String</code>.
*
* @return String in format HH:MM:SS.
*/
public String toString()
{
StringBuffer buf = new StringBuffer();
format.get().format(getDate(), buf,
new FieldPosition(DateFormat.HOUR_OF_DAY0_FIELD));
return buf.toString();
}
/**
* This method performs all necessary steps to enforce TimeValue instance
* to contain only time, without date part.
*
* @param input
* <code>Date</code> instance to set information from.
*/
private void enforceDate(Date input)
{
calendar.setTime(input);
calendar.set(Calendar.YEAR, 0);
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.DATE, 0);
}
}