2

What is wrong with the below code? It gives wrong day for any date of the year.

import java.util.Scanner;
import java.util.Calendar;
public class Solution {
    public static String getDay(String d, String m, String y) {

        String[] days = {"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"};
        Calendar c = Calendar.getInstance();
        c.set(Integer.parseInt(y), Integer.parseInt(m), Integer.parseInt(d)); 
        return days[c.get(Calendar.DAY_OF_WEEK) - 1]; 
    }
public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String m = in.next();
        String d = in.next();
        String y = in.next();

        System.out.println(getDay(d, m, y));
    }
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
user3050866
  • 33
  • 1
  • 5
  • 2
    Provided 3, 5, 2018, and got THURSDAY back, which is right. Can you provide example of failed scenarios? – clement May 03 '18 at 00:48
  • I tried 08 05 2015 (august 5, 2015) and the result was SATURDAY instead of Wednesday. – user3050866 May 04 '18 at 01:33
  • @clement The order in the code is month day-of-month year. March 5 2018 was a Monday, so when you got THURSDAY it was incorrect. – Ole V.V. May 04 '18 at 11:29
  • 1
    FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque May 05 '18 at 04:38
  • @OleV.V. damn american date format, we use dd/mm/yyyy here in Australia (same in France ;) ), 3rd of May 2018 is indeed a Thursday :) – clement May 08 '18 at 23:10

2 Answers2

11

See the documentation for the Calendar class: https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#set-int-int-int-

The value for month is 0-indexed, so if you provide 3 as the month value, it is interpreted as "April".

VeeArr
  • 6,039
  • 3
  • 24
  • 45
  • Thank you very much. I correct the MONTH by deducting one from input value, and it worked. – user3050866 May 04 '18 at 01:36
  • Thank you so much for this! It's a bit strange that month is zero indexed because calendars obviously don't start at 0 and end at 11. I spent a lot of time trying to debug my code :/ – Narin Dhatwalia Apr 02 '22 at 00:33
3

It’s easiest to have the Scanner read int values rather than strings:

    int m = in.nextInt();
    int d = in.nextInt();
    int y = in.nextInt();

    System.out.println(LocalDate.of(y, m, d).getDayOfWeek());

When I feed 5 4 2018 (today’s date), I get FRIDAY, which is correct.

If you must use strings:

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("M/d/u");

    String m = in.next();
    String d = in.next();
    String y = in.next();

    System.out.println(LocalDate.parse(m + '/' + d + '/' + y, dateFormatter).getDayOfWeek());

The Calendar class you were using is long outdated, poorly designed and sometimes cumbersome to work with. Instead I recommend java.time, the modern Java date and time API. It is so much nicer. For one little thing it numbers the months of the year in the same way humans do.

Also the names of the days of the week are built-in, so don’t reinvent the wheel. Your strings coincide with the names of the values of the DayOfWeek enum in java.time, so just print those to get the strings you want. If you don’t want all uppercase or you want the day names in another language, use DayOfWeek.getDisplayName or a DateTimeFormatter.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161