[Java] 두 날짜 사이의 주차구하기

정나영·2021년 1월 1일
0

두 날짜 사이의 주차구하기.

주차를 세는 기준

일요일부터 토요일까지 1주라고 정의하고 특정한 두 날짜 사이의 주차를 세어보려한다.

이번주 월요일부터 금요일까지의 주차를 구할때는 두 날짜 사이의 일수가 7일이 되지않지만 주차를 세기때문에 총 주차는 1주차라고 정의한다.

이번주 목요일부터 다음주 월요일까지의 주차를 구한다면 두 날짜 사이의 일수가 14일이 되지않지만 총 주차는 2주차라고 정의한다.

이번주 목요일부터 다음주 목요일까지 주차를 구한다면 두 날짜 사이의 일수가 딱 7일이지만 주가 다르기 때문에 총 주차는 2주차라고 정의한다.

ex)
2021.01.03 ~ 2021.01.09 => 1주차
2021.01.04 ~ 2021.01.08 => 1주차
2021.01.07 ~ 2021.01.11 => 2주차
2021.01.07 ~ 2021.01.14 => 2주차

주차구하기

Calendar startDate = Calendar.getInstance();
Calendar endDate = Calendar.getInstance();
startDate.set(2021,Calendar.JANUARY, 7);
endDate.set(2021,Calendar.JANUARY,11);

int startDayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);
int endDayOfWeek = endDate.get(Calendar.DAY_OF_WEEK);

int periodWeek = 0;

while( !endDate.before( startDate ) ) {
	startDate.add( Calendar.DATE, 7);
	periodWeek++;
}
		
if(endDayOfWeek-startDayOfWeek < 0) {
	periodWeek = periodWeek + 1;
}
		
System.out.println(periodWeek);

Output
2

코드설명

Canlendar 객체에는 두 날짜 사이를 비교하는 함수가 존재한다.
before과 after라는 함수 중 나는 before을 이용하여 두 날짜를 비교했다.

Canlendar.before()

Java, Calendar의 before, after
{Calendar 개체}.before({비교대상})
이 기본 문법인데, 이것을 이해하는 방법은 애석하게도 미국인 식으로 생각해주어야 한다.
{Calendar 개체} before then {비교대상}
즉 저 before 라는 의미는 “{비교대상}보다 {Calendar 개체}가 이전 인가?”라는 의미와 같다.

before함수는 말 그대로 비교대상보다 Calendar개체가 더 과거이면 true를 반환하고 이후이면 false를 반환한다.

Calendar startDate = Calendar.getInstance();
Calendar endDate = Calendar.getInstance();
startDate.set(2021,Calendar.JANUARY, 7);
endDate.set(2021,Calendar.JANUARY,11);

System.out.println(endDate.before( startDate ));

Output
false

Canlendar.before()의 활용

startDateendDate를 비교해서 startDateendDate보다 과거이면 주차를 세고 startDate에 7일을 더하면서 다음 반복때 두 날짜를 비교해 주차를 또 셀지 안셀지를 정해주었다.

while( !endDate.before( startDate ) ) {
	startDate.add( Calendar.DATE, 7);
	periodWeek++;
}

문제점

Calendar startDate = Calendar.getInstance();
Calendar endDate = Calendar.getInstance();
startDate.set(2021,Calendar.JANUARY, 7);
endDate.set(2021,Calendar.JANUARY,11);

int periodWeek = 0;

while( !endDate.before( startDate ) ) {
	startDate.add( Calendar.DATE, 7);
	periodWeek++;
}

Output
1

우리는 지금 startDate의 요일이 이번주 목요일이고 endDate의 요일이 다음주 월요일일때 두 날짜 사이의 일수는 5일임에도 불구하고 주차 카운팅은 2번 되게끔 구현을 해야한다.
그러나 Canlendar.before()만 사용했을때 원하는대로 카운팅이 안되는 문제가 생긴다. 총 일수가 딱 7일이되야 한번 카운팅이 되어지고 딱 14일이 되어야 두번 카운팅이 되어지기 때문이다.

이를 해결하기 위해서는 두 날짜의 요일를 비교해야한다.
다음과 같이 startDate의 요일이 endDate의 요일보다 클때 주차를 한번 더 카운팅을 해주면 된다.

int startDayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);
int endDayOfWeek = endDate.get(Calendar.DAY_OF_WEEK);

if(endDayOfWeek-startDayOfWeek < 0) {
	periodWeek = periodWeek + 1;
}

다른 방법의 주차 구하기

이 방법으로 주차건 더 쉽다.
캘린더 객체를 이용하면 지정한 날짜가 해당년도의 몇째 주인지 알 수 있으므로 두 날짜의 주차를 구하고(WEEK_OF_YEAR) 서로 빼면 두 날짜 사이의 주차를 구할 수 있게 된다.
물론 위와 똑같은 문제점이 생기기때문에 요일비교를 해주어 +1을 해줘야한다.

int startWeekOfYear = startDate.get(Calendar.WEEK_OF_YEAR);
int endWeekOfYear = endDate.get(Calendar.WEEK_OF_YEAR);
int startDayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);
int endDayOfWeek = endDate.get(Calendar.DAY_OF_WEEK);
int periodWeek = endsWeekOfYear-startWeekOfYear;

if(endDayOfWeek-startDayOfWeek < 0) {
	periodWeek = periodWeek + 1;
}

하지만 이 방법으로 주차를 구하기엔 한계가 있다. 두 날짜의 연도가 다르면 음수가 나오기 때문이다.

위 코드를 보완해서 연도가 다르더라도 주차가 계산되게끔 하면되지않을까 싶었지만 머리가 안돌아간다..ㅎㅎ

연도가 다를땐 제일 처음에 적었던 방법으로..ㄱㄱ

두 날짜의 연도가 서로 다를 때 예시

Calendar startDate = Calendar.getInstance();
Calendar endDate = Calendar.getInstance();
startDate.set(2020,Calendar.DECEMBER, 28);
endDate.set(2021,Calendar.JANUARY,11);

int startDayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);
int endDayOfWeek = endDate.get(Calendar.DAY_OF_WEEK);

int periodWeek = 0;

while( !endDate.before( startDate ) ) {
	startDate.add( Calendar.DATE, 7);
	periodWeek++;
}
		
if(endDayOfWeek-startDayOfWeek < 0) {
	periodWeek = periodWeek + 1;
}
		
System.out.println(periodWeek);

Output
3

글을 마치며...

지금 진행하는 프로젝트에서 주차를 구하는 코드를 구현해야할 거같아서 미리 연습겸 코드를 짜봤다

그리고 새삼 느끼는 거는 진짜 말 못한다.. 글 못쓴다.. 라는 것이다...
어쩌다보니 두괄식의 글이 되어버렸다..ㅋㅋㅋ의도한게 아니었는데ㅋㅋ
글 계속 쓰다보면 언젠간 늘겠지...?ㅠㅠ

참고

[Java/jsp] 자바로 구현한 삼성 주차(오늘이 올해의 몇주차인지) 관리하는 Util

profile
I can do it!

0개의 댓글