staticclassYMD{
int year;
int month;
int day;
YMD(int y, int m, int d) //생성자
{
this.year = y;
this.month = m;
this.day = d;
}
int[][] arr = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //평년 arr[0][]
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} //윤년 arr[1][]
};
staticintisLeap(int year){ //윤년이면 1을 리턴, 평년이면 0을 리턴return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 1 : 0;
}
YMD after(int n)//n일 후 날짜를 리턴하는 메소드{
YMD temp = new YMD(this.year, this.month, this.day);
if (n < 0)
return (before(-n));
temp.day += n;
while (temp.day > arr[isLeap(temp.year)][temp.month - 1]) {
temp.day -= arr[isLeap(temp.year)][temp.month - 1];
if (++temp.month > 12) {
temp.year++;
temp.month = 1;
}
}
return temp;
}
YMD before(int n)//n일 전 날짜를 리턴하는 메소드{
YMD temp = new YMD(this.year, this.month, this.day);
if (n < 0)
return (after(-n));
temp.day -= n;
while (temp.day < 1) {
if (--temp.month < 1) {
temp.year--;
temp.month = 12;
}
temp.day += arr[isLeap(temp.year)][temp.month - 1];
}
return temp;
}
}
실행예제
publicstaticvoidmain(String[] args){
Scanner sc = new Scanner(System.in);
System.out.print("날짜를 입력하세요. 입력 예 : 2023 1 18\n");
int y, m, d;
y = sc.nextInt();
m = sc.nextInt();
d = sc.nextInt();
YMD date = new YMD(y, m, d);
System.out.print("몇 일 앞/뒤의 날짜를 구할까요?:");
int n = sc.nextInt();
YMD d1 = date.after(n);
System.out.printf("%d일 뒤의 날짜는 %d년 %d월 %d일입니다.\n", n, d1.year, d1.month, d1.day);
YMD d2 = date.before(n);
System.out.printf("%d일 앞의 날짜는 %d년 %d월 %d일입니다.\n", n, d2.year, d2.month, d2.day);
}
/*
날짜를 입력하세요. 입력 예 : 2023 1 18
2023 1 18
몇 일 앞/뒤의 날짜를 구할까요?:1000
1000일 뒤의 날짜는 2025년 10월 14일입니다.
1000일 앞의 날짜는 2020년 4월 23일입니다.
*/
네이버 날짜 계산기는 기준일을 1일로 치지만 위 알고리즘은 기준일을 0일로 삼는다.
네이버는 내일을 2일째 되는날이라고 하지만, 위 알고리즘은 1일째 되는날이라고 한다.
설명
arr의 행에 오는 isLeap()메소드는 temp의 연도가 윤년이면 1, 평년이면 0을 리턴한다. 열에오는 temp의 month에 -1을 한 이유는 배열의 인덱스는 0부터 시작하기 때문이다. 2023.01.18에 1000일을 한 temp객체는 초기에 2023.01.1018로 되어있다. while루프는 temp의 day가 달의 일수보다 같거나 작을 때 까지 반복한다. day는 루프를 돌면서 계속 달의 일수만큼 감소된다. 달의 일수가 감소할 때, 달은 계속 증가하게 되고, 달이 12를 넘어가면 연도를 +1해준다.