Time library : Time « Development Class « Java






Time library

    
//revised from prefuse

import java.lang.reflect.Constructor;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Library routines for dealing with times and time spans. All time values
 * are given as long values, indicating the number of milliseconds since
 * the epoch (January 1, 1970). This is the same time format returned
 * by the {@link java.lang.System#currentTimeMillis()} method.
 * 
 * @author jeffrey heer
 */
public class TimeLib {

    /** Represents a millenium, 1000 years. */
    public static final int MILLENIUM = -1000;
    /** Represents a century, 100 years */
    public static final int CENTURY   = -100;
    /** Represents a decade, 10 years */
    public static final int DECADE    = -10;
    
    private static final double SECOND_MILLIS    = 1000;
    private static final double MINUTE_MILLIS    = SECOND_MILLIS*60;
    private static final double HOUR_MILLIS      = MINUTE_MILLIS*60;
    private static final double DAY_MILLIS       = HOUR_MILLIS * 24.0015;
    private static final double WEEK_MILLIS      = DAY_MILLIS * 7;
    private static final double MONTH_MILLIS     = DAY_MILLIS * 30.43675;
    private static final double YEAR_MILLIS      = WEEK_MILLIS * 52.2;
    private static final double DECADE_MILLIS    = YEAR_MILLIS * 10;
    private static final double CENTURY_MILLIS   = DECADE_MILLIS * 10;
    private static final double MILLENIUM_MILLIS = CENTURY_MILLIS * 10;
    
    private static final int[] CALENDAR_FIELDS = {
        Calendar.YEAR, Calendar.MONTH, Calendar.DATE, Calendar.HOUR_OF_DAY,
        Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND    
    };
    
    private TimeLib() {
        // prevent instantiation
    }
    
    /**
     * Get the number of time units between the two given timestamps.
     * @param t0 the first timestamp (as a long)
     * @param t1 the second timestamp (as a long)
     * @param field the time unit to use, one of the {@link java.util.Calendar}
     * fields, or one of the extended fields provided by this class
     * (MILLENIUM, CENTURY, or DECADE).
     * @return the number of time units between the two timestamps
     */
    public static int getUnitsBetween(long t0, long t1, int field) {
        boolean negative = false;
        if ( t1 < t0 ) {
            long tmp = t1; t1 = t0; t0 = tmp; // swap
            negative = true;
        }
        GregorianCalendar gc1 = new GregorianCalendar();
        GregorianCalendar gc2 = new GregorianCalendar();
        gc1.setTimeInMillis(t0);
        gc2.setTimeInMillis(t1);
        
        // add 2 units less than the estimate to 1st date,
        // then serially add units till we exceed 2nd date
        int est = estimateUnitsBetween(t0, t1, field);
        boolean multiYear = isMultiYear(field);
        if ( multiYear ) {
            gc1.add(Calendar.YEAR, -field*(est-2));
            est = -field*est;
        } else {
            gc1.add(field, est-2);
        }
        int f = multiYear ? Calendar.YEAR : field;
        int inc = multiYear ? -field : 1;
        for( int i=est-inc; ; i+=inc ) {
            gc1.add(f, inc);
            if( gc1.after(gc2) ) {
                return negative ? inc-i : i-inc;
            }
        }
    }
    
    /**
     * Based on code posted at
     *  http://forum.java.sun.com/thread.jspa?threadID=488676&messageID=2292012
     */
    private static int estimateUnitsBetween(long t0, long t1, int field) {
        long d = t1-t0;
        switch (field) {
        case Calendar.MILLISECOND:
            return (int)d; // this could be very inaccurate. TODO: use long instead of int?
        case Calendar.SECOND:
            return (int)(d / SECOND_MILLIS + .5);
        case Calendar.MINUTE:
            return (int)(d / MINUTE_MILLIS + .5);
        case Calendar.HOUR_OF_DAY:
        case Calendar.HOUR:
            return (int)(d / HOUR_MILLIS + .5);
        case Calendar.DAY_OF_WEEK_IN_MONTH :
        case Calendar.DAY_OF_MONTH :
        // case Calendar.DATE : // codes to same int as DAY_OF_MONTH
            return (int) (d / DAY_MILLIS + .5);
        case Calendar.WEEK_OF_YEAR :
            return (int) (d / WEEK_MILLIS + .5);
        case Calendar.MONTH :
            return (int) (d / MONTH_MILLIS + .5);
        case Calendar.YEAR :
            return (int) (d / YEAR_MILLIS + .5);
        case DECADE:
            return (int) (d / DECADE_MILLIS + .5);
        case CENTURY:
            return (int) (d / CENTURY_MILLIS + .5);
        case MILLENIUM:
            return (int) (d / MILLENIUM_MILLIS + .5);
        default:
            return 0;
        }
    }
        
    /**
     * Increment a calendar by a given number of time units.
     * @param c the calendar to increment
     * @param field the time unit to increment, one of the
     * {@link java.util.Calendar} fields, or one of the extended fields
     * provided by this class (MILLENIUM, CENTURY, or DECADE).
     * @param val the number of time units to increment by
     */
    public static void increment(Calendar c, int field, int val) {
        if ( isMultiYear(field) ) {
            c.add(Calendar.YEAR, -field*val);
        } else {
            c.add(field, val);
        }
    }
    
    /**
     * Get the value of the given time field for a Calendar. Just like the
     * {@link java.util.Calendar#get(int)} method, but include support for
     * the extended fields provided by this class (MILLENIUM, CENTURY, or
     * DECADE).
     * @param c the Calendar
     * @param field the time field
     * @return the value of the time field for the given calendar
     */
    public static int get(Calendar c, int field) {
        if ( isMultiYear(field) ) {
            int y = c.get(Calendar.YEAR);
            return -field * (y/-field);
        } else {
            return c.get(field);
        }
    }
    
    // ------------------------------------------------------------------------
    // Date Access
    
    /**
     * Get the timestamp for the given year, month, and, day.
     * @param c a Calendar to use to help compute the result. The state of the
     * Calendar will be overwritten.
     * @param year the year to look up
     * @param month the month to look up (months start at 0==January)
     * @param day the day to look up
     * @return the timestamp for the given date
     */
    public static long getDate(Calendar c, int year, int month, int day) {
        c.clear(Calendar.MILLISECOND);
        c.set(year, month, day, 0, 0, 0);
        return c.getTimeInMillis();
    }

    /**
     * Get a timestamp for the given hour, minute, and second. The date will
     * be assumed to be January 1, 1970.
     * @param c a Calendar to use to help compute the result. The state of the
     * Calendar will be overwritten.
     * @param hour the hour, on a 24 hour clock
     * @param minute the minute value
     * @param second the seconds value
     * @return the timestamp for the given date
     */
    public static long getTime(Calendar c, int hour, int minute, int second) {
        c.clear(Calendar.MILLISECOND);
        c.set(1970, 0, 1, hour, minute, second);
        return c.getTimeInMillis();
    }
    
    /**
     * Get a new Date instance of the specified subclass and given long value.
     * @param type the concrete subclass of the Date instance, must be an
     * instance of subclass of java.util.Date
     * @param d the date/time value as a long
     * @return the new Date instance, or null if the class type is not valid
     */
    public static Date getDate(Class type, long d) {
        try {
            Constructor c = type.getConstructor(new Class[] {long.class});
            return (Date)c.newInstance(new Object[] {new Long(d)});
        } catch ( Exception e ) {
            e.printStackTrace();
            return null;
        }
    }
    
    // ------------------------------------------------------------------------
    // Date Normalization
    
    /**
     * Get the timestamp resulting from clearing (setting to zero) all time
     * values less than or equal to that of the given field. For example,
     * clearing to {@link Calendar#HOUR} will floor the time to nearest
     * hour which occurred before or at the given time (e.g., 1:32
     * --> 1:30).
     * @param t the reference time
     * @param c a Calendar instance used to help compute the value, the
     * state of the Calendar will be overwritten.
     * @param field the time field to clear to, one of the
     * {@link java.util.Calendar} fields, or one of the extended fields
     * provided by this class (MILLENIUM, CENTURY, or DECADE).
     * @return the cleared time
     */
    public static long getClearedTime(long t, Calendar c, int field) {
        c.setTimeInMillis(t);
        TimeLib.clearTo(c, field);
        return c.getTimeInMillis();
    }
    
    /**
     * Clear the given calendar, setting to zero all time
     * values less than or equal to that of the given field. For example,
     * clearing to {@link Calendar#HOUR} will floor the time to nearest
     * hour which occurred before or at the given time (e.g., 1:32
     * --> 1:30).
     * @param c the Calendar to clear
     * @param field the time field to clear to, one of the
     * {@link java.util.Calendar} fields, or one of the extended fields
     * provided by this class (MILLENIUM, CENTURY, or DECADE).
     * @return the original Calendar reference, now set to the cleared time
     */
    public static Calendar clearTo(Calendar c, int field) {
        int i = CALENDAR_FIELDS.length-1;
        for ( ; i>=1 && field != CALENDAR_FIELDS[i]; i-- ) {
            int val = (CALENDAR_FIELDS[i]==Calendar.DATE?1:0);
            c.set(CALENDAR_FIELDS[i],val);
        }
        if ( isMultiYear(field) ) {
            int y = c.get(Calendar.YEAR);
            y = -field * (y/-field);
            c.set(Calendar.YEAR, y);
        }
        return c;
    }
    
    /**
     * Indicates if a field value indicates a timespan greater than one
     * year. These multi-year spans are the extended fields introduced by
     * this class (MILLENIUM, CENTURY, and DECADE).
     * @param field the time field
     * @return true if the field is multi-year, false otherwise
     */
    public static boolean isMultiYear(int field) {
        return ( field == DECADE || field == CENTURY || field == MILLENIUM );
    }
    
} // end of class TimeLib

   
    
    
    
  








Related examples in the same category

1.Get Time From Date
2.ISO8601 Date Time Format
3.Time Format
4.Time Formatter
5.Returns time string
6.Returns the given date with the time values cleared
7.Convert the time to the midnight of the currently set date
8.Compare both times and dates
9.Tells you if the date part of a datetime is in a certain time range
10.Returns the given date with time set to the end of the day
11.Convert milliseconds to readable string
12.Determines whether or not a date has any time values (hour, minute, seconds or millisecondsReturns the given date with the time values cleared
13.Returns a formatted String from time
14.Elapsed time in hours/minutes/seconds
15.Sets the time on the same day to 00:00:00.000
16.Determines if given times span at least an entire day
17.Converts a given time in milliseconds into a XMLGregorianCalendar object.
18.Time Distance
19.Time Formatter
20.Format time
21.A utility class for representing a span of time.
22.GmtCalendar is a useful class for working with times that are based using GMT time.
23.Time Period
24.Represents the TSTInfo strcture within a time-stamp token (RFC 3161).
25.SimpleTimer enables bounded and unbounded waits.
26.Takes a time in milliseconds and returns an hours, minutes and seconds representation.
27.Format time in milliseconds