/* ** j###t ########## #### #### ** j###t ########## #### #### ** j###T "###L J###" ** ######P' ########## ######### ** ######k, ########## T######T ** ####~###L #### ** #### q###L ########## .##### ** #### \###L ########## #####" ** ** Class History ** ** Date Name Description ** ---------|------------|----------------------------------------------- ** 06Oct97 exile created this utility class ** 10Jul97 merlin fixed to handle milliseconds greater than 10 digits** ** 05Nov98 subtle made immutable for security */ package key.primitive; import key.Grammar; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.StringTokenizer; /** * Represents an amount of time, such as 4 hours, or * 3 days, or whatever */ public final class Duration implements java.io.Serializable { long milliseconds; public Duration() { milliseconds = 0; } /** * Constructs a new time with the specified duration * in milliseconds */ public Duration( long duration ) { milliseconds = duration; } public Object Clone() { return( new Duration( milliseconds ) ); } public long getTime() { return( milliseconds ); } public final long getHours() { return( milliseconds / SIH ); } /* public void setTime( long duration ) { milliseconds = duration; } */ /* - find the places that do this and change the - add method to be functional in nature public void add( Duration d ) { milliseconds += d.milliseconds; } */ /** * Adds the supplied duration number times */ public Duration addMultiple( Duration d, int number ) { return( new Duration( milliseconds + (d.milliseconds * number) ) ); } public void subtract( Duration d ) { milliseconds -= d.milliseconds; } /** * Given a string that represents a duration, parse it into a * value that can be used to construct a Duration. (Don't * tell anyone, but it returns the duration in milliseconds). */ public static long parse( String s ) throws NumberFormatException { StringTokenizer st = new StringTokenizer( s, "hmsMwdfyq", true ); long millisecs = 0; Double length; char periodType; boolean negative = false; long working; while( st.hasMoreTokens() ) { length = Double.valueOf( st.nextToken() ); if( st.hasMoreTokens() ) { periodType = st.nextToken().charAt(0); switch( periodType ) { case 'y': working = (long)( SIY * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; case 's': working = (long)( SIS * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; case 'w': working = (long)( SIW * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; case 'M': working = (long)( SIMTH * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; case 'f': working = (long)( SIF * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; case 'q': working = (long)( SIQ * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; case 'd': working = (long)( SID * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; case 'm': working = (long)( SIM * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; case 'h': default: working = (long)( SIH * length.doubleValue() ); if( working < 0 ) { negative = true; working *= -1; } millisecs += working; break; } } } if ( negative ) millisecs *= -1; return( millisecs ); } public static final long SIS=1000; // milliseconds in a Second public static final long SIM=60 * SIS; // milliseconds in a Minute public static final long SIH=60 * SIM; // milliseconds in a Hour public static final long SID=24 * SIH; // milliseconds in a Day public static final long SIW=7 * SID; // milliseconds in a Week public static final long SIF=2 * SIW; // milliseconds in a Fortnight public static final long SIMTH = 4 * SIW; // milliseconds in a Month public static final long SIQ= 3 * SIMTH; // milliseconds in a Quarter public static final long SIY=365 * SID; // milliseconds in a Year /** *Return short version of time (ETB) */ public String toShortString() { return( toShortString( milliseconds ) ); } public static String toShortString( long milliseconds ) { String theTime = ""; String seconds = ""; String minutes = ""; long secs = 0; long yrs=0; long wks=0; long days=0; long hrs=0; long mins=0; secs = milliseconds - ( ( yrs = getYears( milliseconds ) ) * SIY ); secs = secs - ( ( wks=getWeeks( secs ) ) * SIW ); secs = secs - ( ( days=getDays( secs ) ) * SID ); secs = secs - ( ( hrs=getHours( secs ) ) * SIH ); secs = secs - ( ( mins=getMinutes( secs ) ) * SIM ); secs = secs / 1000; if( secs < 10 ) seconds = "0"; else seconds = ""; seconds += Long.toString( secs ); if ( mins < 10 ) minutes = " "; else minutes = ""; minutes += Long.toString( mins ); theTime = minutes + ":" + seconds ; return theTime; } /** * This routine courtesy of Adam Teague (brann) */ public String toString() { return( toString( milliseconds, false ) ); } public String toTruncString() { return( toString( milliseconds, true ) ); } public static String toString( long milliseconds, boolean shrt ) { String TheTime[]; int count = 0; long secs = 0; long yrs = 0; long wks = 0; long days = 0; long hrs = 0; long mins = 0; if ( milliseconds < 0 ) milliseconds *= -1; secs = milliseconds - ( ( yrs = getYears( milliseconds ) ) * SIY ); secs = secs - ( ( wks = getWeeks( secs ) ) * SIW ); secs = secs - ( ( days = getDays( secs ) ) * SID ); secs = secs - ( ( hrs = getHours( secs ) ) * SIH ); secs = secs - ( ( mins = getMinutes( secs ) ) * SIM ); secs = secs / 1000; TheTime = new String[ 7 ]; count=0; if( yrs != 0 ) TheTime[ count++ ] = Long.toString( yrs ) + " year" + ( yrs != 1 ? "s" : "" ); if( wks != 0 ) TheTime[ count++ ] = Long.toString( wks ) + " week" + ( wks != 1 ? "s" : "" ); if( days != 0 ) TheTime[ count++ ] = Long.toString( days ) + " day" + ( days != 1 ? "s" : "" ); if( hrs != 0 ) TheTime[ count++ ] = Long.toString( hrs ) + " hour" + ( hrs != 1 ? "s" : "" ); if( mins != 0 && !(count > 1 && shrt) ) TheTime[ count++ ] = Long.toString( mins ) + " minute" + ( mins != 1 ? "s" : "" ); if( secs != 0 && !(count > 1 && shrt) ) TheTime[ count++ ] = Long.toString( secs ) + " second" + ( secs != 1 ? "s" : "" ); if( count == 0 ) return( "no time at all" ); return( Grammar.enumerate( TheTime, count ) ); } static private int getYears( long milliseconds ) { return( (int)( milliseconds / SIY) ); } static private int getWeeks( long milliseconds ) { return( (int)( milliseconds / SIW) ); } static private int getDays( long milliseconds ) { return( (int)( milliseconds / SID) ); } static private int getHours( long milliseconds ) { return( (int)( milliseconds / SIH) ); } static private int getMinutes( long milliseconds ) { return( (int)( milliseconds / SIM) ); } }