Page 2 of 2 FirstFirst 12
Results 21 to 24 of 24
  1. #21
    masijade is offline Senior Member
    Join Date
    Jun 2008
    Posts
    2,571
    Rep Power
    9

    Default

    And that is not the way to use a Calendar to get the difference. Doing it that way, you just as well use Date and a SimpleDateFormat with the timezone set.

    Doing it that way, you will easily be a day off, or more, when counting years, months, etc, and not because of timezones.

    Take measuring the difference from Feb 1 2008 to Feb 1 2009. Doing it the way you are you get 1 year and 1 day, since 1970 was not a leap year and 2008 was. You need to measure from the start date to the end date, using the actual dates, or you can expect problems.
    Last edited by masijade; 02-18-2009 at 09:42 PM.

  2. #22
    masijade is offline Senior Member
    Join Date
    Jun 2008
    Posts
    2,571
    Rep Power
    9

    Default

    Here, go ahead and pick holes in it, but, aside from being "long-winded", and slower than other methods (although still only a few milliseconds, at most, even on the the test dates that are 1000 years apart, so it is still more than fast enough for 99.999999999% of all cases where it might be needed) it is guaranteed to be correct (as far as the GregorianCalendar itself, is correct).

    Java Code:
    package datediffs;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import static java.util.Calendar.YEAR;
    import static java.util.Calendar.DAY_OF_YEAR;
    import static java.util.Calendar.MONTH;
    import static java.util.Calendar.DAY_OF_MONTH;
    import java.util.Date;
    import java.util.GregorianCalendar;
    
    public class Main {
    
        private class DateDiff {
            public int years;
            public int months;
            public int days;
            public int hours;
            public int mins;
            public int secs;
            public int millis;
    
            @Override
            public String toString() {
                StringBuilder sb = new StringBuilder();
                if (years > 0) sb.append("Years:  ").append(years).append("  ");
                if (months > 0) sb.append("Months:  ").append(months).append("  ");
                if (days > 0) sb.append("Days:  ").append(days).append("  ");
                if (hours > 0) sb.append("Hours:  ").append(hours).append("  ");
                if (mins > 0) sb.append("Minutes:  ").append(mins).append("  ");
                if (secs > 0) sb.append("Seconds:  ").append(secs).append("  ");
                if (millis > 0) sb.append("Milliseconds:  ").append(millis).append("  ");
                if (sb.length() > 0) sb.delete(sb.length() -2, sb.length());
                return sb.toString();
            }
        }
    
        private DateDiff getDifference(Date startDate, Date endDate) {
            if (startDate.after(endDate)) return null;
    
            DateDiff diff = new DateDiff();
            Calendar start = new GregorianCalendar();
            Calendar end = new GregorianCalendar();
    
            start.setTime(startDate);
            end.setTime(endDate);
    
            diff.years = end.get(YEAR) - start.get(YEAR);
            start.add(YEAR, diff.years);
            if (start.after(end)) {
                start.add(YEAR, -1);
                diff.years--;
            }
    
            do {
                diff.months++;
                start.add(MONTH, 1);
            } while (start.before(end));
            diff.months--;
            start.add(MONTH, -1);
    
            do {
                diff.days++;
                start.add(DAY_OF_MONTH, 1);
            } while (start.before(end));
            diff.days--;
            start.add(DAY_OF_MONTH, -1);
    
            long rest = end.getTimeInMillis() - start.getTimeInMillis();
            diff.hours = (int) rest/3600000;
            rest %= 3600000;
            diff.mins = (int) rest/60000;
            rest %= 60000;
            diff.secs = (int) rest/1000;
            diff.millis = (int) rest % 1000;
    
            return diff;
        }
    
        private DateDiff getDifferenceInDays(Date startDate, Date endDate) {
            if (startDate.after(endDate)) return null;
    
            DateDiff diff = new DateDiff();
            Calendar start = new GregorianCalendar();
            Calendar end = new GregorianCalendar();
    
            start.setTime(startDate);
            end.setTime(endDate);
    
            if (start.get(YEAR) < end.get(YEAR)) {
                // Adjust for the first of the next year
                diff.days = start.getActualMaximum(DAY_OF_YEAR) - start.get(DAY_OF_YEAR) + 1;
                start.add(DAY_OF_YEAR, diff.days);
            }
    
            while (start.get(YEAR) < end.get(YEAR)) {
                diff.days += start.getActualMaximum(DAY_OF_YEAR);
                start.add(YEAR, 1);
            }
            if (start.after(end)) {
                // only need to remove one day
                diff.days -= 1;
                start.add(DAY_OF_MONTH, -1);
            }
    
            while (start.get(MONTH) < end.get(MONTH)) {
                diff.days += start.getActualMaximum(DAY_OF_MONTH);
                start.add(MONTH, 1);
            }
            if (start.after(end)) {
                start.add(MONTH, -1);
                diff.days -= start.getActualMaximum(DAY_OF_MONTH);
            }
    
            do {
                diff.days++;
                start.add(DAY_OF_MONTH, 1);
            } while (start.before(end));
            diff.days--;
            start.add(DAY_OF_MONTH, -1);
    
            long rest = end.getTimeInMillis() - start.getTimeInMillis();
            diff.hours = (int) rest/3600000;
            rest %= 3600000;
            diff.mins = (int) rest/60000;
            rest %= 60000;
            diff.secs = (int) rest/1000;
            diff.millis = (int) rest % 1000;
    
            return diff;
        }
    
        public static void main(String[] args) throws ParseException {
            Main main = new Main();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
            Date start = sdf.parse("2008/2/1 12:00:00.000");
            Date end = sdf.parse("2009/2/1 13:00:00.000");
            System.out.println(main.getDifference(start, end));
            System.out.println(main.getDifferenceInDays(start, end));
            System.out.println();
            System.out.println();
            System.out.println();
            start = sdf.parse("2008/2/1 12:00:00.000");
            end = sdf.parse("2009/2/1 11:00:00.000");
            System.out.println(main.getDifference(start, end));
            System.out.println(main.getDifferenceInDays(start, end));
            System.out.println();
            System.out.println();
            System.out.println();
            start = sdf.parse("1008/2/1 12:00:00.000");
            end = sdf.parse("2009/2/1 11:00:00.000");
            System.out.println(main.getDifference(start, end));
            System.out.println(main.getDifferenceInDays(start, end));
        }
    }
    Last edited by masijade; 02-19-2009 at 09:26 AM.

  3. #23
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Doing it that way, you will easily be a day off, or more, when counting years, months, etc, and not because of timezones.
    Masijade is right.
    Last edited by Steve11235; 02-19-2009 at 03:43 AM. Reason: ..........

  4. #24
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default Corrected code

    Sorry for my earlier mistake. Here is an approach using calendars that handles exceptional conditions.

    Note that leap days between dates are only accounted for when the start or end date is in February of a leap year. That is the correct solution, since years, months, days type descriptions are inherently imprecise.
    Java Code:
    package test;
    
    import static java.util.Calendar.YEAR;
    import static java.util.Calendar.MONTH;
    import static java.util.Calendar.DATE;
    import java.util.Date;
    import java.util.GregorianCalendar;
    import java.util.TimeZone;
    
    /**
     * DateDifferenceTest
     */
    public class DateDifferenceTest {
    	/**
    	 * Determine the difference between two Date's in years, months, and days
    	 * <p>
    	 * <b>Note:</b>
    	 * 
    	 * @param pDate1
    	 * @param pDate2
    	 * @return a String containing the information
    	 */
    	public static String dateDifference(final Date pDate1,
    	    final Date pDate2) {
    		final String diffString;
    		final int startMonth, startDay;
    		int years = 0, months = 0, days = 0;
    		boolean isNegative = false;
    		GregorianCalendar gc1 = null, gc2 = null;
    		gc1 = new GregorianCalendar();
    		gc1.setTimeZone(TimeZone.getTimeZone("GMT"));
    		gc2 = new GregorianCalendar();
    		gc2.setTimeZone(TimeZone.getTimeZone("GMT"));
    		/*
    		 * Handle pDate2 after pDate1
    		 */
    		if (!pDate1.before(pDate2)) {
    			gc1.setTimeInMillis(pDate1.getTime());
    			gc2.setTimeInMillis(pDate2.getTime());
    		}
    		else {
    			isNegative = true;
    			gc1.setTimeInMillis(pDate2.getTime());
    			gc2.setTimeInMillis(pDate1.getTime());
    		}
    		/*
    		 * Special case: same year and month
    		 */
    		if (gc1.get(YEAR) == gc2.get(YEAR)
    		    && gc1.get(MONTH) == gc2.get(MONTH)) {
    			days = gc1.get(DATE)
    			    - gc2.get(DATE);
    		}
    		/*
    		 * Normal case
    		 */
    		else {
    			/*
    			 * Capture the start day. This is necessary because incrementing the month moves the day back
    			 * to the last day of that month.
    			 */
    			startDay = gc2.get(DATE);
    			/*
    			 * If the day of the end month is less than the day of the start month, increment the start 
    			 * date until the beginning of the next month, count the days
    			 */
    			if (gc1.get(DATE) < gc2.get(DATE)) {
    				startMonth = gc2.get(MONTH);
    				while (startMonth == gc2.get(MONTH)) {
    					days++;
    					gc2.add(DATE,
    					    1);
    				}
    			}
    			/*
    			 * Handle years
    			 */
    			do {
    				years++;
    				gc2.add(YEAR,
    				    1);
    			}
    			while (!gc1.before(gc2));
    			years--;
    			gc2.add(YEAR,
    			    -1);
    			/*
    			 * Handle months
    			 */
    			do {
    				months++;
    				gc2.add(MONTH,
    				    1);
    			}
    			while (!gc1.before(gc2));
    			months--;
    			gc2.add(MONTH,
    			    -1);
    			/*
    			 * Handle days
    			 */
    			if (gc1.get(DATE) < startDay) {
    				days += gc1.get(DATE) - 1;
    			}
    			else {
    				days = gc1.get(DATE)
    				    - startDay;
    			}
    		}
    		/*
    		 * Format response
    		 */
    		diffString = (isNegative
    		    ? "2nd before 1st; "
    		    : "")
    		    + "Years: "
    		    + years
    		    + "; Months: "
    		    + months
    		    + "; Days: "
    		    + days;
    		return diffString;
    	}
    
    	/**
    	 * Entry point for test
    	 * 
    	 * @param args
    	 */
    	public static void main(final String[] args) {
    		final Date date1, date2;
    		/*
    		 * IMPORTANT: Months are zero based: 0 = Jan, 1 = Feb, etc.
    		 */
    		date1 = (new GregorianCalendar(2008,
    		    1,
    		    1)).getTime();
    		date2 = (new GregorianCalendar(2008,
    		    1,
    		    1)).getTime();
    		System.out.println(dateDifference(date1,
    		    date2));
    	}
    }

Page 2 of 2 FirstFirst 12

Similar Threads

  1. How to Compare two Dates
    By Java Tip in forum java.util
    Replies: 1
    Last Post: 06-24-2008, 07:05 AM
  2. No fo days between two dates
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 01-28-2008, 09:06 AM
  3. Comparing dates
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 01-28-2008, 09:02 AM
  4. Inbetween Dates
    By Rageagainst20 in forum New To Java
    Replies: 4
    Last Post: 12-19-2007, 05:24 AM
  5. help with dates and time
    By osval in forum New To Java
    Replies: 3
    Last Post: 12-12-2007, 12:41 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •