
Java Date and Time on HackerRank asks a simple question: given a date, what day of the week was it? You could work it out with Zeller's formula, but the point of the exercise is to use Java's date API instead. Knowing which class to reach for, and the small traps in each one, is exactly what you need when a real project asks you to show "Wednesday, 5 August" on a screen.
It is also a good place to learn the difference between the old Calendar class (which the problem statement mentions) and the newer java.time package that you should use in modern code.
Problem
You are given a month, a day and a year. Complete the method findDay(int month, int day, int year) so that it returns the weekday of that date, written fully in capital letters, such as WEDNESDAY. HackerRank's locked code reads the input, calls your method and prints what you return.
Input: one line with three space-separated numbers in the order MM DD YYYY.
Output: the day of the week in uppercase.
Constraints: 2000 < year < 3000.
Input:
08 05 2015
Output:
WEDNESDAY
5 August 2015 fell on a Wednesday.
Approach
With java.time.LocalDate this takes two lines:
- Build the date with
LocalDate.of(year, month, day). Watch the argument order. The input comes as month, day, year, butLocalDate.ofwants year first. - Call
getDayOfWeek(). It returns aDayOfWeekenum value such asDayOfWeek.WEDNESDAY. - Return
.name()on that enum. Enum constants in Java are written in capitals, so the name is already the exact text the problem wants. NotoUpperCase()needed.
Also note that LocalDate months run from 1 to 12, which matches the input. That is not true for the old Calendar class, as you will see below.
Dry run: for input 08 05 2015, month = 8, day = 5 and year = 2015. LocalDate.of(2015, 8, 5) is 2015-08-05, getDayOfWeek() is WEDNESDAY, and its name is the string "WEDNESDAY".
Solution in Java
import java.time.LocalDate;
import java.util.Scanner;
class Result {
// Returns the weekday for the given date, e.g. "WEDNESDAY"
public static String findDay(int month, int day, int year) {
LocalDate date = LocalDate.of(year, month, day); // note the order: year, month, day
return date.getDayOfWeek().name(); // enum name is already in capitals
}
}
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int month = in.nextInt();
int day = in.nextInt();
int year = in.nextInt();
in.close();
System.out.println(Result.findDay(month, day, year));
}
}
On HackerRank you only fill in the body of findDay inside the Result class. Their locked main writes the result to a file given by the OUTPUT_PATH environment variable. The main above prints to the console instead, so you can run it on your own machine.
What was wrong with the old code. The previous version of this post did not compile. Inside findDay it tried to read input again from a Scanner called in that did not exist, printed the day instead of returning it (the method has to return a String), and the closing brace of the Solution class was missing. The version above uses the parameters it is given and returns the answer.
If you want to use Calendar, as the problem text suggests, the method body would be:
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, day); // Calendar months start at 0 (January = 0)
return cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH).toUpperCase();
That month - 1 is the classic bug. Forget it and every answer is for the following month. Passing Locale.ENGLISH also matters, because otherwise the name comes out in your machine's default language.
Tests I ran with the LocalDate version:
08 05 2015gives WEDNESDAY (the sample).02 29 2024gives THURSDAY. Leap day works with no extra code.01 01 2001gives MONDAY, the first valid year.12 31 2999gives TUESDAY, the last day of the last valid year.
Output
WEDNESDAY
Complexity
Time: O(1). LocalDate computes the weekday from an epoch-day number with plain arithmetic, no looping over days.
Space: O(1).
Common mistakes
- Passing arguments in input order:
LocalDate.of(month, day, year). For the sample that throws aDateTimeException, because 2015 is not a valid day of the month. - With
Calendar, forgetting that January is 0. - Printing inside
findDayinstead of returning the String. The locked code expects a return value and writes it itself. - Using
getDisplayNamewithout a locale and getting the French name "mercredi" on a machine whose default locale is French.
Next in the series: Java String Tokens. Earlier: Java Substring Comparisons.
Tip: try to solve the problem yourself before reading the solution. Use the code as a reference to check your approach, and make sure you understand why it works.
More HackerRank solutions All coding problems MCQ practice
See everything in one place: Coding Problems and Solutions
Thanks you for the solution
ReplyDeleteThis solution is optimized , than mine
ReplyDelete