1

I am working on a problem set, and trying to build a class that returns dates. For this question, I need to return the day of week e.g. "Monday", "Tuesday" for a given date. I searched on Stack Overflow, and decided to try using java.time:

package Chapter1.Section2;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.Locale;

public class exercise_1_2_12 {
    private int day;
    private int month;
    private int year;

    public exercise_1_2_12(int month, int day, int year){
        if (!isDateValid(month, day, year)){
            throw new IllegalArgumentException("Invalid Date!");
        }
        this.month = month;
        this.day = day;
        this.year = year;
    }

    public int day(){
        return day;
    }

    public int month(){
        return month;
    }

    public int year(){
        return year;
    }

    public String toString(){
        //return month() + "-" + day() + "-" + year();
        return  year + "/" + String.format("%02d", month) + "/" + 
        String.format("%02d", day);
    }

    public boolean isDateValid(int month, int day, int year) {
        int[] dayInEachMonthLeapYr = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int[] dayInEachMonthNonLeapYr = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        boolean valid = true;


        if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))) {
            if (year < 1 || month < 1 || month > 12 || day < 1 || day > dayInEachMonthLeapYr[month - 1]) {
                valid = false;
            }
        } else {
            if (year < 1 || month < 1 || month > 12 || day < 1 || day > dayInEachMonthNonLeapYr[month - 1]) {
                valid = false;
            }
        }
        return valid;
    }

    public String dayOfWeekName(){
        DateTimeFormatter format = DateTimeFormatter.ofPattern("mm/dd/yyyy");
        String input = this.toString();
        LocalDate date = LocalDate.parse(input, format);
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        String result = dayOfWeek.getDisplayName(TextStyle.FULL, Locale.US);
        return result;
    }

    public static void main(String[] args){

        StdOut.print("Enter month: ");
        int month = StdIn.readInt();
        StdOut.print("Enter day: ");
        int day = StdIn.readInt();
        StdOut.print("Enter year: ");
        int year = StdIn.readInt();
        exercise_1_2_12 smartDate = new exercise_1_2_12(month,day,year);
        StdOut.println(smartDate);
        smartDate.dayOfWeekName();
    }
}

The problems might be in the instance method dayOfWeekName(), I tried to parse the object this. to String format, then store it in LocalDate date, then return the name of the weekday. I tested it, the error message is the following:

Enter month: 4
Enter day: 1
Enter year: 2018
2018/04/01
Exception in thread "main" java.time.format.DateTimeParseException: Text '2018/04/01' could not be parsed at index 2
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDate.parse(LocalDate.java:400)
at Chapter1.Section2.exercise_1_2_12.dayOfWeekName(exercise_1_2_12.java:64)
at Chapter1.Section2.exercise_1_2_12.main(exercise_1_2_12.java:85)

Process finished with exit code 1

I am not quite sure how to solve this issue.

1
  • By the way, you could replace your isDateValid method by simply trapping for DateTimeException while calling LocalDate.of: try{ LocalDate ld = LocalDate.of( y , m , d ) ; } catch ( DateTimeException e ) { … handle invalid input … } Commented Mar 31, 2018 at 23:38

2 Answers 2

2

Have a look at your date pattern:

DateTimeFormatter format = DateTimeFormatter.ofPattern("mm/dd/yyyy");

The date:

'2018/04/01'

Naturally does not match it.

Either enter a date in that pattern, like:

'04/01/2018'

Or change the pattern:

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd");

Important: As precisely pointed by @Ivar in comments, also note that the pattern for months is uppercase M. When you you use mm, it matches minutes instead.

Sign up to request clarification or add additional context in comments.

2 Comments

@Ivar, you are absolutely right. Usually it takes me a run to spot those patterns. Good eye! Thank you!
Thanks a lot! Should have used "yyyy/MM/dd" format instead. Indeed, mm denotes to minute instead of month!
-1

Use this formatter:

DateTimeFormatter.ofPattern("MM/dd/yyyy")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.