/** * Utility provides a number of static data formatting utilities.<p> * * Copyright &copy; 1998-89 Martin Minow. All Rights Reserved.<p> * * Permission to use, copy, modify, and redistribute this software and its * documentation for personal, non-commercial use is hereby granted provided that * this copyright notice and appropriate documentation appears in all copies. This * software may not be distributed for fee or as part of commercial, "shareware," * and/or not-for-profit endevors including, but not limited to, CD-ROM collections, * online databases, and subscription services without specific license.<p> * * Based on DateGUI.java in Mastering JavaBeans. * @see <a href="http://www.sybase.com">Sybase</a>, click on *  "Catalog>Updates>Mastering JavaBeans". * @author <a href="mailto:minow@pobox.com">Martin Minow</a> * @version 1.0a0 * Set tabs every 8 characters. */package org.minow.applets.sunsphere;import java.beans.*;import java.util.*;import java.awt.*;import java.awt.event.*;import java.awt.image.*;import java.text.*;public class Utility extends Object{    public static final double	DegRad		= Math.PI / 180.0;        public static final char	degreeSign	= '\u00B0';	// 'd';    public static final char	minuteSign	= '\'';		// 'm';    public static final char	secondSign	= '"';		// 's';    /**     * Convert a Java Date to an ISO date string.     * @param	javaDate	The date to convert     * @result	A string in the format YYYY.MM.DD HH:MM:SS.FFF     */    public static String getDateString(	    Date		javaDate	)    {	SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS");	return (formatter.format(javaDate));    }    /**     * Return a reasonable string representation of this timezone for     * the indicated date.     * @param timeZone		The timezone of interest.     * @param javaDate		The date of interest.     * @result	A reasonably formatted value.     */    public static String getTimeZoneValueText(    	    TimeZone		timeZone,    	    Date		javaDate    	)    {    	int timeZoneOffset	= getTimeZoneOffset(timeZone, javaDate);    	String result    		= ((timeZoneOffset > 0) ? "  +" : "  ")    		+ getHMString(((double) timeZoneOffset) / 3600000.0);    	return (result);    }    /**     * Return the current TimeZone offset for the current date, taking     * Daylight Savings Time adjustments into effect.     * @return The current TimeZone offset in milliseconds.     */    public static int getTimeZoneOffset()    {	return (getTimeZoneOffset(new Date()));    }    /**     * Return the current TimeZone offset, taking Daylight Savings     * Time adjustments into effect.     * @param javaDate		The date to use (defines DST etc.)     * @return The current TimeZone offset in milliseconds.     */    public static int getTimeZoneOffset(	    Date		javaDate	)    {	GregorianCalendar	calendar = new GregorianCalendar();	calendar.setTime(javaDate);	return (getTimeZoneOffset(calendar.getTimeZone(), javaDate));    }    /**     * Return the current TimeZone offset, taking Daylight Savings     * Time adjustments into effect for a specific timezone and date     * @param timeZone		The timezone to use     * @param javaDate		The date to use (defines DST etc.)     * @return The current TimeZone offset in milliseconds.     */    public static int getTimeZoneOffset(	    TimeZone		timeZone,	    Date		javaDate	)    {	SimpleTimeZone	zone	= (SimpleTimeZone) timeZone;	int tzOffset		= zone.getRawOffset();	if (zone.inDaylightTime(javaDate)) {	    tzOffset		+= 3600000; /* Msec in one hour */	}	return (tzOffset);    }    /**     * Return the current timezone for this date and the user's     * current location.     */    public static TimeZone getTimeZone()    {	return (getTimeZone(new Date()));    }    /**     * Return the current timezone for a specific date and the user's     * current location.     */    public static TimeZone getTimeZone(	    Date		javaDate	)    {	GregorianCalendar	calendar = new GregorianCalendar();	calendar.setTime(javaDate);	return (calendar.getTimeZone());    }    /**     * Return the name of the timezone associated with the     * current date.     */    public static String getTimeZoneName()    {	return (getTimeZoneName(new Date()));    }    /**     * Return the name of the timezone associated with a     * specified date.     */    public static String getTimeZoneName(	    Date		javaDate	)    {	GregorianCalendar calendar = new GregorianCalendar();	calendar.setTime(javaDate);	SimpleTimeZone	zone	= (SimpleTimeZone) calendar.getTimeZone();	return (zone.getID());    }    /**     * Return true if the indicated date is in Daylight Savings     * Time in the current location's TimeZone.     */    public static boolean inDaylightTime(	    Date		javaDate	)    {	GregorianCalendar calendar = new GregorianCalendar();	calendar.setTime(javaDate);	SimpleTimeZone	zone	= (SimpleTimeZone) calendar.getTimeZone();	return (zone.inDaylightTime(javaDate));    }    /**     * Format a latitude value. Note that this must handle the wierd case     * where the observer has the world upside down.     */    public static String getLatitudeString(	    double		value	)    {    	if (value < 0.0) {    	    value		= 360.0 + value;    	}    	if (value >= 180.0) {    	    value		= value - 360.0;    	}	return (getDMSString(value, "NS"));    }    public static String getLongitudeString(	    double		value	)    {	return (getDMSString(value, "EW"));    }        /**     * Convert a fractional hour value to its string representation.     * @param value		A fractional hour.     * @result			The string representation. For example, 6.25     *				yields "06:15"     */    public static String getHMString(    	    double		value    	)    {    	int minute		= (int) Math.round(value * 60.0);    	boolean	negative	= (minute < 0);    	if (negative) {    	    minute		= (-minute);    	}    	int hour		= minute / 60;    	minute			= minute - (hour * 60);	String	result		=		((negative) ? "-" : "")		+ format(hour,   '0', 2) + ':'		+ format(minute, '0', 2);	return (result);    }    /**     * Convert a fractional degree value to its string representation.     * @param value		A fractional degree.     * @param tag		Either "EW" or "NS"     * @result			The string representation. For example, 90.5     *					yields E90¡30'00"     */    public static String getDMSString(	    double		value, 	    String		tag	)    {	StringBuffer text = new StringBuffer(getDMSString(Math.abs(value)));	if (value == 0.0) {	    ;	}	else if (value > 0.0) {	    text.insert(0, tag.charAt(0));	}	else {	    text.insert(0, tag.charAt(1));	}	return (text.toString());    }    /**     * Convert a fractional degree value to its string representation.     * The result is always in the range 0..360.     * @param value		A fractional degree.     * @result			The string representation. For example, 90.5     *					yields 90¡30'00"     */    public static String getDMSString(    		double				value    	)    {    	return (getDMSString(value, false));    }    /**     * Convert a fractional degree value to its string representation.     * If negativeOK is false, the result is always in the range 0..360.     * @param value			A fractional degree.     * @param negativeOK	True to allow negative angles.     * @result			The string representation. For example, 90.5     *					yields 90¡30'00"     */    public static String getDMSString(    		double				value,    		boolean				negativeOK    	)    {	if (negativeOK == false && value < 0.0) {    	    value		+= 360.0;    	}	boolean isNegative	= (value < 0.0);	if (isNegative) {	    value		= (-value);	}	int	degree		= (int) Math.floor(value);	value 			= (value - (double) degree) * 60.0;	int	minute		= (int) Math.floor(value);	int	second		= (int) ((value - (double) minute) * 60.0);	if (isNegative) {	    if (degree > 0) {		degree		= (-degree);	    }	    else if (minute > 0) {		minute		= (-minute);	    }	    else {		second		= (-second);	    }	}	String result		= format(degree, ' ', 4) + degreeSign				+ format(minute, '0', 2) + minuteSign				+ format(second, '0', 2) + secondSign; 	return (result);    }    /*     * Format the year, month, date from a Java date object.     * @param	javaDate	The value to format.     */    public static String getYMDString(	    Date			javaDate	)    {	return (format(javaDate.getYear() + 1900, ' ', 4)		+ ":" + format(javaDate.getMonth() + 1, '0', 2)		+ ":" + format(javaDate.getDate(), '0', 2)	    );    }    /**     * Format an integer value.     * @param	value		The value to format.     * @param	fieldWidth	A fixed-size field width (includes the fraction     *				part, if specified), zero for a variable-length field     *				(i.e., never fill the field).     *				A positive fieldWidth right-justifies the result     *				while a negative fieldWidth left-justifies it.     *				The value is space-filled.     * @result			The string representation.     */    public static String format(	    long		value,	    int			fieldWidth	)    {    	return (format(value, ' ', fieldWidth));    }    /**     * Format an integer value.     * @param	value		The value to format.     * @param	fillChar	The fill character, generally space.     * @param	fieldWidth	A fixed-size field width (includes the fraction     *				part, if specified), zero for a variable-length field     *				(i.e., never fill the field).     *				A positive fieldWidth right-justifies the result     *				while a negative fieldWidth left-justifies it.     * @result			The string representation.     */    public static String format(	    long		value,	    char		fillChar,	    int			fieldWidth	)    {	StringBuffer result = new StringBuffer(Long.toString(value));	if (fieldWidth < 0) {	    fieldWidth = (-fieldWidth);	    while (result.length() < fieldWidth) {		result.append(fillChar);	    }	}	else {	    while (result.length() < fieldWidth) {		result.insert(0, fillChar);	    }	}	return (result.toString());    }    /*     * Format a double-precision number with .xxx precision.     * @param	value		The number to format.     * @result			The string (-123.456)     */    public static String format(	    double	    value	)    {	if (Double.isInfinite(value)	 || Double.isNaN(value)	 || (value > 0 && value > (double) (Long.MAX_VALUE - 1))	 || (value < 0 && value < (double) (Long.MIN_VALUE + 1))) {	    return (new String().valueOf(value));	}	else {	    StringBuffer result = new StringBuffer();	    if (value < 0) {		result.append('-');		value = (-value);	    }	    value		+= 0.0005;	    long integerPart	= (long) value;	    long fractionPart	=		(long) ((value - ((double) integerPart)) * 1000.0);	    result.append(integerPart);	    /* The 1000 here forces leading zeros */	    result.append(1000 + fractionPart);	    result.setCharAt(result.length() - 4, '.');	    while (result.length() < 8) {	    	result.insert(0, ' ');	    }	    return (result.toString());	}    }    /*     * Modulus function that always returns a positive value. For example,     * AstroMath.mod(-3, 24) == 21     */    public static double MOD( 	    double		numerator, 	    double		denomenator 	)    { 	double result		= Math.IEEEremainder(numerator, denomenator); 	if (result < 0.0) 	    result += denomenator; 	return (result);     }    /**     * Debug logging.     */    public static void log(    	    String		what,    	    int			value    	)    {    	System.out.println(format(value, 20) + " " + what);    }        public static void log(    	    String		what,    	    double		value    	)    {	StringBuffer	result	= new StringBuffer(format(value));	while (result.length() < 20) {	    result.insert(0, ' ');	}    	System.out.println(result.toString() + " " + what);    }        /**     * This is used to debug the PixelGrabber class.     */    public static void logPixelGrabberInfo(    	    PixelGrabber	pg    	)    {        System.out.println("PixelGrabber dimensions: "        	+ pg.getWidth() + ", " + pg.getHeight());	System.out.println("PixelGrabber status: " + Integer.toHexString(pg.status()));	if ((pg.getStatus() & ImageObserver.ABORT) != 0) {	    System.out.println("PixelGrabber aborted");	}	if ((pg.getStatus() & ImageObserver.ALLBITS) != 0) {	    System.out.println("PixelGrabber all bits loaded");	}	if ((pg.getStatus() & ImageObserver.ERROR) != 0) {	    System.out.println("PixelGrabber error");	}	if ((pg.getStatus() & ImageObserver.FRAMEBITS) != 0) {	    System.out.println("PixelGrabber frame loaded");	}	if ((pg.getStatus() & ImageObserver.HEIGHT) != 0) {	    System.out.println("PixelGrabber height = " + pg.getHeight());	}	if ((pg.getStatus() & ImageObserver.PROPERTIES) != 0) {	    System.out.println("PixelGrabber properties available");	}	if ((pg.getStatus() & ImageObserver.SOMEBITS) != 0) {	    System.out.println("PixelGrabber some bits available");	}	if ((pg.getStatus() & ImageObserver.WIDTH) != 0) {	    System.out.println("PixelGrabber width = " + pg.getWidth());	}    }}