How to change the date of a Calendar instance in Java?

I have a class DayOfWeek which takes a date from the user and prints the day of the week on that date.

For example the user will enter his date as: (with the format MM DD YYYY)

07 22 2016

and the output should be

FRIDAY

This is my class:

public class DayOfWeek{
    public static void main(String[] args){
        System.out.println("Enter the date (Format: MM DD YYYY) :");
        Scanner sc = new Scanner(System.in);
        String month = sc.next();
        String day = sc.next();
        String year = sc.next();
        int m = Integer.parseInt(month);
        int d = Integer.parseInt(day);
        int y = Integer.parseInt(year);
        Calendar cal = Calendar.getInstance();
        Date date = new Date(y, m, d);
        cal.setTime(date);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
        System.out.println((sdf.format(dayOfWeek)).toUpperCase());
    }
}

However when I enter the date stated above (07 22 2016), I don't get the required output (FRIDAY). Instead the output is the current day of week on my system. I am totally stuck on what the problem is.

Jon Skeet
people
quotationmark

You're currently passing an int to SimpleDateFormat... you should pass the Date value. You don't need a Calendar at all for that:

// BAD CODE: DON'T USE - KEEP READING
import java.text.*;
import java.util.*;

public class DayOfWeek {
    public static void main(String[] args){
        System.out.println("Enter the date (Format: MM DD YYYY) :");
        Scanner sc = new Scanner(System.in);
        String month = sc.next();
        String day = sc.next();
        String year = sc.next();
        int m = Integer.parseInt(month);
        int d = Integer.parseInt(day);
        int y = Integer.parseInt(year);
        // Note the changes here
        Date date = new Date(y - 1900, m - 1, d);
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
        System.out.println(sdf.format(date).toUpperCase());
    }
}

I've put the warning there because you're using a deprecated Date constructor - and it's deprecated for good reasons. Basically, java.util.Date is a terrible API and you should avoid using it if you possibly can. Your original call to new Date(y, m, d) was broken because the first parameter to java.util.Date(int, int, int) represents the year with a 1900 base (so a value of 117 means year 2017) and the second parameter represents the month with a 0 base (so a value of 6 means July). Then there's the implicit time zone conversion, which you really don't want.

You'd be much better off using java.time, and in this case the LocalDate class:

import java.time.*;
import java.time.format.*;
import java.util.*;

public class DayOfWeek {
    public static void main(String[] args){
        System.out.println("Enter the date (Format: MM DD YYYY) :");
        Scanner sc = new Scanner(System.in);
        String month = sc.next();
        String day = sc.next();
        String year = sc.next();
        int m = Integer.parseInt(month);
        int d = Integer.parseInt(day);
        int y = Integer.parseInt(year);
        LocalDate date = LocalDate.of(y, m, d);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE");
        System.out.println(formatter.format(date).toUpperCase());
    }
}

Finally, your approach to parsing the user input isn't ideal either - I'd suggest using a DateTimeFormatter for that, too:

import java.time.*;
import java.time.format.*;

public class DayOfWeek {
    public static void main(String[] args){
        System.out.println("Enter the date (Format: MM DD YYYY) :");
        DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM dd yyyy");
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        LocalDate date = LocalDate.parse(line, parser);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE");
        System.out.println(formatter.format(date).toUpperCase());
    }
}

people

See more on this question at Stackoverflow