I have to calculate the number of days between two dates the hard way.

I know there is already a way to do this with an existing package and such but I have to do it within a single method "daysBetween" without altering any other part of the code.

The method must be able to return a positive/negative value depending what start/end dates it is given and also take into account leap years and such.

What I have right now in the "daysBetween" method starting on line 258 DOES NOT WORK and can be completely scrapped if necessary.

(I know its long, i'm sorry but i didn't know what you might need)

The "daysBetween" method starts on line 258

import java.util.Calendar;
import java.util.GregorianCalendar;

public class Date implements Proj1Constants {

	private static final int[] DAYS = { 0, 31, 29, 31, 30, 31, 30, 31, 31,
			30, 31, 30, 31 };
    private static final int LEAP_YEAR = 366;
    private static final int NON_LEAP_YEAR = 365;

	private final int month; // month (between 1 and 12)
	private final int day; // day (between 1 and DAYS[month])
	private final int year; // year

    /**
	 * Constructor: default; returns today's date
	 */
    // creates today's date as the date; obtains it from Java library
    public Date() {
        GregorianCalendar c = new GregorianCalendar();
        month = c.get(Calendar.MONTH)+1; //our month starts from 1
        day = c.get(Calendar.DAY_OF_MONTH);
        year = c.get(Calendar.YEAR);
    }

	/**
	 * Constructor: Does bounds-checking to ensure object represents a valid
	 * date
	 *
	 * @param m represents the month between 1 and 12
	 * @param d represents the date between 1 and the corresponding number
	 * from array DAYS
	 * @param y represents the year
	 * @exception RuntimeException
	 * if the date is invalid
	 */
	public Date(int m, int d, int y) {
		if (!isValid(m, d, y))
			throw new RuntimeException("Invalid date");
		month = m;
		day = d;
		year = y;
	}

	/**
	 * Constructor: Does bounds-checking to ensure string represents a valid
	 * date
	 *
	 * @param sDate represents a date given in format mm-dd-yyyy
	 * @exception RuntimeException if the date is invalid
	 */
	public Date(String sDate) {
		int m, d, y;
		String[] chopDate = sDate.split("-");
		m = Integer.parseInt(chopDate[ZEROI]);
		d = Integer.parseInt(chopDate[ONEI]);
		y = Integer.parseInt(chopDate[TWOI]);
		if (!isValid(m, d, y))
			throw new RuntimeException("Invalid date");
		month = m;
		day = d;
		year = y;
	}

	/**
	 * constructor: creates a date with a given year; fills in valid month and day;
     * as december 31st.
	 *
	 * @param y represents a date given in year as integer
	 */
	public Date(int y) {

		month = 12;
		day = DAYS[12];
		year = y;
	}

	/**
	 * create a date with a given month and year; fills in valid day;
	 *
	 * @param m represents the month between 1 and 12
	 * @param y represents the year
	 * @exception RuntimeException if the date is invalid
	 */
	public Date(int m, int y) {

		if (!isValid(m, DAYS[m], y))
			throw new RuntimeException("Invalid date; correct input");
		month = m;
		day = DAYS[m];
		year = y;
	}

	/**
	 * Is the given date valid?
	 *
	 * @param month, day, and year
	 * @return false if month exceeds 12 or is less than 1
	 * @return false if day exceeds the corresponding days for a month from
	 * array DAYS
	 * @return false if the year is not a leap year and has 29 days
	 */
	private static boolean isValid(int m, int d, int y) {
		if (m < 1 || m > 12)
			return false;
		if (d < 1 || d > DAYS[m])
			return false;
		if (m == 2 && d == 29 && !isLeapYear(y))
			return false;
		return true;
	}

	/**
	 * is y a leap year?
	 *
	 * @param y
	 * represents the year specified
	 * @return true if year divisible by 400
	 * @return false if year divisible by 100 and not by 400
	 */
	private static boolean isLeapYear(int y) {
		if (y % 400 == 0)
			return true;
		if (y % 100 == 0)
			return false;
		return (y % 4 == 0);
	}

    /**
	 * is (m, y) a leap month?
	 *
     * @param m represents the month specified
	 * @param y represents the year specified
	 * @return true if it is a leap month
	 * @return false otherwise
	 */
	private static boolean isLeapMonth(int m, int y) {
		if (isLeapYear(y)) return ((m == 2) ? true : false);
		return false;
	}

	// return the next Date
	/**
	 * adds a day and returns a new Date object
	 *
	 * @return returns a new Date object adding a day
	 */
	public Date next() {
		if (isValid(month, day + 1, year))
			return new Date(month, day + 1, year);
		else if (isValid(month + 1, 1, year))
			return new Date(month + 1, 1, year);
		else
			return new Date(1, 1, year + 1);
	}

	// is this Date after b?
	/**
	 * compares two Date objects
	 *
	 * @param b Date object
	 * @return true if this Date is after Date b
	 */
	public boolean isAfter(Date b) {
		return compareTo(b) > 0;
	}

	// is this Date a before b?
	/**
	 * compares two date objects
	 *
	 * @param b Date object
	 * @return true if this Date is before Date b
	 */
	public boolean isBefore(Date b) {
		return compareTo(b) < 0;
	}

	

	// comparison function between two dates
	/**
	 * compares two Date objects
	 *
	 * @param b Date object
	 * @return 0 if this Date is the same as Date b <br>
	 * negative integer if this Date is earlier than Date b <br>
	 * positive integer if this Date is after Date b
	 */
	public int compareTo(Date b) {
		if (year != b.year)
			return year - b.year;
		if (month != b.month)
			return month - b.month;
		return day - b.day;
	}

	
	// advance date by number of months
	/**
	 * advances the date by m months
	 *
	 * @param m represents the months to advance
	 * @return new Date object (as the original object is immutable)
	 */
	public Date addMonths(int m) {

		
		int newMonth, newYear, newDay;
		
		newMonth = month + m;
		
		if (newMonth > 12){
			newMonth = (month + m)%12;
		}
		
		newYear = (int)((month + m)/12);
		
		if(!isValid(newMonth, day,year + newYear)){
			if(newMonth == 2){
				if(isLeapMonth(newMonth, year + newYear)){
					newDay = DAYS[newMonth];
				}
				else{
					newDay = DAYS[newMonth]-1;
				}
			}
			else
				newDay = DAYS[newMonth];
			return new Date(newMonth,newDay,year + newYear);
		}
		else
			return new Date(newMonth, day, year + newYear);
		
	}

	// subtracts two dates to return the difference in full months
	/**
	 * @param endDate represents the second date
	 * @return int months - the difference between the two dates
	 */
	public int monthsBetween(Date endDate) {
		//complete this method
		
		return ((endDate.month - month)+(endDate.year - year)*12);
	}

	
       // returns the number of days between two date
	 /**
     	   * @ param endDate is the second date
	   * @ return the number of days between two dates
     	   * - 1 if start date is after the end date
     	   * 0 if start date is equal to the end date
     	   * + #days if the start date is before end date
	   *
	   */
	public int daysBetween(Date endDate) {
		
		int currentYear=year, currentMonth=month, dayCount=0, i;
		
		
		if(isAfter(endDate)){
			if(!isLeapYear(year) && month == 2){
				for (i=day;i<=DAYS[currentMonth]-1;i++){
					dayCount += 1;
				}
			}
			else{
				for (i=day;i<=DAYS[currentMonth];i++){
					dayCount +=1;
				}
			}
			System.out.println("from ["+month+"-"+day+"-"+year+"] to next month is "+dayCount);
			
			while(endDate.year != year && endDate.month != month ){
				for (i=0;i<DAYS[currentMonth];i++){
					dayCount += 1;
				}
				currentMonth += 1;
				
				if(currentMonth > 12){
					currentYear += 1;
					currentMonth = 1;
					System.out.println("Advancing to month "+ currentMonth+"-"+currentYear);
				}
			}
		}
		else
			dayCount = 123; // I did this so that I could run the program and avoid (-) values for now
		return dayCount;
				
	}

	// return a string representation of this date
	/**
	 * replaces the default toString of Object class
	 */
	public String toString() {
		return "[" + month + "-" + day + "-" + year + "]";
	}

	// sample client for testing
	/**
	 * Code for testing the Date class
	 *
	 * @param args Array of String arguments
	 */

	public static void main(String[] args) {
		Date today = new Date(2, 26, 2012);
		System.out.println("Input date is " + today);
		System.out.println("Printing the next 10 days after " + today);
		for (int i = 0; i < 10; i++) {
			today = today.next();
			System.out.println(today);
		}
		Date expiry = new Date(2011);
		System.out.println("testing year 2011 as input:" + expiry);

		Date todayDate = new Date(9,6,2011);
		System.out.println("todays date: " + todayDate);
		System.out.println("current month:" + todayDate.month);

		// testing isValidMonth function
		Date start = new Date("08-01-2010");
		Date end1 = new Date("09-01-2010");
		
		Date lease = new Date("1-01-2012");
		Date expiry1 = new Date("12-31-2012");

		// testing daysBetween
		System.out
				.println("\nTESTING daysBetween method\n------------------------------");
		int count = lease.daysBetween(expiry);
		System.out.println("Days between " + lease + " and " + expiry + "is: "
				+ count);
        count = new Date("1-01-2011").daysBetween(new Date("12-31-2011"));
		System.out.println("Days between [1-01-2011]  and [12-31-2011]" + "is: "
				+ count);
		count = lease.daysBetween(expiry1);
		System.out.println("Days between " + lease + " and " + expiry1 + "is: "
				+ count);
		Date testDate = new Date("12-31-2013");
		count = lease.daysBetween(testDate);
		System.out.println("Days between " + lease + " and [12-31-2013] "
				+ "is: " + count);
		count = lease.daysBetween(lease);
		System.out.println("Days between " + lease + " and " + lease + "is: "
				+ count);
        count = lease.daysBetween(new Date("1-10-2012"));
		System.out.println("Days between " + lease + " and [1-10-2012" + "is: "
				+ count);
        
		count = testDate.daysBetween(lease);
		System.out.println("Days between " + testDate + " and " + lease + "is: "
				+ count);

		// testing isBefore
		System.out
				.println("\nTESTING isBefore method\n------------------------------");
		boolean isBefore = today.isBefore(today.next());
		System.out.println(today + "is before " + today.next() + ": "
				+ isBefore);
		isBefore = today.next().isBefore(today);
		System.out.println(today.next() + "is before " + today + ": "
				+ isBefore);
		isBefore = today.isBefore(today);
		System.out.println(today + "is before " + today + ": " + isBefore);
        isBefore = today.isBefore(today.addMonths(12));
		System.out.println(today + "is before " + today.addMonths(12) + ": " + isBefore);

		// testing addMonths
		System.out
				.println("\nTESTING addMonths method\n------------------------------");
		today = new Date("1-31-2011");
		Date newDate = today.addMonths(1);
		System.out
				.println("adding 1 months to " + today + " gives: " + newDate);
		newDate = today.addMonths(13);
		System.out.println("adding 13 months to " + today + " gives: "
				+ newDate);
		today = new Date("3-31-2010");
		newDate = today.addMonths(15);
		System.out.println("adding 15 months to " + today + " gives: "
				+ newDate);
		newDate = today.addMonths(23);
		System.out.println("adding 23 months to " + today + " gives: "
				+ newDate);
		newDate = today.addMonths(49);
		System.out.println("adding 49 months to " + today + " gives: "
				+ newDate);
		newDate = today.addMonths(0);
		System.out
				.println("adding 0 months to " + today + " gives: " + newDate);
		
		// testing monthsBetween
		System.out
				.println("\nTESTING monthsBetween method\n------------------------------");
		int monthDiff = today.monthsBetween(today.addMonths(1));
		System.out.println("months between " + today + " and " + today.addMonths(1)
				+ ": " + monthDiff);
		monthDiff = today.next().monthsBetween(today);
		System.out.println("months between " + today.next() + " and " + today
				+ ": " + monthDiff);
		today = new Date("09-30-2011");
		Date endDate = new Date("2-29-2012");
		monthDiff = today.monthsBetween(endDate);
		System.out.println("months between " + today + " and " + endDate + ": "
				+ monthDiff);
		today = new Date();
		Date endDate1 = new Date("12-04-2011");
		monthDiff = today.monthsBetween(endDate1);
		System.out.println("months between " + today + " and " + endDate1
				+ ": " + monthDiff);
		today = new Date();
		Date endDate2 = new Date("12-22-2010");
		monthDiff = today.monthsBetween(endDate2);
		System.out.println("months between " + today + " and " + endDate2
				+ ": " + monthDiff);
		
		// following should generate exception as date is invalid!
		// today = new Date(13, 13, 2010);

		// expiry = new Date("2-29-2009");
        // newDate = today.addMonths(-11);

	}

}

Recommended Answers

All 3 Replies

The Dates topic is already posted by previous folks and it is answered.
Just search in daniweb.

Doing the calculation like that is horribly complex. It works out much easier to write a method that converts a date to int days since 1/1/1900, then you can just subtract one from the other.

The Dates topic is already posted by previous folks and it is answered.
Just search in daniweb.

I did search first and found absolutely nothing that didn't use some sort of built in method or algorithm to handle dates in any language let alone Java.

Doing the calculation like that is horribly complex

Your absolutely right, I did however get it working provided the end date is AFTER the start date. i.e. it will only return a foreword moving count. If the end date is before the start date, it just returns a "-1"

After I got it working this way I was told it was good enough and it would do just fine, so I don't plan on making negative counts work.

Here is the method I devised, marvel in it's ridiculusness....

public int daysBetween(Date endDate) {
		
		int currentYear=year, currentMonth=month, dayCount=0, i, currentDay = day;
		int seperateCount=0;		
		
		if(isBefore(endDate)){
			if(currentMonth == 2 && !isLeapMonth(currentMonth,currentYear)){
				for (i=day;i<=DAYS[2]-1;i++){
					dayCount += 1;
				}

				currentMonth +=1;
				currentDay = 1;
			}
			else{
				for (i=day;i<=DAYS[currentMonth];i++){
					dayCount +=1;
				}
				currentMonth +=1;
				currentDay +=1;
			}
			
			if(endDate.month-month==0 && endDate.year-year==0)
				return dayCount;
			
			while(endDate.year != currentYear || endDate.month != currentMonth){
				if (currentMonth == 2 && !isLeapMonth(currentMonth,currentYear)){
					for (i=0;i<DAYS[currentMonth]-1;i++){
						dayCount += 1;
						currentDay = i+1;
						seperateCount +=1;
					}
				}
				else{
					for (i=0;i<DAYS[currentMonth];i++){
						dayCount += 1;
						currentDay = i+1;
						seperateCount +=1;
					}
				}
			
				currentMonth += 1;
				if (seperateCount > 50 || dayCount > 1095)  //loop breaker, not used
					return 5;
				seperateCount =0;
				if(currentMonth > 12){
					currentYear += 1;
					currentMonth = 1;

				}
			}
			dayCount += (endDate.day);
		}
		else
			dayCount = -1;
		
		return dayCount;
	}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.