⌛⌛ Dates

Place your code into a file named Dates.java in folder Round5/dates in your Git repository.

Implement a class Dates that can be used for computing differences between dates. The class must have the following properties:

  • An inner static class DateDiff that stores a start date an end date as strings and their difference (as number of days) as an integer.

    • The class has public getters String getStart(), String getEnd() and int getDiff().

      • The start and end dates are returned as ISO-8601 dates, in the form “year-month-day”. E.g. the date 6.12.2021 would be represented as “2021-12-06”.

    • All constructors (you probably need only one) are private!

      • This means that DateDiff objects can be created only within the outer class Dates; recall that Dates can access all private members of its inner class DateDiff.

    • A public member function String toString() that returns a string of form “start --> end: diff days" or "``start --> end: 1 day”, where the start and end dates are expressed in the form “Weekday day.month.year”. Both day and month are expressed using two digits.

    • E.g. if a DateDiff object dd is associated with start date 1.1.1999 and end date 1.1.2001, then:

      • dd.getStart() would return “1999-01-01”, dd.getEnd() would return “2001-01-01” and dd.toString() would return “Friday 01.01.1999 --> Monday 01.01.2001: 731 days”.

      • For simplicity the weekday will always be expressed in English.

  • A public static member function DateDiff[] dateDiffs(String ...dateStrs) that returns a DateDiff array that describes the differences between the dates described by the parameters. The difference between two dates is the number of days between them. E.g. the difference between 3.5.2021 and 4.5.2021 is 1 and the difference between same dates is 0.

    • To be more precise, the function sorts the received dates into ascending time order and returns one DateDiff object per each consecutive dates. This should become clear if you look at the examples below.

    • A reminder: the parameter dataStrs is variadic → the function receives dateStrs as a String array.

    • Each string in the dateStrs array must describe a date either in the ISO-8601 format or the (e.g. Finnish) format “day.month.year”. The ISO-8601 format requires that the day and the month use two digits and the year four. The function accepts a Finnish date if the day and the month use either one or two digits (may be mixed) and the year uses four digits. The dates also need to be legal; e.g. the otherwise correctly formed strings “2001-02-29” and “10.13.2004” would be discarded because they express illegal dates.

      • Each parameter string dateStr that is malformed or expresses an illegal date will be discarded and a message of form “The date dateStr is illegal!” is printed out.

      • The function must first iterate over dateStrs and select only legal dates. The legal dates are then sorted and a DateDiff object is created for each successive date pair.

      • Note that the requirement of four digit years means that only the years 1000…9999 are accepted.

    • The DateDiff objects are returned in a plain array. If the function receives less than two legal dates, no DateDiff objects can be created. In this case the function returns an empty array that can be created in the usual way; e.g as new DateDiff[0] or using an empty array initializer {}.

Some advice

Checking if a date is legal: how does the function LocalDate.of behave if its parameters describe an illegal date?

Weekday? A LocalDate object knows the weekday of the date it represents.

Difference between two dates? One fairly direct solution is to use the function LocalDate.until.

You might format the date strings (e.g. the weekdays) manually, if you wish to do so. But note that e.g. the Java library class DateTimeFormatter used in combination with the locale Locale.US might work well.

Example tests

The automated grader tests your Dates implementation with a test program similar to this:

public class DatesTest {
  public static void main(String args[]) {
    Dates.DateDiff[] diffArray = {};
    if(args.length == 2) {
      diffArray = Dates.dateDiffs(args[0], args[1]);
    }
    else {
      diffArray = Dates.dateDiffs(args);
    }
    for(Dates.DateDiff dd : diffArray) {
      System.out.format("start: %s end: %s diff: %d%n",
              dd.getStart(), dd.getEnd(), dd.getDiff());
      System.out.println("  " + dd);
    }
  }
}

Below are three example test program runs and their expected ouputs:

java DatesTest 1.1.2022 5.6.850

The date "5.6.850" is illegal!

java DatesTest 2022-05-31 1.1.2022

start: 2022-01-01 end: 2022-05-31 diff: 150
  Saturday 01.01.2022 --> Tuesday 31.05.2022: 150 days

java DatesTest 1.08.2016 07.3.2004 31.05.2022 29.2.2015 2017-11-23 7.04.2019 2000-3-6 2009-05-13

The date "29.2.2015" is illegal!
The date "2000-3-6" is illegal!
start: 2004-03-07 end: 2009-05-13 diff: 1893
  Sunday 07.03.2004 --> Wednesday 13.05.2009: 1893 days
start: 2009-05-13 end: 2016-08-01 diff: 2637
  Wednesday 13.05.2009 --> Monday 01.08.2016: 2637 days
start: 2016-08-01 end: 2017-11-23 diff: 479
  Monday 01.08.2016 --> Thursday 23.11.2017: 479 days
start: 2017-11-23 end: 2019-04-07 diff: 500
  Thursday 23.11.2017 --> Sunday 07.04.2019: 500 days
start: 2019-04-07 end: 2022-05-31 diff: 1150
  Sunday 07.04.2019 --> Tuesday 31.05.2022: 1150 days

A+ presents the exercise submission form here.