// Time.java
/**
* Objects of this class represent a time
* within a 24-hour day, ranging from
* 00:00:00 to 23:59:59 when specified as
* an hour, minute, and second; or ranging
* from from 0 to 86399 when specified as
* a total number of seconds since midnight.
*/
public class Time {
/** The hour in a 24-hour time */
private byte hour;
/** The minute in a 24-hour time */
private byte minute;
/** The second in a 24-hour time */
private byte second;
/**
* Creates a Time object representing a time specified
* as a total number of seconds since midnight.
*
* @param totalSeconds number of seconds since midnight.
* Must be in range 0 to 86499, inclusive.
* @exception IllegalArgumentException if totalSeconds
* is out of range.
*/
public Time(int totalSeconds)
{
if ( totalSeconds < 0 || totalSeconds >= 86400 )
throw new IllegalArgumentException(
"Time: seconds since midnight "
+ totalSeconds
+ " must be >=0 and < 86400.");
// Calculate values to assign to instance variables:
hour = (byte) (totalSeconds / 3600);
minute = (byte) (totalSeconds / 60 % 60);
second = (byte) (totalSeconds % 60);
} // constructor(int)
/**
* Creates a Time object representing a time specified
* as an hour, minute, and second in 24-hour time..
*
* @param h the hour. Must be in range 0 to 23, inclusive.
* @param m the minute. Must be in range 0 to 59, inclusive.
* @param s the second. Must be in range 0 to 59, inclusive.
* @exception IllegalArgumentException if any
* of the parameters are out of range.
*/
public Time(int hour, int minute, int second)
{
if ( hour < 0 || hour >= 24 )
throw new IllegalArgumentException(
"Time: hour " + hour
+ " must be >=0 and < 24.");
if ( minute < 0 || minute >= 60 )
throw new IllegalArgumentException(
"Time: minute " + minute
+ " must be >=0 and < 60.");
if ( second < 0 || second >= 60 )
throw new IllegalArgumentException(
"Time: second " + second
+ " must be >=0 and < 60.");
// Initialize instance variables:
this.hour = (byte) hour;
this.minute = (byte) minute;
this.second = (byte) second;
} // constructor(int, int, int)
/**
* Returns the hour in a specification of this Time
* as an hour, minute, and second in 24-hour time.
*/
public byte getHour() { return hour; }
/**
* Returns the minute in a specification of this Time
* as an hour, minute, and second in 24-hour time.
*/
public byte getMinute() { return minute; }
/**
* Returns the second in a specification of this Time
* as an hour, minute, and second in 24-hour time.
*/
public byte getSecond() { return second; }
/**
* Returns an integer specifying this Time
* as a total number of seconds since midnight.
*/
public int getTotalSeconds()
{
return (hour * 3600 + minute * 60 + second);
} // method getTotalSeconds
/**
* Determines whether this Time is equal in value
* to the parameter object. A Time object if equal
* to another object if the other object is also of
* class Time and the two objects represent the
* same time in a day.
*
* @param o the object to which this Time is
* being compared for equality.
* @return true if this Time is equal to the
* parameter object, false otherwise.
*/
public boolean equals(Object other)
{
return ( other != null
&& getClass() == other.getClass()
&& hour == ((Time) other).hour
&& minute == ((Time) other).minute
&& second == ((Time) other).second );
} // method equals
/**
* If a class defines the equals method, it must
* also define a hashCode method such that
* two objects that are "equal" according to the
* equals method ALSO have the same hashCode.
*
* @return a hash code for this object
*/
public int hashCode()
{
// Exact details are unimportant as long
// as two "equal" objects have the same
// hash code. One simple implementation,
// good enough for this course, would be:
return toString().hashCode();
// This is okay ONLY IF toString() has
// been defined in such a way that any two
// objects of this class which are equal
// according to the equals method also
// return exactly equal strings when the
// toString() method is called.
} // method hashCode
/**
* Compares this Time object to the parameter
* Time object. Times begin at midnight, so
* the "earliest" time is midnight and the
* "latest" time is one second before the
* following midnight.
*
* @param other the Time with which this Time
* is being compared
* @return a negative integer if this Time precedes
* <code>other</code>, a positive integer if
* <code>other</code> precedes this Time, or
* zero if the two times are equal.
*/
public int compareTo(Time other)
{
if ( hour != other.hour )
return ( hour - other.hour );
if ( minute != other.minute )
return ( minute - other.minute );
return ( second - other.second );
} // method compareTo
/**
* Returns a String representing this Time
* as a 24-hour time in HH:MM:SS format.
*/
public String toString()
{
return padToTwoDigits(hour) + ":" +
padToTwoDigits(minute) + ":" +
padToTwoDigits(second);
} // method toString
/**
* Returns a String representing this Time
* as a 12-hour time in HH:MM:SS format,
* followed by " AM" or " PM".
*/
public String to12HourString()
{
String AMorPM = ( hour < 12 ) ? " AM" : " PM";
byte h = (byte) (hour % 12);
if ( h == 0 )
h = 12;
return padToTwoDigits(h) + ":" +
padToTwoDigits(minute) + ":" +
padToTwoDigits(second) + AMorPM;
} // method to12HourString
/**
* Returns a String representation of the parameter
* as a base-10 integer with a minimum of two digits,
* padded with a leading zero if necessary.
*
* @param b the number to be formatted.
* @return a 2-digit base-10 String representation of
* b, padded with a leading zero if necessary.
*/
private static String padToTwoDigits(byte b)
{
return ( b < 10 ) ? ("0" + b) : Byte.toString(b);
} // method padToTwoDigits
} // class Time