본문 바로가기

IT/Java

Java로 달력(Calendar) 구현하기

/* 
written by kaspy (kaspyx@gmail.com)
*/ 

아래는 Java로 달력을 구현한 소스코드이다. 2개파일로 나뉘었고, 주석에 자세한 설명을 해놨으니 복붙해서 봐도될듯하다.
1980년 1월 1일(화요일)을 기준으로 지정해준 날짜까지(윤년 포함) 총합을 계산한다 그리고 7로 나눠서 요일을 구한다. 끝

Calender.java

  1. public class Calender {
  2.                                         //미리 기준 연도와 , 기준월을 정해서 출력하는 방법을 선택함.
  3.  
  4.         int base_year = 1980;           // 기준 연도
  5.         int base_month = 1;             // 기준 월 입니다. 실제로는 1980년 1월 1을 기준으로 계산
  6.         int total_sum = 0;              // 기준 년과 월에서 입력받은 날짜까지 총 일수를 여기에 저장
  7.  
  8.         int[] month_table = new int[] { 312831303130313130313031}; //각 월마다 총 일수
  9.        
  10.         public int is_leap_year(int n)  {       //윤년이 있는 년도를 조사하는 함수입니다. 윤년인경우는 1
  11.  
  12.                         if ( n % 4 == 0){       //4의 배수는 윤년
  13.  
  14.                                 if ( n % 100 == 0 ) // 그런데 100의 배수는 윤년이 아님
  15.                                 {
  16.                                         if ( n % 400 == 0 )     //그중에서 400의 배수는 윤년
  17.                                                 return 1;
  18.        
  19.                                         return 0;
  20.                                 }
  21.        
  22.                         return 1;
  23.                 }
  24.                
  25.                 else
  26.                         return 0;
  27.  
  28.         }
  29.  
  30.  
  31.         public int total_to_month(int total)    // 기준 날짜부터 입력받은 날짜까지 총 일수를 구해서 반환,
  32.         {
  33.        
  34.                 boolean CHK = false;            // 무한 루프를 돌리기위한 불리안 값입니다.
  35.                 int i=0;                        // i변수는 월입니다.
  36.                 int cnt=0;                      // 총 일수를 월로 바꾸어서 cnt 저장시킵니다.
  37.                 int chk_leap_year = base_year;  // 총 일수를 월로 바꾸려면 윤년이 있는 날을 고려해야합니다.
  38.                                                 // 기준연도부터 시작해서 윤년을 조사합니다.
  39.                
  40.  
  41.                 while (CHK!=true)
  42.                 {
  43.                         if ( is_leap_year(chk_leap_year) == 1)  //만약 지금 연도가 윤년이라면
  44.                                 month_table[1] = 29;            //2월달은 하루가 더 늘어납니다.
  45.                
  46.        
  47.                         if ( total >= month_table[i] )         // 총 일수가 month_table[]배열의 총일수 보다 작다면,
  48.                         {
  49.                                 total -= month_table[i++]// 총일수를 month_table 배열의 현재 월의 일수로 빼줍니다.
  50.                                                                 // 그리고 i를 증가시킵니다. 즉 다음달로 증가됩니다.
  51.                                 cnt++;                          // 그리고 월이 증가합니다.
  52.                                 if (i==12)                  // 만약 12월이된다면 계절이 변해 다시 제자리로 오는것처럼
  53.                                 {
  54.                                         i-=12;              // 다시 12를빼서 0으로 만들어줍니다.
  55.                                         chk_leap_year++;    //그리고 12개월이 지났으니 연도도 증가시켜줘야함
  56.                                 }
  57.  
  58.                                 month_table[1]= 28;             //윤년을 평년의 해로 바꾸어주어야합니다.
  59.                                
  60.                         }
  61.  
  62.                         else break;
  63.  
  64.                 }
  65.  
  66.                 cnt%=12;        // 위의 무한루프를 통해 총일수를 총월수로 계산됨, 이제 12 나머지 연산을 해주면
  67.                                 // 몇년도 몇월이라는 값으로 바꿀수있습니다.
  68.  
  69.                 return  (cnt+1);        // 그리고 바꾼 월을 반환
  70.  
  71.         }
  72.  
  73.         public int count_leap(int n)            // 기준 연도부터 시작해서 입력받은 연도까지의 윤년이 있는날을 셉니다.
  74.         {
  75.                 int i;          //기준연도를 저장합니다.
  76.                 int cnt=0;      // 윤년의 개수입니다.
  77.  
  78.                 for (i=base_year ; i < (base_year-n) ; i++)
  79.                 // i(기준연도) 부터 입력받은 연도까지 i를 증가시키며 윤년이낀 갯수를 구함.
  80.                 {
  81.  
  82.                         if ( is_leap_year(i) == 1 )     //위에서 구현한 윤년인지를 판단하는 함수를 사용
  83.                         {
  84.                                 cnt++;                  // 윤년이라면 총 윤년의 개수를 증가시킵니다.
  85.                         }
  86.                
  87.                 }
  88.  
  89.                 return cnt;             //카운트한 윤년의 갯수를 리턴합니다.
  90.  
  91.         }
  92.  
  93.         public void convert_to_day(int nYear) {         // 기준 연도부터 입력받은 연도까지 총일수를 구해서 리턴합니다.
  94.                 total_sum  =(( nYear - base_year) * 365)+count_leap((base_year-nYear));
  95.         }
  96.                

  97.         void result(int nYear, int mth)
  98.         {
  99.                 int i,j;                // 카운트를 위한 변수입니다.
  100.                 int d=0;               
  101.                 int year=0;
  102.                 int month;
  103.                 int sum=0;
  104.  
  105.                 int dy = count_leap(base_year-nYear);   //dy는 기준연도부터 현재연도까지 낀 윤년의 갯수입니다.
  106.                 convert_to_day(nYear);  // ★ 우선 기준연도부터 현재 연도까지 년 단위로 총일수를 구합니다. ★
  107.  
  108.                 int day;        // 이변수는 요일을 결정하기위해 존재합니다.예를들어 기준일부터 현재일까지 차이가 7이고
  109.                                 // 기준일이 월요일이면 7로 나눠서 나머지가 0이되니까 월요일임을 알수 있듯이
  110.                                 // day는 숫자로서 요일을 결정할수있습니다.
  111.                 if ( nYear >= base_year)
  112.                 {
  113.  
  114.                         if ( is_leap_year(nYear) == 1)          //윤달이 낀날의 2월은 하루 증가
  115.                                         month_table[1] = 29;
  116.                
  117.                         for ( i =0; i < (mth - base_month ) ;i++)              
  118.                                         total_sum += month_table[i];
  119.                                         // 위에 ★ 에서 기준연도부터 현재연도까지의 일수를 구했습니다.
  120.                                         // 이 for루프를 통해 나머지 기준월부터 현재월까지의 총일수를 구합니다.     
  121.                                         // 즉 이루프를 통해 기준 연도와 월부터 현재 연도와 월까지의 총일수를 구함.
  122.                
  123.                         day = (total_sum+2) % 7;
  124.                       // 현재까지의 총일수를 7의 나머지로 연산해줍니다. 2를 더해준 이유는 1980년도 1월 1일 = 화요일

  125.                         System.out.println("총 일수 = "+total_sum+"윤달이 낀 숫자 = " +dy);
  126.                         month = total_to_month(total_sum); // 입력받은 해당 날짜의 정확한 달을 구해서 저장합니다.
  127.  
  128.                         System.out.println(+month+" 월의 달력");
  129.  
  130.                         System.out.println("일 월     화     수     목     금     토");
  131.  
  132.                         for ( i = 0; i <  day; i++) //day 변수는 요일 입니다. 갯수만큼 \t로 공백을 만들어줍니다.
  133.                                 System.out.print("\t");
  134.  
  135.                         for ( j = 1 ; j <= month_table[month-1]; j++)  
  136.                         // month변수에서 1을 빼준이유는 배열은 0부터 시작하기때문입니다.
  137.                         {                                              
  138.                                 System.out.print(j+"\t");// j를 증가시켜가며 차례데로 날짜를 출력합니다.
  139.  
  140.                                 if (((j+day) % 7) == 0 ) System.out.println(); 
  141.                                 // 그리고 처음 요일을 출력하기위한 공백만큼 계산해서 출력
  142.                         }
  143.  
  144.                         System.out.println();
  145.  
  146.                         month_table[1] = 28;    //윤년이었다면 다시 평년으로 바꾸어줍니다.
  147.  
  148.                 }
  149.         }
  150.  
  151. }


CalenderUser.java


  1. import java.util.Scanner;
  2.  
  3. public class CalenderUser {
  4.         public static void main(String args[])
  5.         {      
  6.                 int year,month;
  7.  
  8.                 Scanner s = new Scanner(System.in);
  9.                 Calender cldUser = new Calender();
  10.                 System.out.println("Year, Month");     
  11.                 year = s.nextInt();
  12.                 month = s.nextInt();// 연도와 월을 입력받습니다.
  13.                 cldUser.result(year,month); // cldUser클래스의 result함수에매개변수
  14.                                             // year, month를 넘겨주면 cldUser클래스가 결과를 출력합니다.
  15.         }
  16. }


컴파일 

javac Calender.java

javac CalenderUser.java


실행

java Calender


실행화면




'IT > Java' 카테고리의 다른 글

자바 리플렉션(Java Reflection)  (0) 2017.01.06
자바(Java)로 구현한 RSA 암호학 알고리즘 예제  (0) 2015.11.12