This is my updated code, it still doesn't work. It returns day for all cases of Feb. 29th, when it should only return day if it is a leap year, if it is not a leap year 1 should be returned.
public int checkDay (int day)
{
// For months with 30 days.
if ((month == 4 || month == 6 || month == 9 || month == 11) && day <= 30)
return day;
// For months with 31 days.
if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && (day <= 31))
return day;
// For leap years.
// If February 29th...
if (month == 2 && day == 29)
{
// Check if year is a leap year.
if ((year%4 == 0 && year%100!=0) || year%400 == 0)
{
// If year is a leap year return day as 29th.
return day;
}
// If not a leap year, return day as 1st.
else return 1;
}
// If Date if February 1st through 28th return day, as it is valid.
if (month == 2 && (day >= 1 && day <= 28))
return day;
// Return day as 1st for all other cases.
return 1;
}
Try GregorianCalendar http://docs.oracle.com/javase/6/docs/api/java/util/GregorianCalendar.html
GregorianCalendar gc = new GregorianCalendar();
if (gc.isLeapYear(year) )
Try changing your code as
if (year%4==0&&(year%100!=0&&year%400==0))
if ((year%4==0 && year%100!=0) || year%400==0)
this solves your problem, your logic was false :)
try this code: if the returned boolean is false you can set the day to 1, because the date is not valid.
public bool checkDay (int day, int month, int year){
bool valid = false;
if(day >=1){
// For months with 30 days.
if ((month == 4 || month == 6 || month == 9 || month == 11) && day <= 30){
valid = true;
}
// For months with 31 days.
if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day <= 31){
valid = true;
}
// For February.
if (month == 2)
{
if(day <= 28){
valid = true;
} else if(day == 29){
if ((year%4 == 0 && year%100!=0) || year%400 == 0){
valid = true;
} //else invalid
}
}
} //else date is not valid
return valid;
}
It is better practice to have only one return statement in each method. That makes it easier to understand the code and by that to debug it and find possible errors. If you have any problems, feel free to ask.
Related
public static void main(String[] args){
boolean year = isLeapYear(9999);
System.out.println("Is Leap Year: " + year);
}
public static boolean isLeapYear(int year){
int rem4 = year % 4;
int rem100 = year % 100;
int rem400 = year % 400;
if ((year >= 1 && year <= 9999) && (rem4 == 0) && (rem100 == 0 && rem400 == 0) || (rem100 != 0) && (rem4 == 0)){
return true;
}
return false;
}
When I enter a negative year (so far only -1024) my range condition doesn't work.
But if I enter any other negative leap year it works(-2020). So I don't know what I'm possibly missing, or if the structure of the algorithm is quite right. Any help will be appreciated.
What is expected is that when I enter a year that is not a leap year, and if it is a negative leap year, it returns false.
I know it's considered cool to be concise and all, but this kind of thing is often best done with multiple simple conditionals. Especially when you're first developing it.
if (year < 1 || year > 9999)
return false;
if (rem4 != 0)
return false;
if (rem100 == 0 && rem400 != 0)
return false;
return true;
Or, perhaps:
if (year >= 1 && year <= 9999)
if (rem4 == 0) {
if (rem100 == 0)
return (rem400 == 0);
return true;
}
return false;
Either way will be easier to debug than one big long complicated if statement.
Not exactly sure, but maybe it's because when
|| (rem100 != 0) && (rem4 == 0)) returns a true statement, your whole function returns true, negating the whole first part of your if-statement.
As the || overrides the positive validation part, just add that same validation in the other part of the condition...
(year >= 1 && year <= 9999 && rem4 == 0 && rem100 == 0 && rem400 == 0 || year >= 1 && year <= 9999 && rem100 != 0 && rem4 == 0)
I am trying to write a program which shows the number of days in a given month of a year. The outputs for the month of February, non leap years (no output) and the months having 30 days in leap years is incorrect (output is 29). How could I resolve this?
public class Q11 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner number1 = new Scanner(System.in);
Scanner number2 = new Scanner(System.in);
System.out.println("Enter the month (1-12)");
int month = number1.nextInt();
System.out.println("Enter the year");
int year = number2.nextInt();
int number_of_days = 0;
boolean N1 = (month == 1) ||
(month == 3) ||
(month == 5) ||
(month == 7) ||
(month == 8) ||
(month == 10) ||
(month == 12);
boolean N2 = (month == 2) && (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
boolean N3 = (month == 2) && (year % 400 <= 1) || (year % 4 <= 1) && (year % 100 == 0);
boolean N4 = (month == 4) ||
(month == 6) ||
(month == 9) ||
(month == 11);
if (N1)
System.out.println(". This month has 31 days");
else if (N2)
System.out.println(". This month has 29 days");
else if (N3)
System.out.println(". This month has 28 days");
else if (N4)
System.out.println(". This month has 30 days");
}
}
Problem
You run into a problem due to the fact how the program evaluates your boolean expressions. Remember the rules for boolean precedence. && is evaluated first and takes precedence. Also, the formula is evaluated from left to right. Operator precedence can be overruled with the correct setting of parentheses.
E.g. if you have a && b || c, a && b is evaluated first, after which we evaluate its result against || c. But: a && (b || c) is evaluated by first evaluating b || c and then evaluating this result against && a.
In your case, when you enter e.g. month = 4 and year = 2020 the following happens:
The rule n1 is skipped - month is not listed.
The rule n2 is evaluated - month is not equals to two and the year is not divisible by 400; so far everything goes to plan. But now - the next || comes around to bite you. The year is divisible by 4 AND it is not divisible by 100. The program now incorrectly prints 29.
The rules n3 and n4 are solved like n2 and are left as an exercise for the reader :)
Solution
Easiest way is to understand why n2 is failing and optimize the formula. Since this is a homework task I don't want to solve it for you.
General
One scanner instance on System.in is enough.
Your variable names should follow the Java naming convention, lowerCaseCamelCase instead of snake_case and N1.
Parting thought
Try using a switch statement on month - it will make your code a bit easier to understand. Finally: Good luck in your studies.
In your existing code make the following changes.
this checks for leap year.
if it is divisible by 4 and not a century year, its is a leap year
or if is divisible by 400 it is a leap year.
otherwise, it isn't.
boolean N2 = (year %4 == 0 && year %100 != 0) || (year % 400 == 0);
Now just use the negation of the boolean to test for non leap year.
if (N1)
System.out.println(". This month has 31 days");
else if (N4) {
System.out.println(". This month has 30 days");
} else if (month == 2) {
boolean N2 = (year %4 == 0 && year %100 != 0) || (year % 400 == 0);
if (N2) {
System.out.println("This month has 29 days");
} else {// must not be leap year.
System.out.println("This month has 28 days");
}
} else {
System.out.printf("Bad month(%d) entered", month);
}
Also, you should only use one Scanner for all console input.
An alternative approach
In case you didn't know, the enhanced switch statement introduced in Java 13 would be perfect for this.
it takes multiple cases
and returns an argument for processing.
public class Q11 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the month (1-12)");
int month = scanner.nextInt();
System.out.println("Enter the year");
int year = scanner.nextInt();
boolean isLeapYear = (year %4 == 0 && year %100 != 0) || (year % 400 == 0);
String proclamation = switch(month) {
case 1,3,5,7,8,10,12 -> "This month has 31 days.";
case 4,6,9,11 -> "This month has 30 days";
case 2 -> "This month has %d days".formatted(isLeapYear ? 29 : 28);
default -> "Bad month (%d) entered.".formatted(month);
};
System.out.println(proclamation);
}
}
So basically we have this question to do : Write a method dayNumber that determines the number of days in a year up to and including the current day. The method should have three int parameters: year, month, and day. If the value of any parameter is invalid, the method should print a warning message and return the value zero. The table gives some examples of the action of the method. Accept any non-negative year as being valid. You may want to assume the existence of a method numberOfDays that returns the number of days in a given month of a given year. And you should have a method call isLeapYear, if the user enter a year that is a leap year.
This is what I did so far....
class dayMonthYear {
public static void main(String[] args) {
System.out.println("Enter a year");
int year = In.getInt();
System.out.println("Enter the month for '1' to be January - '12' to be december");
int month = In.getInt();
System.out.println("Enter the day");
int day = In.getInt();
dayNumber(year, month, day);
System.out.println(dayNumber(year, month, day));
}
public static int dayNumber(int year, int month, int day) {
int total = 0;
for (int m = 1; m < month; m++)
total += (numberOfDays(month, year));
return total + day;
}
public static boolean isLeapYear(int yearB) {
return (yearB % 4 == 0 && yearB % 100 != 0) || yearB % 400 == 0;
}
public static int numberOfDays(int monthA, int yearA) {
int days = 0;
if (monthA == 4 || monthA == 6 || monthA == 9 || monthA == 11)
days = 30;
if (monthA == 1 || monthA == 3 || monthA == 5 || monthA == 7
|| monthA == 8 || monthA == 10 || monthA == 12)
days = 31;
else if (monthA == 2 && isLeapYear(yearA))
days = 29;
else if (monthA == 2)
days = 28;
return days;
}
}
It works and compiles but my problem is that: let say I enter "12" for December and December has 31 days, so what my program will do since December has 31 days, it thinks each month has 31 days and add them up which will give me 372 when it's suppose to give me 365. How do I make it that it won't do that and that it will work if the year is a leap year too.
Basically, this...
for (int m= 1; m < month; m++)
total += (numberOfDays(month, year));
is wrong, you are passing the value of month to this method each time it is called (12 for example), meaning that each time you call it, it thinks the number of days in the month is 31 (because it is)...
Instead, pass m
for (int m= 1; m < month; m++)
total += (numberOfDays(m, year));
Spoiler alert!! for project euler problem 19.
The problem is how many sundays fall on the first of the month from 1901 to 2000. Given information: Jan 1st 1900 was a monday, Jan & march etc have 31 days, April, June etc 30 days and a leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400. which in this case applies to year 2000.
I got the correct answer, but when I checked my results with a real calendar, it turns out my code is counting saturdays. I don't see why it is doing that, can someone help?!
public class Sunday {
public static void main(String[] args) {
int sundayCount = 0;
int currentday = 0; // monday is 0, sunday will be 6
int dayLimit = 0;
for (int year = 1900; year < 2001; year++) {
for (int month = 1; month < 13; month++) {
// 30 days April, June, September, November
if (month == 4 || month == 6 || month == 9 || month == 11)
dayLimit = 30;
// leap year
else if (month == 2 && year % 4 == 0)
dayLimit = 29;
// February not leap year
else if (month == 2 && year % 4 != 0)
dayLimit = 28;
// Jan, March, May, July, August, October, December
else
dayLimit = 31;
for (int day = 1; day <= dayLimit; day++) {
if (day == 1 && currentday == 6 && year > 1900) {
System.out.println("year: " + year);
System.out.println("month: " + month);
sundayCount++;
}
if (currentday < 6)
currentday++;
else
currentday = 0;
}
}
}
System.out.println(sundayCount);
}
}
You forget to add into the code to check for if febuary 1900 should have 29 or 28 days. As 1900 wasn't a leap year it shouldn't have 29 days in 1900.
else if (month == 2 && year % 4 == 0 && year != 1900)
dayLimit = 29;
// February not leap year
else if (month == 2)
dayLimit = 28;
This should fix it.
I have a homework assignment which asks to have the user input a date in Java in the (mm/dd/yyyy) format, then to determine if the entered date is valid. I have been able to successfully do this for every month, save February, because you must take leap years into account.
I have this code:
import java.util.Scanner;
/**
*
* #author Andrew De Forest
* #version v1.0
*
*/
public class exc6
{
public static void main (String[] args)
{
//Initialize a string
String getInput;
//Initialize some integers
int month, day, year;
//Make a boolean
boolean validDate;
//Set the date to false
validDate = false;
//Ask for input
System.out.println("Enter a date (mm/dd/yyyy)");
//Initialize the scanner
Scanner keyboard = new Scanner (System.in);
//Get input & use a delimiter
keyboard.useDelimiter("[/\n]");
month = keyboard.nextInt();
day = keyboard.nextInt();
year = keyboard.nextInt();
if((month >= 1 && month <= 12) && (day >= 1 && day <= 31))
{
//For months with 30 days
if((month == 4 || month == 6 || month == 9 || month == 11) && (day <= 30))
{
validDate = true;
}
//For months with 31 days
if((month == 1 || month == 2 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && (day <= 31))
{
validDate = true;
}
//For February
if((month == 2) && (day < 30))
{
//Boolean for valid leap year
boolean validLeapYear = false;
//A leap year is any year that is divisible by 4 but not divisible by 100 unless it is also divisible by 400
if((year % 400 == 0) || ((year % 4 == 0) && (year %100 !=0)))
{
validLeapYear = true;
}
if (validLeapYear == true && day <= 29)
{
validDate = true;
}
else if (validLeapYear == false && day <= 28)
{
validDate = true;
}
}
}
//If the date is valid
if(validDate == true)
{
System.out.println(month + "/" + day + "/" + year + " is a valid date.");
}
else
{
System.out.println("Invalid date!");
}
}
}
The part I'm most concerned with is this:
//For February
if((month == 2) && (day < 30))
{
//Boolean for valid leap year
boolean validLeapYear = false;
//A leap year is any year that is divisible by 4 but not divisible by 100 unless it is also divisible by 400
if((year % 400 == 0) || ((year % 4 == 0) && (year %100 !=0)))
{
validLeapYear = true;
}
if (validLeapYear == true && day <= 29)
{
validDate = true;
}
else if (validLeapYear == false && day <= 28)
{
validDate = true;
}
}
}
As far as I can tell, it looks correct. However, when I input something like 2/29/2011, it returns as a valid date (which it should not, as 2011 was not a leap year). Why is this? What am I missing, or passing over, that causes bad dates to return valid?
if((month == 1 || month == 2 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && (day <= 31))
This line already catches February.
DateFormat dateFormat = new SimpleDateFormat("yyyy-MMM-dd");
dateFormat.setLenient(false);
String dateAsString = "2011-Feb-29";
Date date = dateFormat.parse(dateAsString); // throws an exception; invalid date
First you're setting validDate to true because month is 2.
Next you're setting validLeapYear to false because it's not a leap year.
(validLeapYear == true && day <= 29) isn't true.
(validLeapYear == false && day <= 28) also isn't true.
Therefore, validDate is still true.