//Class: Date
public class Date implements Cloneable, Comparable{
    private int month;
    private int day;
    private int year;

    //Default constructor
    public Date() {
        month = 0;
        day = 0;
        year = 1900;
    }

    //Alternate constructor
    public Date(int m, int d, int y) {
        month = (m >=1 && m <= 12)? m: 0;
        day = (d >=1 && d <= 31)? d: 0;
        year = (y >=1900 && y <= 2020)? y: 0;
        //setDate(m, d, y);
    }

    //Copy constructor
    public Date(Date original) {
        if(original == null)  {
            System.out.println("Fatal error for this Date.");
            System.exit(0);
        }
        month = original.month;
        day = original.day;
        year = original.year;
    }

    //clone; without this, compile error in client (.clone protected)
    public Object clone() {
        try  {
            return super.clone();
        }
        catch (CloneNotSupportedException e) {
            return null;
        }
    }

    public void setDate(int m, int d, int y) {
        month = (m >=1 && m <= 12)? m: 0;
        day = (d >=1 && d <= 31)? d: 0;
        year = (y >=1900 && y <= 2020)? y: 0;
    }

    public int getMonth() {
        return month;
    }

    public int getDay() {
        return day;
    }

    public int getYear() {
        return year;
    }

    public String toString() {
        return (month + "-" + day + "-" + year);
    }

    public boolean equals(Object obj) {
      if (obj instanceof Date) {
          Date otherDate = (Date) obj;
          return month == otherDate.month && day == otherDate.day && year == otherDate.year;
      }
      else   // not a Date object
          return false;
    }

    public int compareTo(Object otherDate) {
        Date temp = (Date) otherDate;
        int yearDiff = year - temp.year;
        if (yearDiff != 0)
            return yearDiff;
        int monthDiff = month - temp.month;
        if (monthDiff != 0)
            return monthDiff;
        return day - temp.day;
    }
}

//Class: ClientDateClone
public class ClientDateClone {
    public static void main(String[] args) {
        Date d1 = new Date(1, 2, 2009);
        System.out.println("d1: " + d1);
        Date d2 = (Date) d1.clone();
        System.out.println("Copy d1 using .clone(). After copy, d2: " + d2);

        if (d1 == d2)
            System.out.println("Both d1 and d2 refer to the same object.");
        else
            System.out.println("d1 and d2 DON'T refer to the same object.");
        d1.setDate(11, 12, 2009);
        System.out.println("Changed d1 to 11-12-2009. After change:");
        System.out.println("d1: " + d1);
        System.out.println("d2: " + d2);
    }
}

OUTPUT:

d1: 1-2-2009
Copy d1 using .clone(). After copy, d2: 1-2-2009
d1 and d2 DON'T refer to the same object.
Changed d1 to 11-12-2009. After change:
d1: 11-12-2009
d2: 1-2-2009