The overall goal is to create a set of classes that are capable of managing and
ID: 3916763 • Letter: T
Question
The overall goal is to create a set of classes that are capable of managing and displaying dates by the Gregorian and Julian calendars. The first in the series takes a naive view of creating classes, resulting in a program that has a lot of duplicated code. Then, in the second part, you'll clean up all of the duplication through the use of the Java programming language features, making a big improvement of the first assignment in the series.For the purposes of this assignment, we are mostly interested in the difference in how leap years are determined, and using that, want to represent dates using both calendars. For example, today (when I'm writing this) on the Gregorian calendar is February 15th, 2018, but on the Julian calendar is February 3rd, 2018.
The following details the requirements for the assignment:
Create two classes, GregorianDate and JulianDate.
The two date classes must expose only the following public instance methods and constructors, and provides an implementation that is appropriate for the calendar:
Default constructor that sets the date to the current date. See notes below about dates to help you figure out how to do this appropriately for each calendar.
Overloaded constructor that takes year, month, and date values and sets the date to that date: GregorianDate(int year, int month, int day) and JulianDate(int year, int month, int day)
A method that adds a specified number of days to the date: void addDays(int days)
Remember to track when the month and years change.
A method that subtracts a specified number of days to the date: void subtractDays(int days)
Remember to track when the month and years change.
A method that returns true/false if the date is part of a leap year: boolean isLeapYear()
A method that prints the date (without a carriage return) in mm/dd/yyyy format: void printShortDate()
A method that prints the date (without a carriage return) in Monthname dd, yyyy format: void printLongDate()
The following 'get' accessor methods. These aren't used by the sample driver code, but would normally be part of a class like this. These accessor methods, however, are used by the unit tests.
String getCurrentMonthName()
int getCurrentMonth()
int getCurrentYear()
int getCurrentDayOfMonth()
Store the year, month, and day values as private instance (non-static) data members of the class.
The two date classes must provide only the following private methods, which you'll use in support of the other public instance methods:
A method that returns true/false if a a specified year is a leap year: boolean isLeapYear(int year)
A method that returns the number of days in a month (for a year): int getNumberOfDaysInMonth(int year, int month)
A method that returns the name of a month: String getMonthName(int month)
Use System.currentTimeMillis() to obtain the number of milliseconds that have occurred since January 1, 1970.
The number returned from this method does not account for the time zone of the computer it is running on, you need to account for that. To get the time zone offset to correct for local time you can call java.util.TimeZone.getDefault().getRawOffset()This gives the number of milliseconds to "add" to the current time. I say "add" because it is a negative number, it is the offset you need.
For a Gregorian date, you can use this knowledge to start by initializing a date to 1/1/1970, then adding the number of days the number of milliseconds since then have taken place; remember to account for the time zone as described above.
For a Julian date, you have to set the starting date to January 1, 1 (1/1/1), then add in the number of days until (Gregorian) January 1, 1970, then, update the date with the number of milliseconds since 1/1/1970; of course, remember to account for the time zone as described above. The number of Julian days from 1/1/1 to 1/1/1970 is 719164. Here is a handy reference to compute the number of days between two dates
You can't use the built-in Date, Calendar, or GregorianCalendar classes as part of the code you write.
Explanation / Answer
//DateBase .java
package calendars;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DateBase {
private String[] MONTH_NAMES = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
private List<Integer> ODD_MONTHS = Arrays.asList(1, 3, 5, 7, 8, 10, 12);
private int year;
private int month;
private int day;
public DateBase() {
}
public DateBase(int y, int m, int d) {
day = d;
month = m;
year = y;
}
public void addDays(int days) {
year += days / 365;
days %= 365;
month += days / 30;
days %= 30;
day += days;
if (isLeapYear(year) && month == 2 && day > 28) {
day -= 28;
month++;
} else if (ODD_MONTHS.contains(month) && day > 31) {
day -= 31;
month++;
} else if (day > 30) {
day -= 30;
month++;
}
}
public void subtractDays(int days) {
year -= days / 365;
days %= 365;
month -= days / 30;
days %= 30;
day -= days;
if (isLeapYear(year) && month == 2 && day > 28) {
day += 28;
month--;
} else if (ODD_MONTHS.contains(month) && day > 31) {
day += 31;
month--;
} else if (day > 30) {
day += 30;
month--;
}
}
private boolean isLeapYear(int year) {
return year % 4 == 0;
}
private int getNumberOfDaysInMonth(int year, int month) {
if (isLeapYear(year) && month == 2) {
return 29;
} else if (month == 2) {
return 28;
} else if (ODD_MONTHS.contains(month)) {
return 31;
}
return 30;
}
public String getCurrentMonthName() {
return MONTH_NAMES[month - 1];
}
public int getCurrentMonth() {
return month;
}
public int getCurrentYear() {
return year;
}
public int getCurrentDayOfMonth() {
return day;
}
public void printShortDate() {
System.out.println(String.format("%d/%d/%d", month, day, year));
}
public void printLongDate() {
System.out.println(String.format("%s %d, %d", getCurrentMonthName(), day, year));
}
}
//GregorianDate.java
package calendars;
public class GregorianDate extends DateBase {
public GregorianDate() {
super(1970, 1, 1);
long miliSeconds = System.currentTimeMillis() + java.util.TimeZone.getDefault().getRawOffset();
int days = (int) miliSeconds / 1000 / 60 / 60 / 24;
addDays(days);
}
public GregorianDate(int year, int month, int day) {
super(year, month, day);
}
}
//JulianDate.java
package calendars;
public class JulianDate extends DateBase {
public JulianDate() {
super(1, 1, 1);
addDays(719164);
long miliSeconds = System.currentTimeMillis() + java.util.TimeZone.getDefault().getRawOffset();
int days = (int) miliSeconds / 1000 / 60 / 60 / 24;
addDays(days);
}
public JulianDate(int year, int month, int day) {
super(year, month, day);
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.