Skip to content

Commit b45a336

Browse files
author
java-tester-x
committed
Add code of "DateUtil" task
Add code of "DateUtil" task
1 parent 8507562 commit b45a336

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

difficult/DateUtil.java

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/**
2+
* Complete the following methods in a class called DateUtil:
3+
*
4+
* - boolean isLeapYear(int year): returns true if the given year is a leap year.
5+
* A year is a leap year if it is divisible by 4 but not by 100, or it is divisible by 400.
6+
*
7+
* - boolean isValidDate(int year, int month, int day): returns true if the given year,
8+
* month and day constitute a given date. Assume that year is between 1 and 9999,
9+
* month is between 1 (Jan) to 12 (Dec) and day shall be between 1 and 28|29|30|31
10+
* depending on the month and whether it is a leap year.
11+
*
12+
* - int getDayOfWeek(int year, int month, int day): returns the day of the week,
13+
* where 0 for SUN, 1 for MON, ..., 6 for SAT, for the given date. Assume that the date is valid.
14+
*
15+
* - String toString(int year, int month, int day): prints the given date
16+
* in the format "xxxday d mmm yyyy", e.g., "Tuesday 14 Feb 2012". Assume that the given date is valid.
17+
*
18+
* To find the day of the week (Reference: Wiki "Determination of the day of the week"):
19+
* 1. Based on the first two digit of the year, get the number from the following "century" table.
20+
* -------+---------+--------+--------+--------+--------+--------+--------+
21+
* 1700- | 1800- | 1900- | 2000- | 2100- | 2200- | 2300- | 2400- |
22+
* 4 | 2 | 0 | 6 | 4 | 2 | 0 | 6 |
23+
* -------+---------+--------+--------+--------+--------+--------+--------+
24+
* Take note that the entries 4, 2, 0, 6 repeat.
25+
*
26+
* 2. Add to the last two digit of the year.
27+
*
28+
* 3. Add to "the last two digit of the year divide by 4, truncate the fractional part".
29+
*
30+
* 4. Add to the number obtained from the following month table:
31+
* -------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
32+
* Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
33+
* -------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
34+
* Non-Leap Year 0 | 3 | 3 | 6 | 1 | 4 | 6 | 2 | 5 | 0 | 3 | 5 |
35+
* -------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
36+
* Leap Year 6 | 2 | same as above |
37+
* -------------------+-----+-----------------------------------------------------------+
38+
*
39+
* 5. Add to the day.
40+
*
41+
* 6. The sum modulus 7 gives the day of the week, where 0 for SUN, 1 for MON, ..., 6 for SAT.
42+
*
43+
* For example: 2012, Feb, 17
44+
* (6 + 12 + 12/4 + 2 + 17) % 7 = 5 (Fri)
45+
*/
46+
47+
package javaexercises.difficult;
48+
49+
public class DateUtil {
50+
51+
private final int MIN_YEAR = 1;
52+
private final int MAX_YEAR = 9999;
53+
54+
// Month's name – for printing
55+
private final String[] strMonths = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
56+
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
57+
// Day's name - for printing
58+
private final String[] strDays = {"Sunday", "Monday", "Tuesday", "Wednesday",
59+
"Thursday", "Friday", "Saturday"};
60+
61+
// Number of days in each month (for non-leap years)
62+
private final int[] daysInMonths = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
63+
64+
private final int[] nonLeapYearMonthNumbers = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
65+
66+
private final int[] leapYearMonthNumbers = {6, 2, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
67+
68+
69+
public static void main(String[] args) {
70+
DateUtil aDateUtil = new DateUtil();
71+
72+
System.out.println(aDateUtil.isLeapYear(1900)); // false
73+
System.out.println(aDateUtil.isLeapYear(2000)); // true
74+
System.out.println(aDateUtil.isLeapYear(2011)); // false
75+
System.out.println(aDateUtil.isLeapYear(2012)); // true
76+
77+
System.out.println(aDateUtil.isValidDate(2012, 2, 29)); // true
78+
System.out.println(aDateUtil.isValidDate(2011, 2, 29)); // false
79+
System.out.println(aDateUtil.isValidDate(2099, 12, 31)); // true
80+
System.out.println(aDateUtil.isValidDate(2099, 12, 32)); // false
81+
82+
System.out.println(aDateUtil.getDayOfWeek(1982, 4, 24)); // 6:Sat
83+
System.out.println(aDateUtil.getDayOfWeek(2000, 1, 1)); // 6:Sat
84+
System.out.println(aDateUtil.getDayOfWeek(2054, 6, 19)); // 5:Fri
85+
System.out.println(aDateUtil.getDayOfWeek(2012, 2, 17)); // 5:Fri
86+
87+
System.out.println(aDateUtil.toString(2012, 2, 14)); // Tuesday 14 Feb 2012
88+
System.out.println(aDateUtil.toString(2014, 2, 26)); // Wednesday 26 Feb 2014
89+
}
90+
91+
/**
92+
* Returns true if the given year is a leap year.
93+
* A year is a leap year if it is divisible by 4 but not by 100,
94+
* or it is divisible by 400.
95+
*
96+
* @param year
97+
* @return true if the given year is a leap year.
98+
*/
99+
private boolean isLeapYear(int year) {
100+
return (year%4 == 0 && year%100 != 0) || (year%400 == 0);
101+
}
102+
103+
/**
104+
* Returns true if the given year, month and day constitute a given date.
105+
* Assume that year is between 1 and 9999, month is between 1 (Jan) to 12 (Dec)
106+
* and day shall be between 1 and 28|29|30|31 depending on the month
107+
* and whether it is a leap year.
108+
*
109+
* @param year
110+
* @param month
111+
* @param day
112+
* @return true if the given year, month and day constitute a given date.
113+
*/
114+
private boolean isValidDate(int year, int month, int day)
115+
{
116+
if (year < MIN_YEAR || year > MAX_YEAR) {
117+
return false;
118+
}
119+
if (month < 1 || month > 12) {
120+
return false;
121+
}
122+
int monthDays = daysInMonths[month-1] + (month == 2 && isLeapYear(year) ? 1 : 0);
123+
return 1 <= day && day <= monthDays;
124+
}
125+
126+
// Return the day of the week, 0:Sun, 1:Mon, ..., 6:Sat
127+
private int getDayOfWeek(int year, int month, int day)
128+
{
129+
// 1. Based on the first two digit of the year, get the number from the "century" table.
130+
int magicCenturyNumber = 6 - 2*((year / 100) % 4);
131+
132+
// 2. Add to the last two digit of the year.
133+
int lastTwoDigitsOfYear = year % 100;
134+
135+
// 3. Add to "the last two digit of the year divide by 4, truncate the fractional part".
136+
int magicYearNumber = lastTwoDigitsOfYear / 4;
137+
138+
// 4. Add to the number obtained from the month table.
139+
int magicMonthNumber = isLeapYear(year) ? leapYearMonthNumbers[month-1] : nonLeapYearMonthNumbers[month-1];
140+
141+
// 5. Add to the day.
142+
int magicDayNumber = day;
143+
144+
// 6. The sum modulus 7 gives the day of the week, where 0 for SUN, 1 for MON, ..., 6 for SAT.
145+
return ( magicCenturyNumber + lastTwoDigitsOfYear
146+
+ magicYearNumber + magicMonthNumber + magicDayNumber) % 7;
147+
}
148+
149+
// Return String "xxxday d mmm yyyy" (e.g., Wednesday 29 Feb 2012)
150+
private String toString(int year, int month, int day) {
151+
if ( ! isValidDate(year, month, day)) {
152+
return "Not a valid date!";
153+
}
154+
int d = getDayOfWeek(year, month, day);
155+
return strDays[d] + " " + day + " " + strMonths[month-1] + " " + year;
156+
}
157+
}

0 commit comments

Comments
 (0)