Simple way to add 30 days to a date - java

I'm new to programming (doing a course on Computer Science) and one of the exercises is to have the program read a date and then print the next 30 days over and over until the end of the year.
Problem is, there are restrictions. I cannot use Date/Calendar classes, only the Scanner class. So I'm having some trouble getting the dates right... so the only way I've found is to use Switch and have a case for each month, but then there's the issue with the 30/31-day months and leap years. So the days are not the same.
Is there a simpler way to do it?

If you can't use date/calendar classes, then the question is aimed at getting you to do the kind of things that date/calendar classes do internally. I wouldn't be surprised to see switch statements as part of your answer. You will need to teach your implementation knows how many days are in a month, which years are leap years etc.

You could use something like this,
Main class:
public class AppMain {
public static void main(String[] args) {
MyDate initDate = new MyDate(14, 1, 2012);
printMyDate(initDate);
MyDate newDate = initDate;
do{
newDate = DateIncrementator.increaseDate(newDate, 30);
printMyDate(newDate);
}while(newDate.getYear() == initDate.getYear());
}
private static void printMyDate(MyDate date){
System.out.println("[Day: "+ date.getDay() + "][" + "[Mont: "+ date.getMonth() + "][" + "[Year: "+ date.getYear() + "]");
}
}
DateIncrementator class:
public class DateIncrementator {
private static final int[] MONTH_DAYS_NOP_LEAP_YEAR = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public static MyDate increaseDate(MyDate date, int numberOfDays){
if(numberOfDays < 1 || numberOfDays > 30){
throw new IllegalArgumentException("numberOfDays must have a value between 1 and 30");
}
int numberDaysCurrentMonth = MONTH_DAYS_NOP_LEAP_YEAR[date.getMonth() - 1];
if(date.getMonth() == 2 && isLeapYear(date.getYear())){
numberDaysCurrentMonth++;
}
int newDay = date.getDay();
int newMonth = date.getMonth();
int newYear = date.getYear();
newDay += numberOfDays;
if(newDay > numberDaysCurrentMonth){
newDay = newDay % numberDaysCurrentMonth;
newMonth++;
}
if(newMonth > 12){
newMonth = 1;
newYear++;
}
return new MyDate(newDay, newMonth, newYear);
}
private static boolean isLeapYear(int year){
if(year % 4 != 0){
return false;
}
if(year % 100 != 100){
return true;
}
if(year % 400 == 0){
return true;
}else{
return false;
}
}
}
MyDate class:
public class MyDate {
private int day; // 1 to 31
private int month; // 1 to 12
private int year; // 0 to infinite
public MyDate(int day, int month, int year) {
this.day = day;
this.month = month;
this.year = year;
}
public int getDay() {
return day;
}
public int getMonth() {
return month;
}
public int getYear() {
return year;
}
}

Related

Duplicate Value when parameter names are different and constructor chaining only giving zeros as output

Im trying to make 3 constructors to put into someone elses code. Im getting 2 weird errors. 1. its giving me a duplicate error when the names are different and 2. Its outputting only zeros even when there is user input to say other wise. Im assuming its my constructors but Im not sure. EDIT: Ive added the rest of the code for reference
public class MyDateChoice {
private static final String[] monthNames = {"January", "February",
"March", "April", "May", "June", "July", "August",
"September", "October", "November", "December"};
private static final int[] monthDays = {31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
private int day; // day of the month
private int month; // month in the year
private int year; // year
public MyDateChoice () {
this (0,0,0);
}
public MyDateChoice (int month, int day, int year) {
}
public MyDateChoice (String monthName, int day, int year) {
}
public MyDateChoice(int ddd, int year) {
if (year < 0) { // validate year
throw new IllegalArgumentException("year must be > 0");
}
if (ddd < 1 || ddd > 366) { // check for invalid day
throw new IllegalArgumentException("day out of range");
}
this.year = year;
int dayTotal = 0;
for (int m = 1;
m < 13 && (dayTotal + daysInMonth(m, year)) < ddd; ++m) {
dayTotal += daysInMonth(m, year);
this.month = 1;
}
this.day = ddd - dayTotal;
}
// Set the day
public void setDay(int day) {
if (day < 1 || day > daysInMonth(month, year)) {
throw new IllegalArgumentException("day out of range for current month");
}
this.day = day;
}
// Set the month
public void setMonth(int month) {
if (month <= 0 || month > 12) { // validate month
throw new IllegalArgumentException("month must be 1-12");
}
this.month = month;
}
// Set the year
public void setYear(int year) {
if (year < 0) { // validate year
throw new IllegalArgumentException("year must be > 0");
}
this.year = year;
}
// return Date in format: mm/dd/yyyy
public String toString() {
return String.format("%d/%d/%d", month, day, year);
}
// return Date in format: MonthName dd, yyyy
public String toMonthNameDateString() {
return String.format(
"%s %d, %d", monthNames[month ], day, year);
}
// return Date in format DDD YYYY
public String toDayDateString() {
return String.format("%d %d", convertToDayOfYear(), year);
}
// Return the number of days in the month
private static int daysInMonth(int month, int year) {
return leapYear(year) && month == 2 ? 29 : monthDays[month - 1];
}
// test for a leap year
private static boolean leapYear(int year) {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
return true;
}
else {
return false;
}
}
// convert mm and dd to ddd
private int convertToDayOfYear() {
int ddd = 0;
for (int m = 1; m < month; ++m) {
if (leapYear(year) && m == 2) {
ddd += 29;
}
else {
ddd += monthDays[m -1];
}
}
ddd += day;
return ddd;
}
// convert from month name to month number
private static int convertFromMonthName(String monthName) {
for (int subscript = 0; subscript < 12; subscript++) {
if (monthName.equals(monthNames[subscript])) {
return subscript + 1;
}
}
throw new IllegalArgumentException("Invalid month name");
}
}
For the first issue, The constructor does not really care about the name of the variables as they are aliases. It only cares about the type of the input parameters, in this case both methods have two int inputs.
For the second issue, it seems for now you have implemented the default constructor which simply initializes all your members to zero. That's the reason why you are getting everything as zero (I am guessing this is the one only used for initialization of your new objects for now)
Design tips:
Rather than having setter for every member, it is a good practice to follow the builder pattern (https://dzone.com/articles/design-patterns-the-builder-pattern)
Rather than having many constructors with different parameter types you can use generic methods (https://docs.oracle.com/javase/tutorial/extra/generics/methods.html) or even simpler way is to use conversions. To elaborate this further:
This is what you have:
public MyDateChoice (int month, int day, int year) {
}
public MyDateChoice (String monthName, int day, int year) {
}
What you can do is create a static method that converts the month name from string to int, and this allows you to eliminate the second constructor:
public MyDateChoice (int month, int day, int year) {
}
public static int getMonthNameInt(Stringt monthName) {
}

Is it bad practice to have validation of an instance variable depend on another instance variable?

Is it bad to have one variable depend on the state of another variable?
For example, I have a class Date which has the attributes day, month, and year. Month and year can be independently validated in their respective setters, but day depends on month and / or year i.e. maximum number of days during a month / leap year. My approach is to ensure that my constructor requires all three fields, and it will call the setter for day after month and year.
Is a state dependency like this discouraged? My class is not immutable, so I need some sort of validation, and I want to encapsulate the validation in the class itself rather than do it externally.
Below is my current code :
class Date {
private int day;
private int month;
private int year;
public String toString() {
return String.format("%02d/%02d/%04d", month, day, year);
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
// Check if month is valid
if (month < 1 || month > 12) {
throw new IllegalArgumentException(
String.format("%02d is not a valid month", month)
);
} else {
this.month = month;
}
}
public int getYear() {
return year;
}
public void setYear(int year) {
// Check if year is valid
if (year < 1900 || year > 2020) {
throw new IllegalArgumentException(
String.format("%04d is not a valid year", year)
);
} else {
this.year = year;
}
}
public int getDay() {
return day;
}
public void setDay(int day) {
// Check if day is valid
if (day < 1 || day > getMaxNumDaysInMonth(this.getMonth(), this.getYear())) {
throw new IllegalAccessException(
String.format("%02d is not a valid day", day)
);
} else {
this.day = day;
}
}
Date(int month, int day, int year) {
setMonth(month);
setYear(year);
setDay(day);
}
private final int[] MAX_MONTH_DAYS = {
0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
/**
* Gets the maximum number of days in a month
* Depends on the month and whether the year is a leap year
* #param month
* #param year
* #return
*/
private int getMaxNumDaysInMonth(int month, int year) {
// Check if date is valid
if (year < 1 || month < 1 || month > 12) {
throw new IllegalArgumentException(
String.format("%04d-%02d is not a valid date", year, month)
);
} else {
// Adjust February if year is a leap year
if (month == 2) {
if (isLeapYear(year)) {
return MAX_MONTH_DAYS[month];
} else {
return MAX_MONTH_DAYS[month] - 1;
}
} else {
return MAX_MONTH_DAYS[month];
}
}
} // end getNumDaysInMonth
/**
* Returns true if year is a Leap year
* Returns false otherwise
* #param year
* #return
*/
private boolean isLeapYear(int year) {
return (year % 4) == 0 && (year % 100 !=0 || year % 400 == 0);
}
} // end Date class
Argument validation is always a great idea, there are actually classes dedicated to do this kind of thing for you as well to make it even easier.
Preconditions
public void setMonth(int month) {
Preconditions.checkArgument(month >= 1 && month <= 12, String.format("%s is not a valid month.", month));
this.month = month.
}
On an unrelated note regarding mutability
If you want this class to be immutable but still allow for methods like setMonth you can always make the fields final and return a new Date with the new month for example.
class Date {
private final int month;
private final int day;
private final int year;
// constructor
public Date setMonth(int month) {
// check argument is valid
return new Date(day, month, year);
}
}
Date date = new Date(2020, 3, 7);
date = date.setMonth(4);
Did you know this has already been done?
Do you need to create a class that manages Date? This already exists, and has been vastly improved in the last few years.
LocalDate localDate = LocalDate.now();
localDate = localDate.withMonth(4).withDayOfMonth(8).withYear(2021);
LocalDateTime localDateTime = LocalDateTime.now();
localDateTime = localDateTime.withHour(9).withMinute(45).withSecond(30).withDayOfMonth(8);
ZonedDateTime zonedDateTime = ZonedDateTime.now();
zonedDateTime = zonedDateTime.withZoneSameLocal(ZoneId.of("UTC"));
As mentioned by #Jason consider creating an immutable class. Right now your implementation is not safe. Users can break your class invariant by using different 'set' methods on already existing instance. For example, create a date of January, 31. Then set month to February. Because you only check for valid month there the resulting date will be 31 of February. Same for 29 Feb 2020 and change year to 2019.
If your class is immutable then you just need to place all validity checks inside a constructor and don't need to worry about preserving the class invariants in all 'set' methods.
Interesting question. Here's my thought: your object really only has one state variable: a date. That you must set that state variable by providing three separate numbers is a detail of your implementation.
Your validation should reject any attempt to set the state variable to some bogus value.
If you had a class with more than one state variable, it would be helpful to your users to validate them independently. But not for a date.

How to add n days to a Date in java without importing Date/Calendar from java API?

How do I add n days to a date in Java Creating my own java class?
For example, my date is (dd/mm/yyyy) = 26/02/2014
Adding 3 days, the output should be 01/03/2014.
Without importing Calendar or Date from JAVA API
Thank you in Advance. Any Sample code or Pseudo Code or idea will be highly apprecited
Convert the date to days. For example how many days passed from 01/01/1900 then add 3 days and convert it back.
This was one of my interview question, I had return the below code on paper may be my bad luck :-( I didn't get selected in that round, may be interviewer was not able to understand :-) :-).
I just searched to see is there any better way of doing it but I didn't, so I wrote same code what I had written on paper but its working like charm. Hope fully my confidence remains same :-) :-)
Hope this help you or some body.
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
public class MyDate
{
private static final Map<Integer, Integer> daysInMonth;
static
{
daysInMonth = new HashMap<Integer, Integer>();
daysInMonth.put(1, 31);
daysInMonth.put(2, 28);
daysInMonth.put(3, 31);
daysInMonth.put(4, 30);
daysInMonth.put(5, 31);
daysInMonth.put(6, 30);
daysInMonth.put(7, 31);
daysInMonth.put(8, 31);
daysInMonth.put(9, 30);
daysInMonth.put(10, 31);
daysInMonth.put(11, 30);
daysInMonth.put(12, 31);
}
private int day;
private int month;
private int year;
private int amount;
public MyDate(int day, int month, int year)
{
this.day = day;
this.month = month;
this.year = year;
}
public MyDate addOrSubDays(int amount)
{
this.amount = amount;
return addOrSubDays(this.day + this.amount, this.month, this.year);
}
public static void main(String[] args)
{
int amount = 650;
MyDate myDate = new MyDate(21, 5, 2016);
MyDate addOrSubDays = myDate.addOrSubDays(amount);
System.out.println(addOrSubDays.getDay() + "-" + addOrSubDays.getMonth() + "-" + addOrSubDays.getYear());
// Testing
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, amount);
System.out.println(cal.getTime());
}
private MyDate addOrSubDays(int days, int month, int year)
{
if (days > 0 && days <= getNoOfDaysInMonth(month, year))
{
return new MyDate(days, month, year);
}
else if (days <= 0)
{
month = month - 1;
if (month == 0)
{
month = 12;
year = year - 1;
}
days = getNoOfDaysInMonth(month, year) + days;
}
else
{
month = month + 1;
if (month > 12)
{
month = 1;
year = year + 1;
}
days = days - getNoOfDaysInMonth(month, year);
}
return addOrSubDays(days, month, year);
}
private int getNoOfDaysInMonth(int month, int year)
{
if (month == 2 && checkIsLeepYear(year))
{
return daysInMonth.get(month) + 1;
}
return daysInMonth.get(month);
}
private boolean checkIsLeepYear(int year)
{
if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)))
{
return true;
}
return false;
}
public int getDay()
{
return day;
}
public int getMonth()
{
return month;
}
public int getYear()
{
return year;
}
public int getAmount()
{
return amount;
}
}
Since everyone is putting their Date class here, I'll post mine.
Here are test results.
Jun 12, 2014 + 10 days -> Jun 22, 2014
Jun 12, 2014 + 20 days -> Jul 2, 2014
Dec 15, 2014 + 20 days -> Jan 4, 2015
Dec 15, 1955 + 30 days -> Jan 14, 1956
Dec 15, 1955 - 30 days -> Nov 15, 1955
Dec 15, 1955 + 16 days -> Dec 31, 1955
Dec 15, 1955 + 17 days -> Jan 1, 1956
Dec 15, 1955 + 80 days -> Mar 4, 1956
Dec 15, 1956 + 80 days -> Mar 5, 1957
Mar 5, 1957 - 80 days -> Dec 15, 1956
Mar 5, 1956 - 80 days -> Dec 16, 1955
And here's the code. I formatted my dates in a month, day, year format. You can change the getFormattedOutput method to be in a day, month, year format.
package com.ggl.testing;
import java.security.InvalidParameterException;
public class Date {
private static final boolean DEBUG = false;
private static final int BASE_MONTH = 1;
private static final int BASE_YEAR = 1700;
private int days;
public Date(int month, int day, int year) {
setDate(month, day, year);
}
public void setDate(int month, int day, int year) {
if ((month >= 1) && (month <= 12)) {
} else {
String s = "Month not between 1 and 12";
throw new InvalidParameterException(s);
}
if (year >= BASE_YEAR) {
int temp = calculateMonthDays(month, year);
if ((day >= 1) && (day <= temp)) {
} else {
String s = "Day not between 1 and " + temp;
throw new InvalidParameterException(s);
}
int days = calculateYearDays(year);
if (DEBUG) {
System.out.println(days);
System.out.println(temp);
}
days += temp;
this.days = days + day;
if (DEBUG) {
System.out.println(day);
System.out.println(this.days);
}
} else {
String s = "Year before " + BASE_YEAR;
throw new InvalidParameterException(s);
}
}
public int[] getDate() {
int days = this.days;
if (DEBUG)
System.out.println(days);
int year = BASE_YEAR;
int decrement = daysInYear(year);
while (days > decrement) {
days -= decrement;
decrement = daysInYear(++year);
}
if (DEBUG)
System.out.println(days);
int month = BASE_MONTH;
decrement = daysInMonth(month, year);
while (days > decrement) {
days -= decrement;
decrement = daysInMonth(++month, year);
}
if (DEBUG)
System.out.println(days);
int day = days;
int[] result = new int[3];
result[0] = month;
result[1] = day;
result[2] = year;
return result;
}
public String getFormattedDate() {
String[] months = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec" };
int[] fields = getDate();
return String.format("%s %d, %d", months[fields[0] - 1], fields[1],
fields[2]);
}
public void addDays(int increment) {
this.days += increment;
}
private int calculateMonthDays(int month, int year) {
int days = 0;
for (int i = BASE_MONTH; i < month; i++) {
days += daysInMonth(i, year);
}
return days;
}
private int calculateYearDays(int year) {
int days = 0;
for (int i = BASE_YEAR; i < year; i++) {
days += daysInYear(i);
}
return days;
}
private int daysInMonth(int month, int year) {
int[] days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month == 2) {
if (daysInYear(year) > 365) {
return days[month - 1] + 1;
}
}
return days[month - 1];
}
private int daysInYear(int year) {
int days = 365;
if ((year % 4) == 0) {
if ((year % 100) == 0) {
if ((year % 400) == 0) {
days++;
}
} else {
days++;
}
}
return days;
}
public static void main(String[] args) {
Date date = new Date(6, 12, 2014);
displayResult(date, 10);
date = new Date(6, 12, 2014);
displayResult(date, 20);
date = new Date(12, 15, 2014);
displayResult(date, 20);
date = new Date(12, 15, 1955);
displayResult(date, 30);
date = new Date(12, 15, 1955);
displayResult(date, -30);
date = new Date(12, 15, 1955);
displayResult(date, 16);
date = new Date(12, 15, 1955);
displayResult(date, 17);
date = new Date(12, 15, 1955);
displayResult(date, 80);
date = new Date(12, 15, 1956);
displayResult(date, 80);
date = new Date(3, 5, 1957);
displayResult(date, -80);
date = new Date(3, 5, 1956);
displayResult(date, -80);
}
private static void displayResult(Date date, int increment) {
String sign = "";
int display = 0;
if (increment > 0) {
sign = " + ";
display = increment;
} else {
sign = " - ";
display = -increment;
}
System.out
.print(date.getFormattedDate() + sign + display + " days -> ");
date.addDays(increment);
System.out.println(date.getFormattedDate());
}
}
try this
class Date {
static int[] daysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int m;
int d;
int y;
Date(String date) {
// parse and get int fields
}
Date(int d, int m, int y) {
this.d = d;
this.m = m;
this.y = y;
}
int maxDays() {
int md = daysInMonth[m - 1];
// correction for Feb
return md;
}
Date addDays(int n) {
int d = this.d += n;
int m = this.m;
int y = this.y;
while (d > maxDays()) {
d = d - maxDays();
m++;
if (m > 12) {
y++;
m = 1;
}
}
return new Date(d, m, y);
}
}
note that code may need fixing
class DateCalculator{
private int[] normalYear = {31,28,31,30,31,30,31,31,30,31,30,31};
private int[] leapYear = {31,29,31,30,31,30,31,31,30,31,30,31};
public String calculateDate(String date, int numberOfDays){
String[] date_parts = date.split("/");
int year = Integer.parseInt(date_parts[2]);
int month = Integer.parseInt(date_parts[1]);
int day = Integer.parseInt(date_parts[0]);
int days = numberOfDays;
int[] refYear = getRefYear(year);
while(true){
int diff = days - (refYear[month - 1] - day);
if(diff > 0 ){
days = diff;
month++;
day = 0;
if(month <= 12){
continue;
}
}else{
day = day + days;
break;
}
year++;
month = 1;
refYear = getRefYear(year);
}
StringBuilder finalDate = new StringBuilder();
finalDate.append(day);
finalDate.append("/");
finalDate.append(month);
finalDate.append("/");
finalDate.append(year);
return finalDate.toString();
}
private int[] getRefYear(int year){
return isLeapYear(year)? leapYear : normalYear;
}
private boolean isLeapYear(int year){
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ){
return true;
}
return false;
}
}
Question: increase or update given date by certain days, without using calendar or date class?
Answer: I verified first ex and that seems like good a reference for storing values in maps (as days for months are fixed).
My solution is below and it is working correctly, when I tested.
Solution code:
import java.util.*;
public class IncreaseDate {
private static final Map<Integer, Integer> date;
static {
date= new HashMap<Integer,Integer>();
date.put(1,31);
date.put(2,28);
date.put(3,31);
date.put(4,30);
date.put(5,31);
date.put(6,30);
date.put(7,31);
date.put(8,31);
date.put(9,30);
date.put(10,31);
date.put(11,30);
date.put(12,31);
}
public static void main(String args[]) {
IncreaseDate id= new IncreaseDate();
System.out.println("2/5/2018 "+"+"+60+" : ");
id.updateDate(2,5,2018,60);
}
public void updateDate(int m,int d, int y, int days) {
int temp=date.get(m);
// for finding leap year
if(m==2 && (y%4==0 && y%100!=0 && y%400!=0)) {
temp= date.get(m)+1;
}
if(d+days>temp) {
if(m<=11) {
updateDate(m+1,d,y,days-temp);
}
else {
updateDate(1,d,y+1,days-temp);
}
}
else {
System.out.println("Upadate Date: "+m+"/"+(d+days)+"/"+y);
}
}
}
Points to remember:
We are updating months and years and decreasing days until it becomes less than that month days.
Calendar class is abstract class, so we cant create object directly. But we can create using getInstance() factory method.
package StringProgram;
public class AddingDaystoDate {
public static String addDays(String date, int n)
{
int[] daysInNormalYear={31,28,31,30,31,30,31,31,30,31,30,31};
int[] daysInLeapYear={31,29,31,30,31,30,31,31,30,31,30,31};
String[] sArray=date.split("/");
int dd=Integer.valueOf(sArray[0]);
int mm=Integer.valueOf(sArray[1]);
int yy=Integer.valueOf(sArray[2]);
String updatedDate="";
if(calculateLeapYear(yy)==true)
{
int maxDayinMonth=daysInLeapYear[mm-1];
dd=dd+n;
if(dd>maxDayinMonth)
{
dd=dd-maxDayinMonth;
mm++;
if(mm>12)
{
yy++;
mm=1;
}
}
updatedDate=new String(""+dd+"/"+mm+"/"+yy);
}
else
{
int maxDayinMonth=daysInNormalYear[mm-1];
dd=dd+n;
if(dd>maxDayinMonth)
{
dd=dd-maxDayinMonth;
mm++;
if(mm>12)
{
yy++;
mm=1;
}
}
updatedDate=new String(""+dd+"/"+mm+"/"+yy);
}
return updatedDate;
}
public static boolean calculateLeapYear(int year)
{
if(year%4==0)
{
if(year%100==0)
{
if(year%400==0)
{
return true;
}
}
return false;
}
return false;
}
public static void main(String[] args) {
String date="27/12/2014";
String s=addDays(date,5);
System.out.print(s);
}
}
simple code for add or sub using method
public Date1(int d, int m, int y) {
this.day = d;
this.month = m;
this.year = y;
}
public void addDay() {
month--;
Calendar m = Calendar.getInstance();
m.set(year, month, day);
m.add(day, 5); // if you want add or sub month or year it depend on days
java.sql.Date d = new java.sql.Date(m.getTimeInMillis());
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
System.out.println(" date is " + df.format(d));

Validation issue With Date Program

I have to validate the date,For example If I enter 31/2/2013,It should give an error as February doesn't contains 31 days,but I am stuck at how to achieve that,I tried to use the switch statement but still in vain.Help would be much appreciated.
public class Date
{
private int PDay;
private int PMonth;
private int PYear;
public Date(int day,int month,int year)
{
setDay(day);
setMonth(month);
setYear(year);
}
public Date(int month,int year)
{
this(1,month,year);
}
public Date(int year)
{
this(1,1,year);
}
public void setDay(int day)
{
PDay=day;
}
public int getDay()
{
return PDay;
}
public void setMonth(int month)
{
if(month>=1 && month<=12)
PMonth=month;
else
System.out.println("Month Invalid-Must be Between 1 & 12");
}
public int getMonth()
{
return PMonth;
}
public void setYear(int year)
{
if(year>=1950 && year<=2049)
PYear=year;
else
System.out.println("Year Invalid-Must be Between 1950 & 2049");
}
public int getYear()
{
return PYear;
}
public String toString()
{
return PDay+"/"+PMonth+"/"+PYear;
}
}
P.S. Its not Homework :P/>
Test Program is:
public class DateTest
{
public static void main(String[] args)
{
Date newDate = new Date(7,14,2012);
Date newDate1 = new Date(2152);
System.out.println(newDate);
System.out.println(newDate1);
}
}
In the constructor, set the day after the year and month:
public Date(int day, int month, int year) {
setYear(year);
setMonth(month);
setDay(day);
}
And in the method setDay() add the validation logic:
public void setDay(int day) {
if (pMonth == 1 && (day < 1 || day > 31)) {
// throw exception or handle error
throw new IllegalArgumentException("invalid number of days");
} else if (pMonth == 2 && (day < 1 || day > 28)) {
// same thing
}
// ... rest of validations
PDay = day;
}
If you want to be even more strict, you can use the year to determine if February has 28 or 29 days.
EDIT: Don't implement date handling on your own as long as there are existing frameworks fitting your needs.
But beware of the pitfalls of some of the existing frameworks: (end of EDIT)
Don't use java.util.Date for such checks. Nearly all of the methods of Date are buggy and have been declared as deprecated. Those setters and getters have been reimplemented in the java.util.Calendar classes. But since they are still buggy in some circumstances the best choice would be to use the new Date Time API of Java 8 if this is an option or to use the "third-party" Jodatime library for correct date handling.
If you just want to have some checks on input, then you may use java.text.SimpleDateFormat that handles the parsing and the checks.

Can anyone please help me solve this?? (solving year 2000 with java) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a project in school to solve year 2000 with java. here is the description of the assignment:
Create a Date object with the following:
attribute: a julian date representing the number of days since Jan 1, 1501 (the epoch date for this project) - this should be a private member variable of the class with the associated accessor and mutator methods.
constants: a suitable constant for each month
a suitable contant for each component of the epoch date
method: Date(long year, long month, long day) that converts the given year, month, and day to the julian date.
method: a method that converts a year, month, and day into the number of days since the project's epoch date.
method: a method that determines if a given year is a leap year
method: a method that returns the number of days in a given year; replace the current simple if statement with a single statement using the conditional operator (? :)
method: a method that returns the number of days in a given month of a given year; method should implement a switch statement using appropriate constants.
methods: any of the other methods developed in class should probably also be included.
method: returnYear() a method that determines the year component of the julian date value
method: returnMonth() a method that determines the month component of the julian date value
method: returnDay() a method that determines the day component of the julian date value
method: returnMonthName() a method that returns the name of the given month ( if month = JAN return "January" (use a switch statement))
method: returnDate() a method that returns the date in the format monthName day, year
class: Utility containing two query methods.
And here is the code I came with so far.. it is not compiling because there is something wrong with the switch!
import java.util.Scanner;
class Date
{
public final static long EPOCHYEAR = 1501;
private long julianDate;
Date(long year, long month, long day)
{
julianDate = returnTotalJulianDay(year, month, day);
System.out.println("Days is " + julianDate);
}
boolean isLeapYear(long year)
{
boolean answer;
if(year % 4 == 0 && (year % 4 == 0 || year % 100 != 0))
{
answer = true;
}
else
{
answer = false;
}
return answer;
}
long returnDaysInMonth(long year, long month)
{
if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
{
return 31;
}
else if(month == 4 || month == 6 || month == 9 || month == 11)
{
return 30;
}
else if(isLeapYear(year))
{
return 29;
}
else
{
return 28;
}
}
long returnJulianDate(long year, long month, long day)
{
long julianDate;
long monthCounter;
julianDate = 0;
monthCounter = 1;
while(monthCounter < month)
{
julianDate += returnDaysInMonth(year, monthCounter);
monthCounter += 1;
}
julianDate += day;
return julianDate;
}
long returnTotalJulianDay(long year, long month, long day)
{
long totalJulianDay = 0;
long yearCounter = 1;
while(yearCounter < year)
{
totalJulianDay += returnJulianDate(year, month, yearCounter);
yearCounter += 1;
}
return totalJulianDay;
}
long returnDaysInYear(long year)
{
final long DAYSINYEAR = 365;
if(isLeapYear(year))
{
return 366;
}
else
{
return DAYSINYEAR;
}
}
long returnJulianEpochDays(long year, long month, long day)
{
long yearCounter = EPOCHYEAR;
long total = 0;
while(yearCounter < year)
{
total += returnDaysInYear(yearCounter);
yearCounter += 1;
}
total += returnJulianDate(year, month, day);
return total;
}
long returnYear()
{
long dayCounter = 0;
long yearCounter = EPOCHYEAR;
for(dayCounter = this.julianDate; dayCounter > returnDaysInYear(yearCounter); yearCounter++)
{
dayCounter -= returnDaysInYear(yearCounter);
}
return yearCounter;
}
long returnMonth()
{
long julianEpochDays = julianDate;
long yearCounter = EPOCHYEAR;
long monthCounter = 1;
while(julianEpochDays > returnDaysInYear(yearCounter))
{
julianEpochDays -= returnDaysInYear(yearCounter);
yearCounter++;
}
while(julianEpochDays > returnDaysInMonth(yearCounter, monthCounter))
{
julianEpochDays -= returnDaysInMonth(yearCounter, monthCounter);
monthCounter++;
}
return monthCounter;
}
long returnDay()
{
long julianEpochDays = julianDate;
long yearCounter = EPOCHYEAR;
long monthCounter = 1;
while(julianEpochDays > returnDaysInYear(yearCounter))
{
julianEpochDays -= returnDaysInYear(yearCounter);
yearCounter++;
}
while(julianEpochDays > returnDaysInMonth(yearCounter, monthCounter))
{
julianEpochDays -= returnDaysInMonth(yearCounter, monthCounter);
monthCounter++;
}
return julianEpochDays;
}
long returnMonthName()
{
int month = 0;
final int JAN = 1;
final int FEB = 2;
final int MAR = 3;
final int APR = 4;
final int MAY = 5;
final int JUN = 6;
final int JUL = 7;
final int AUG = 8;
final int SEP = 9;
final int OCT = 10;
final int NOV = 11;
final int DEC = 12;
switch(month)
{
case JAN:
return "January";
case FEB:
return "Febuary";
case MAR:
return "March";
case APR:
return "April";
case MAY:
return "May";
case JUN:
return "June";
case JUL:
return "July";
case AUG:
return "August";
case SEP:
return "September";
case OCT:
return "October";
case NOV:
return "November";
case DEC:
return "December";
}
}
}
class utility
{
public char queryForCharacter(String prompt)
{
int typedCharacter = ' ';
try
{
System.out.print(prompt);
typedCharacter = System.in.read();
}
catch(Exception e)
{
}
return (char) typedCharacter;
}
public static long queryForLong(String prompt)
{
Scanner keyboard;
long theNumber;
keyboard = new Scanner(System.in);
System.out.print(prompt);
theNumber = keyboard.nextInt();
return theNumber;
}
}
public class DateDriver
{
public static void main(String[] args)
{
Date aTestDate = null;
aTestDate = new Date(1502, 1, 1);
}
}
Your method returnMonthName() is declared to return a long, but the switch cases return Strings.
Also, the method needs to return something if none of the cases in the switch match.
Your function returns a type of long:
"long returnMonthName() {"
But your are returning a type of "String". i.e. "January".

Categories

Resources