A Class that Represents a Moment in Time

From Java Example Source Code

Jump to: navigation, search

Contents

[edit] Overview - A Class that Represents a Moment in Time

This is a example of Java program.

[edit] Java Source Code

  • Package: dreyer.jacob
  • File: Time.java
package dreyer.jacob;
 
/*
 * This code 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 code 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 program;
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */
// package no.geosoft.cc.util;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
 
/**
 * A class representing a moment in time. Extends Day which represents the day of the moment, and
 * defines the time within the day to millisecond accuracy.
 * 
 * @author Jacob Dreyer (<a href="mailto:jacob.dreyer@geosoft.no">jacob.dreyer@geosoft.no</a>)
 */
public class Time extends Day {
    /**
     * Instantiate a Time object. The time is lenient meaning that illegal day parameters can be
     * specified and results in a recomputed day with legal month/day values.
     * 
     * @param year
     *            Year of this time
     * @param month
     *            Month of this time
     * @param dayOfMonth
     *            Day of month of this time.
     * @param hours
     *            Hours of this time [0-23]
     * @param minutes
     *            Minutes of this time [0-23]
     * @param seconds
     *            Seconds of this time [0-23]
     */
    public Time(int year, int month, int dayOfMonth, int hours, int minutes, int seconds) {
	super(year, month, dayOfMonth);
	setHours(hours);
	setMinutes(minutes);
	setSeconds(seconds);
    }
 
    public Time(Day day, int hours, int minutes, int seconds) {
	this(day.getYear(), day.getMonth(), day.getDayOfMonth(), hours, minutes, seconds);
    }
 
    public Time(int hours, int minutes, int seconds) {
	this(new Day(), hours, minutes, seconds);
    }
 
    public Time() {
	calendar_ = new GregorianCalendar(); // Now
    }
 
    public void setDay(Day day) {
	setYear(day.getYear());
	setMonth(day.getMonth());
	setDayOfMonth(day.getDayOfMonth());
    }
 
    public void setHours(int hours) {
	calendar_.set(Calendar.HOUR_OF_DAY, hours);
    }
 
    public int getHours() {
	return calendar_.get(Calendar.HOUR_OF_DAY);
    }
 
    public void setMinutes(int minutes) {
	calendar_.set(Calendar.MINUTE, minutes);
    }
 
    public int getMinutes() {
	return calendar_.get(Calendar.MINUTE);
    }
 
    public void setSeconds(int seconds) {
	calendar_.set(Calendar.SECOND, seconds);
    }
 
    public int getSeconds() {
	return calendar_.get(Calendar.SECOND);
    }
 
    public void setMilliSeconds(int milliSeconds) {
	calendar_.set(Calendar.MILLISECOND, milliSeconds);
    }
 
    public int getMilliSeconds() {
	return calendar_.get(Calendar.MILLISECOND);
    }
 
    public boolean isAfter(Time time) {
	return calendar_.after(time.calendar_);
    }
 
    public boolean isBefore(Time time) {
	return calendar_.before(time.calendar_);
    }
 
    public boolean equals(Time time) {
	return calendar_.equals(time.calendar_);
    }
 
    public void addHours(int nHours) {
	calendar_.add(Calendar.HOUR_OF_DAY, nHours);
    }
 
    public void addMinutes(int nMinutes) {
	calendar_.add(Calendar.MINUTE, nMinutes);
    }
 
    public void addSeconds(int nSeconds) {
	calendar_.add(Calendar.SECOND, nSeconds);
    }
 
    public void addMilliSeconds(int nMilliSeconds) {
	calendar_.add(Calendar.MILLISECOND, nMilliSeconds);
    }
 
    public long milliSecondsBetween(Time time) {
	long millisBetween = calendar_.getTime().getTime() - time.calendar_.getTime().getTime();
	return millisBetween;
    }
 
    public double secondsBetween(Time time) {
	long millisBetween = calendar_.getTime().getTime() - time.calendar_.getTime().getTime();
	return millisBetween / 1000;
    }
 
    public double minutesBetween(Time time) {
	long millisBetween = calendar_.getTime().getTime() - time.calendar_.getTime().getTime();
	return millisBetween / (1000 * 60);
    }
 
    public double hoursBetween(Time time) {
	long millisBetween = calendar_.getTime().getTime() - time.calendar_.getTime().getTime();
	return millisBetween / (1000 * 60 * 60);
    }
 
    public String toString() {
	StringBuffer string = new StringBuffer();
	string.append(super.toString());
	string.append(' ');
	if (getHours() < 10)
	    string.append('0');
	string.append(getHours());
	string.append(':');
	if (getMinutes() < 10)
	    string.append('0');
	string.append(getMinutes());
	string.append(':');
	if (getSeconds() < 10)
	    string.append('0');
	string.append(getSeconds());
	string.append(',');
	string.append(getMilliSeconds());
 
	return string.toString();
    }
 
    public static void main(String args[]) {
	Time time = new Time(12, 00, 00);
	System.out.println(time);
    }
}
 
class Day implements Comparable, Cloneable, Serializable {
    protected Calendar calendar_;
 
    /**
     * Initialize the internal calendar instance.
     * 
     * @param year
     *            Year of new day.
     * @param month
     *            Month of new day.
     * @param dayOfMonth
     *            Day of month of new day.
     */
    private void initialize(int year, int month, int dayOfMonth) {
	calendar_ = Calendar.getInstance();
	calendar_.setLenient(true);
	calendar_.setFirstDayOfWeek(Calendar.MONDAY);
	calendar_.setTimeZone(TimeZone.getTimeZone("GMT"));
	set(year, month, dayOfMonth);
    }
 
    /**
     * Create a new day. The day is lenient meaning that illegal day parameters can be specified and
     * results in a recomputed day with legal month/day values.
     * 
     * @param year
     *            Year of new day.
     * @param month
     *            Month of new day (0-11)
     * @param dayOfMonth
     *            Day of month of new day (1-31)
     */
    public Day(int year, int month, int dayOfMonth) {
	initialize(year, month, dayOfMonth);
    }
 
    /**
     * Create a new day, specifying the year and the day of year. The day is lenient meaning that
     * illegal day parameters can be specified and results in a recomputed day with legal month/day
     * values.
     * 
     * @param year
     *            Year of new day.
     * @param dayOfYear
     *            1=January 1, etc.
     */
    public Day(int year, int dayOfYear) {
	initialize(year, Calendar.JANUARY, 1);
	calendar_.set(Calendar.DAY_OF_YEAR, dayOfYear);
    }
 
    /**
     * Create a new day representing the day of creation (according to the setting of the current
     * machine).
     */
    public Day() {
	// Now (in the currenct locale of the client machine)
	Calendar calendar = Calendar.getInstance();
 
	// Prune time part
	initialize(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
    }
 
    /**
     * Create a new day based on a java.util.Calendar instance. NOTE: The time component from
     * calendar will be pruned.
     * 
     * @param calendar
     *            Calendar instance to copy.
     */
    public Day(Calendar calendar) {
	this(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
    }
 
    /**
     * Create a new day based on a java.util.Date instance. NOTE: The time component from date will
     * be pruned.
     * 
     * @param date
     *            Date instance to copy.
     */
    public Day(Date date) {
	// Create a calendar based on given date
	Calendar calendar = Calendar.getInstance();
	calendar.setTime(date);
 
	// Extract date values and use these only
	initialize(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
    }
 
    /**
     * Create a new day based on a time value. Time is milliseconds since "the Epoch" (1.1.1970).
     * NOTE: The time component from time will be pruned.
     * 
     * @param time
     *            Milliseconds since "the Epoch".
     */
    public Day(long time) {
	this(new Date(time));
    }
 
    /**
     * Create a new day as a copy of the specified day.
     * 
     * @param day
     *            Day to clone.
     */
    public Day(Day day) {
	this(day.getYear(), day.getMonth(), day.getDayOfMonth());
    }
 
    /**
     * Create a clone of this day.
     * 
     * @return This day cloned.
     */
    public Object clone() {
	return new Day(this);
    }
 
    /**
     * A more explicit front-end to the Day() constructor which return a day object representing the
     * day of creation.
     * 
     * @return A day instance representing today.
     */
    public static Day today() {
	return new Day();
    }
 
    /**
     * Return a Calendar instance representing the same day as this instance. For use by secondary
     * methods requiring java.util.Calendar as input.
     * 
     * @return Calendar equivalent representing this day.
     */
    public Calendar getCalendar() {
	return (Calendar) calendar_.clone();
    }
 
    /**
     * Return a Date instance representing the same date as this instance. For use by secondary
     * methods requiring java.util.Date as input.
     * 
     * @return Date equivalent representing this day.
     */
    public Date getDate() {
	return getCalendar().getTime();
    }
 
    /**
     * Compare this day to the specified day. If object is not of type Day a ClassCastException is
     * thrown.
     * 
     * @param object
     *            Day object to compare to.
     * @return
     * @see Comparable#compareTo(Object)
     * @throws ClassCastException
     *             If object is not of type Day.
     */
    public int compareTo(Object object) {
	Day day = (Day) object;
	return calendar_.getTime().compareTo(day.calendar_.getTime());
    }
 
    /**
     * Return true if this day is after the specified day.
     * 
     * @param date
     *            Day to compare to.
     * @return True if this is after day, false otherwise.
     */
    public boolean isAfter(Day day) {
	return calendar_.after(day.calendar_);
    }
 
    /**
     * Return true if this day is before the specified day.
     * 
     * @param date
     *            Day to compare to.
     * @return True if this is before day, false otherwise.
     */
    public boolean isBefore(Day day) {
	return calendar_.before(day.calendar_);
    }
 
    /**
     * Return true if this day equals (represent the same date) as the specified day.
     * 
     * @param date
     *            Day to compare to.
     * @return True if this equals day, false otherwise.
     */
    public boolean equals(Day day) {
	return calendar_.equals(day.calendar_);
    }
 
    /**
     * Overload required as default definition of equals() has changed.
     * 
     * @return A hash code value for this object.
     */
    public int hashCode() {
	return calendar_.hashCode();
    }
 
    /**
     * Set date of this day. The day is lenient meaning that illegal day parameters can be specified
     * and results in a recomputed day with legal month/day values.
     * 
     * @param year
     *            Year of this day.
     * @param month
     *            Month of this day (0-11).
     * @param dayOfMonth
     *            Day of month of this day (1-31).
     */
    public void set(int year, int month, int dayOfMonth) {
	setYear(year);
	setMonth(month);
	setDayOfMonth(dayOfMonth);
    }
 
    /**
     * Return year of this day.
     * 
     * @return Year of this day.
     */
    public int getYear() {
	return calendar_.get(Calendar.YEAR);
    }
 
    /**
     * Set year of this day.
     * 
     * @param year
     *            New year of this day.
     */
    public void setYear(int year) {
	calendar_.set(Calendar.YEAR, year);
    }
 
    /**
     * Return month of this day. The result must be compared to Calendar.JANUARY, Calendar.FEBRUARY,
     * etc.
     * 
     * @return Month of this day.
     */
    public int getMonth() {
	return calendar_.get(Calendar.MONTH);
    }
 
    /**
     * Return the 1-based month number of the month of this day. 1 = January, 2 = February and so
     * on.
     * 
     * @return Month number of this month
     */
    public int getMonthNo() {
	// It is tempting to return getMonth() + 1 but this is conceptually
	// wrong, as Calendar month is an enumeration and the values are tags
	// only and can be anything.
	switch (getMonth()) {
	case Calendar.JANUARY:
	    return 1;
	case Calendar.FEBRUARY:
	    return 2;
	case Calendar.MARCH:
	    return 3;
	case Calendar.APRIL:
	    return 4;
	case Calendar.MAY:
	    return 5;
	case Calendar.JUNE:
	    return 6;
	case Calendar.JULY:
	    return 7;
	case Calendar.AUGUST:
	    return 8;
	case Calendar.SEPTEMBER:
	    return 9;
	case Calendar.OCTOBER:
	    return 10;
	case Calendar.NOVEMBER:
	    return 11;
	case Calendar.DECEMBER:
	    return 12;
	}
 
	// This will never happen
	return 0;
    }
 
    /**
     * Set month of this day. January = 0, February = 1, etc. Illegal month values will result in a
     * recomputation of year and a resetting of month to a valid value. I.e. setMonth(20), will add
     * 1 year to day and set month to 8.
     * 
     * @param month
     *            New month of this day.
     */
    public void setMonth(int month) {
	calendar_.set(Calendar.MONTH, month);
    }
 
    /**
     * Return day of month of this day. NOTE: First day of month is 1 (not 0).
     * 
     * @return Day of month of this day.
     */
    public int getDayOfMonth() {
	return calendar_.get(Calendar.DAY_OF_MONTH);
    }
 
    /**
     * Set day of month of this date. 1=1st 2=2nd, etc. Illegal day values will result in a
     * recomputation of month/year and a resetting of day to a valid value. I.e. setDayOfMonth(33),
     * will add 1 month to date and set day to 5, 4, 3 or 2 depending on month/year.
     * 
     * @param dayOfMonth
     *            New day of month of this day.
     */
    public void setDayOfMonth(int dayOfMonth) {
	calendar_.set(Calendar.DAY_OF_MONTH, dayOfMonth);
    }
 
    /**
     * Return the day number of year this day represents. January 1 = 1 and so on.
     * 
     * @return day number of year.
     */
    public int getDayOfYear() {
	return calendar_.get(Calendar.DAY_OF_YEAR);
    }
 
    /**
     * Return the day of week of this day. NOTE: Must be compared to Calendar.MONDAY, TUSEDAY etc.
     * 
     * @return Day of week of this day.
     */
    public int getDayOfWeek() {
	return calendar_.get(Calendar.DAY_OF_WEEK);
    }
 
    /**
     * Return the day number of week of this day, where Monday=1, Tuesday=2, ... Sunday=7.
     * 
     * @return Day number of week of this day.
     */
    public int getDayNumberOfWeek() {
	return getDayOfWeek() == Calendar.SUNDAY ? 7 : getDayOfWeek() - Calendar.SUNDAY;
    }
 
    /**
     * Return the week number of year, this day belongs to. 1st=1 and so on.
     * 
     * @return Week number of year of this day.
     */
    public int getWeekOfYear() {
	return calendar_.get(Calendar.WEEK_OF_YEAR);
    }
 
    /**
     * Add a number of days to this day. Subtracting a number of days can be done by a negative
     * argument to addDays() or calling subtractDays() explicitly.
     * 
     * @param nDays
     *            Number of days to add.
     */
    public void addDays(int nDays) {
	calendar_.add(Calendar.DAY_OF_MONTH, nDays);
    }
 
    /**
     * Subtract a number of days from this day
     * 
     * @param nDays
     *            Number of days to subtract.
     */
    public void subtractDays(int nDays) {
	addDays(-nDays);
    }
 
    /**
     * Add a number of months to this day. The actual number of days added depends on the staring
     * day. Subtracting a number of months can be done by a negative argument to addMonths() or
     * calling subtactMonths() explicitly. NOTE: addMonth(n) m times will in general give a
     * different result than addMonth(m*n). Add 1 month to January 31, 2005 will give February 28,
     * 2005.
     * 
     * @param nMonths
     *            Number of months to add.
     */
    public void addMonths(int nMonths) {
	calendar_.add(Calendar.MONTH, nMonths);
    }
 
    /**
     * Subtract a number of months from this day
     * 
     * @see #addMonths(int).
     * 
     * @param nDays
     *            Number of days to subtract.
     */
    public void subtractMonths(int nMonths) {
	addMonths(-nMonths);
    }
 
    /**
     * Add a number of years to this day. The actual number of days added depends on the starting
     * day. Subtracting a number of years can be done by a negative argument to addYears() or
     * calling subtractYears explicitly.
     * 
     * @param nYears
     *            Number of years to add.
     */
    public void addYears(int nYears) {
	calendar_.add(Calendar.YEAR, nYears);
    }
 
    /**
     * Subtract a number of years from this day
     * 
     * @see #addYears(int).
     * 
     * @param nYears
     *            Number of years to subtract.
     */
    public void subtractYears(int nYears) {
	addYears(-nYears);
    }
 
    /**
     * Return the number of days in the year of this day.
     * 
     * @return Number of days in this year.
     */
    public int getDaysInYear() {
	return calendar_.getActualMaximum(Calendar.DAY_OF_YEAR);
    }
 
    /**
     * Return true if the year of this day is a leap year.
     * 
     * @return True if this year is a leap year, false otherwise.
     */
    public boolean isLeapYear() {
	return getDaysInYear() == calendar_.getMaximum(Calendar.DAY_OF_YEAR);
    }
 
    /**
     * Return true if the specified year is a leap year.
     * 
     * @param year
     *            Year to check.
     * @return True if specified year is leap year, false otherwise.
     */
    public static boolean isLeapYear(int year) {
	return (new Day(year, Calendar.JANUARY, 1)).isLeapYear();
    }
 
    /**
     * Return the number of days in the month of this day.
     * 
     * @return Number of days in this month.
     */
    public int getDaysInMonth() {
	return calendar_.getActualMaximum(Calendar.DAY_OF_MONTH);
    }
 
    /**
     * Get default locale name of this day ("Monday", "Tuesday", etc.
     * 
     * @return Name of day.
     */
    public String getDayName() {
	switch (getDayOfWeek()) {
	case Calendar.MONDAY:
	    return "Monday";
	case Calendar.TUESDAY:
	    return "Tuesday";
	case Calendar.WEDNESDAY:
	    return "Wednesday";
	case Calendar.THURSDAY:
	    return "Thursday";
	case Calendar.FRIDAY:
	    return "Friday";
	case Calendar.SATURDAY:
	    return "Saturday";
	case Calendar.SUNDAY:
	    return "Sunday";
	}
 
	// This will never happen
	return null;
    }
 
    /**
     * Return number of days between two days. The method always returns a positive number of days.
     * 
     * @param date
     *            The day to compare to.
     * @return Number of days between this and day.
     */
    public int daysBetween(Day day) {
	long millisBetween = Math.abs(calendar_.getTime().getTime() - day.calendar_.getTime().getTime());
	return (int) Math.round(millisBetween / (1000 * 60 * 60 * 24));
    }
 
    /**
     * Find the n'th xxxxday of s specified month (for instance find 1st sunday of May 2006;
     * findNthOfMonth (1, Calendar.SUNDAY, Calendar.MAY, 2006); Return null if the specified day
     * doesn't exists.
     * 
     * @param n
     *            Nth day to look for.
     * @param dayOfWeek
     *            Day to look for (Calendar.XXXDAY).
     * @param month
     *            Month to check (Calendar.XXX).
     * @param year
     *            Year to check.
     * @return Required Day (or null if non-existent)
     * @throws ArrayIndexOutOfBoundsException
     *             if dyaOfWeek parameter doesn't represent a valid day.
     */
    public static Day getNthOfMonth(int n, int dayOfWeek, int month, int year) throws ArrayIndexOutOfBoundsException {
	// Validate the dayOfWeek argument
	if (dayOfWeek < 0 || dayOfWeek > 6)
	    throw new ArrayIndexOutOfBoundsException(dayOfWeek);
 
	Day first = new Day(year, month, 1);
 
	int offset = dayOfWeek - first.getDayOfWeek();
	if (offset < 0)
	    offset = 7 + offset;
 
	int dayNo = (n - 1) * 7 + offset + 1;
 
	return dayNo > first.getDaysInMonth() ? null : new Day(year, month, dayNo);
    }
 
    /**
     * Find the first of a specific day in a given month, for instance first Tuesday of May:
     * getFirstOfMonth (Calendar.TUESDAY, Calendar.MAY, 2005);
     * 
     * @param dayOfWeek
     *            Weekday to get.
     * @param month
     *            Month of day to get.
     * @param year
     *            Year of day to get.
     * @return The requested day.
     */
    public static Day getFirstOfMonth(int dayOfWeek, int month, int year) {
	return Day.getNthOfMonth(1, dayOfWeek, month, year);
    }
 
    /**
     * Find the last of a specific day in a given month, for instance last Tuesday of May:
     * getLastOfMonth (Calendar.TUESDAY, Calendar.MAY, 2005);
     * 
     * @param dayOfWeek
     *            Weekday to get.
     * @param month
     *            Month of day to get.
     * @param year
     *            Year of day to get.
     * @return The requested day.
     */
    public static Day getLastOfMonth(int dayOfWeek, int month, int year) {
	Day day = Day.getNthOfMonth(5, dayOfWeek, month, year);
	return day != null ? day : Day.getNthOfMonth(4, dayOfWeek, month, year);
    }
 
    /**
     * Return a scratch string representation of this day. Used for debugging only. The format of
     * the day is dd/mm-yyyy
     * 
     * @return A string representation of this day.
     */
    public String toString() {
	StringBuffer string = new StringBuffer();
 
	if (getDayOfMonth() < 10)
	    string.append('0');
	string.append(getDayOfMonth());
	string.append('/');
	if (getMonth() < 9)
	    string.append('0');
	string.append(getMonth() + 1);
	string.append('-');
	string.append(getYear());
	string.append(" ");
	string.append(getDayName());
 
	return string.toString();
    }
 
    /**
     * Testing this class.
     * 
     * @param args
     *            Not used.
     */
    public static void main(String[] args) {
	// This proves that there are 912 days between the two major
	// terrorist attacks, not 911 as is common knowledge.
	Day september11 = new Day(2001, Calendar.SEPTEMBER, 11);
	Day march11 = new Day(2004, Calendar.MARCH, 11);
	System.out.println(september11.daysBetween(march11));
 
	// This proves that Kennedy was president for 1037 days,
	// not 1000 as is the popular belief nor 1036 which is the
	// bluffers reply. Nerds knows when to add one...
	Day precidency = new Day(1961, Calendar.JANUARY, 20);
	Day assasination = new Day(1963, Calendar.NOVEMBER, 22);
	System.out.println(precidency.daysBetween(assasination) + 1);
 
	// Niel Armstrong walked the moon on a Sunday
	Day nielOnMoon = new Day(1969, Calendar.JULY, 20);
	System.out.println(nielOnMoon.getDayNumberOfWeek());
 
	// Find last tuesdays for 2005
	for (int i = 0; i < 12; i++) {
	    Day tuesday = Day.getLastOfMonth(Calendar.TUESDAY, i, 2005);
	    System.out.println(tuesday);
	}
    }
}

[edit] What Result You Can Get

Coming soon...

[edit] Required External Libraries and/or Files for this Java Example

Need nothing.


[edit] How to Run this Java Example Program

We recommend running this Java example program with Eclipse.

For assistance in working with Eclipse, please see How to Run Java Program with Eclipse.

It's fairly easy.



[edit] Question & Answer

Any question?

Click edit and post your question or answer here.


Personal tools