How to count Sundays between specific two dates in Java

I am struggling to count the number of Sundays on the 1st of the months. like input 1 (test case) 1900 1 1 1902 1 1(year, month, day) the output should be 4. Start date is included.

EXPLANATION:

1 April 1900
1 July 1900
1 September 1901
1 December 1901

However, when I tried THIS:

6 4699 12 12 4710 1 1 1988 3 25 1989 7 13 1924 6 6 1925 6 16 1000000000000 2 2 1000000001000 3 2 1925 6 16 1924 6 6 1905 1 1 1905 1 1

OUTPUT SHOULD BE: 18 2 2 1720 0 1

My CODE OUTPUT IS: 18 2 2 **1714** 0 1

In the test input 6 means 6 test cases. 4699 years 12 month, 12 days, so Dec 12, 4699; 4710 end date and so on.

Could you help me to solve this problem?

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;

public class nineteen {
    
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
        Scanner sc = new Scanner(System.in);
        int loop = sc.nextInt();
        for (int i = 0; i < loop; i++) {
            long year = sc.nextLong(), month = sc.nextLong(), day = sc.nextLong(), yearto = sc.nextLong(),
                    monthto = sc.nextLong(), dayto = sc.nextLong();
            String day1 = String.valueOf(day);
            String month1 = String.valueOf(month);
            String year1 = String.valueOf(year);
            String dayt = String.valueOf(dayto);
            String montht = String.valueOf(monthto);
            String yeart = String.valueOf(yearto);
            String input_date = month1 + "/" + day1 + "/" + year1; // month day year
            String out_date = montht + "/" + dayt + "/" + yeart; // month day year
            long count = 0;

            Date d1 = formatter.parse(input_date);
            Date d2 = formatter.parse(out_date);
            count = saturdayscount(d1, d2);

            // TODO Auto-generated method stub

        }
        sc.close();
    }

    public static long saturdayscount(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(d1);

        Calendar c2 = Calendar.getInstance();
        c2.setTime(d2);

        long sundays = 0;

        while (!c1.after(c2)) {

            if (c1.get(Calendar.DAY_OF_MONTH) != 1) {
                c1.add(Calendar.MONTH, 1);
                c1.set(Calendar.DAY_OF_MONTH, 1);

            }

            if (c1.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {

                sundays++;
            }

            c1.add(Calendar.MONTH, 1);
            c1.set(Calendar.DAY_OF_MONTH, 1);
        }

        System.out.println(sundays);
        return sundays;
    }

}

Answer

I recommend you to do it using the modern date-time API*

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Tests
        System.out.println("Count: " + countSundaysBetween("1900 1 1", "1902 1 1"));
        System.out.println();
        System.out.println("Count: " + countSundaysBetween("1000000000000 2 2", "1000000001000 3 2"));
    }

    static int countSundaysBetween(String strStartDate, String strEndDate) {
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("uuuu M d", Locale.ENGLISH);
        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("d MMMM uuuu", Locale.ENGLISH);
        int count = 0;

        LocalDate start, end;

        System.out.printf("Processing start date: %s and end date: %s%n", strStartDate, strEndDate);

        try {
            start = LocalDate.parse(strStartDate, dtfInput);
        } catch (DateTimeParseException e) {
            System.out.printf("The start date %s can not be processed%n", strStartDate);
            return 0;
        }

        try {
            end = LocalDate.parse(strEndDate, dtfInput);
        } catch (DateTimeParseException e) {
            System.out.printf("The end date %s can not be processed%n", strEndDate);
            return 0;
        }

        for (LocalDate date = start.with(TemporalAdjusters.firstDayOfMonth()); !date.isAfter(end); date = date
                .plusMonths(1)) {
            if (date.getDayOfWeek() == DayOfWeek.SUNDAY) {
                System.out.println(date.format(dtfOutput));
                count++;
            }
        }

        return count;
    }
}

Output:

Processing start date: 1900 1 1 and end date: 1902 1 1
1 April 1900
1 July 1900
1 September 1901
1 December 1901
Count: 4

Processing start date: 1000000000000 2 2 and end date: 1000000001000 3 2
The start date 1000000000000 2 2 can not be processed
Count: 0

ONLINE DEMO

Learn more about the modern date-time API from Trail: Date Time.

Note: I have used LocalDate#parse to keep the demo clean and focussed on the main problem i.e. how to count Sundays between two given dates. If you need to create an instance of LocalDate using year, month and day-of-month as the input, you will use LocalDate#of. And, as you can understand from the documentation, in that case, you will need to replace DateTimeParseException with DateTimeException. The rest of the solution will remain unchanged.


* The java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API. For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Leave a Reply

Your email address will not be published. Required fields are marked *