/* -----BEGIN PGP SIGNED MESSAGE----- */ import java.util.*; import java.text.*; public class DateDiff { // set some constants that allow pretty accurate estimates over // about 2,000 years before or after the present. These are // slight overestimates since that's what we want (and need!) private static final double DAY_MILLIS = 1000*60*60 * 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; protected int getDateDiff( int calUnit, Date d1, Date d2 ) { // swap if d1 later than d2 boolean neg = false; if( d1.after(d2) ) { Date temp = d1; d1 = d2; d2 = temp; neg = true; } // estimate the diff. d1 is now guaranteed <= d2 int estimate = (int)getEstDiff( calUnit, d1, d2 ); // convert the Dates to GregorianCalendars GregorianCalendar c1 = new GregorianCalendar(); c1.setTime(d1); GregorianCalendar c2 = new GregorianCalendar(); c2.setTime(d2); // add 2 units less than the estimate to 1st date, // then serially add units till we exceed 2nd date c1.add( calUnit, (int)estimate - 2 ); for( int i=estimate-1; ; i++ ) { c1.add( calUnit, 1 ); if( c1.after(c2) ) return neg ? 1-i : i-1; } } private int getEstDiff( int calUnit, Date d1, Date d2 ) { long diff = d2.getTime() - d1.getTime(); switch (calUnit) { 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) (diff / DAY_MILLIS + .5); case Calendar.WEEK_OF_YEAR : return (int) (diff / WEEK_MILLIS + .5); case Calendar.MONTH : return (int) (diff / MONTH_MILLIS + .5); case Calendar.YEAR : return (int) (diff / YEAR_MILLIS + .5); default: return 0; } /* endswitch */ } // some test code... public static void main(String[] args) { DateDiff dd = new DateDiff(); Date then = null, now = null; DateFormat df = DateFormat.getInstance(); // DecimalFormat ddf = (DecimalFormat)NumberFormat.getInstance(); // ddf.setMaximumFractionDigits(0); // Use this instead of DecimalFormat if you have it... // If not, you can get it at: // http://pws.prserv.net/ad/programs/Programs.html#PaddedDecimalFormat PaddedDecimalFormat ddf = PaddedDecimalFormat.getNumberInstance(0, Locale.getDefault()); df.setTimeZone( TimeZone.getDefault() ); if (args.length < 2) { String pattern = ((SimpleDateFormat)df).toLocalizedPattern(); System.out.println("Usage: Enter two dates in this format: " + pattern.substring( 0, pattern.indexOf(' ')) ); System.exit(0); } else { try { then = df.parse( args[0] + " 12:00 PM" ); now = df.parse( args[1] + " 12:00 PM" ); } catch ( ParseException e ) { System.out.println("Couldn't parse date: " + e ); System.exit(1); } /* endcatch */ } /* endif */ // now we have two Date objects. get real & estimated diff int diff = dd.getDateDiff( Calendar.DATE, then, now ); System.out.println("Interval in days: " + ddf.format( diff, 20 ) ); // + ddf.format( diff ) ); diff = dd.getDateDiff( Calendar.WEEK_OF_YEAR, then, now ); System.out.println("Interval in weeks: " + ddf.format( diff, 20 ) ); // + ddf.format( diff ) ); diff = dd.getDateDiff( Calendar.MONTH, then, now ); System.out.println("Interval in months: " + ddf.format( diff, 20 ) ); // + ddf.format( diff ) ); diff = dd.getDateDiff( Calendar.YEAR, then, now ); System.out.println("Interval in years: " + ddf.format( diff, 20 ) ); // + ddf.format( diff ) ); } } /* Example output of test code: [F:\test]java DateDiff 5/29/1066 5/29/1999 Interval in days: 340,765 Interval in weeks: 48,680 Interval in months: 11,196 Interval in years: 933 -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQCVAwUBN83eDmbsFmrW0oYFAQHwGQQAs/ulTqgeNdTjVISm6Mb8sa7G3Dn1axUv od19UC3qAKGHC0Rko8HrsozlB7GdZNADVrX0N2C5N4GquYc2lAxVwdKE/g0CYtJ5 Iz8qyLMYgZ3NvZbQgVDQY+qPNoQVSLIkCBBuSVZeD+bS1OeQykYhoxgcRnQdIGOp C69BKm2vRsc= =w561 -----END PGP SIGNATURE----- */