'자바 법정공휴일 소스'에 해당되는 글 1건

728x90

자바(Java) 음력 일자 변환 라이브러리 설치법은 https://link2me.tistory.com/1695 를 참조하면 된다.

음력에 대한 자세한 내용을 알고 싶다면 http://oops.org/project/manse/https://github.com/OOPS-ORG-PHP/Lunar 를 읽어보면 도움이 될 것이다. 고영창 씨께서 고생해서 자료와 알고리즘을 만들었던 거 같다.

음력 앱, 프로그램 등을 테스트하다보면 음력일자가 약간 틀리게 나오는 경우도 있다. 정확한 데이터를 기준으로 해야 하는데, 데이터의 기준이 이것이 정확하다고 하는 걸 찾는게 어려운 거 같다.

음력 데이터를 MySQL 버전으로 DB화를 해 놓은 걸 SQLite 로 포팅하는 걸 시도해봐야 하나 고민되기도 한다.


자바(Java)에서 사용하는 라이브러리가 맞다는 가정하에 이 코드를 기준으로 음력과 양력을 변환하여 법정공휴일 처리를 하도록 했다. 음력을 지원하는 앱을 실행해보면서 2019년도 추석, 설 데이터, 어린이날 대체공휴일 등이 맞는 걸로 봐서 음력 데이터가 정확한 거 같아서 아래 코드를 노가다 수준으로 구현해서 테스트 했다.


법정공휴일 처리를 위해서 Holidays Class 를 만들었다.

ArrayList를 사용해서 입력 연도에 해당되는 법정공휴일 처리를 하려고 한다.

public class Holidays implements Comparable<Holidays>{
    // ArrayList의 type이 Comparable을 implements한 경우에만 sort 메소드의 정렬 기능을 사용할 수 있다
    private String year; // 연도
    private String date; // 월일
    private String name; // 휴일 명칭

    public Holidays() {
    }

    public Holidays(String year, String date, String name) {
        this.year = year;
        this.date = date;
        this.name = name;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int compareTo(Holidays o) {
        return this.date.compareTo(o.date);
    }
}


이제 법정공휴일 양력과 음력을 처리할 ArrayList<Holidays> holidayArray(String yyyy) 메소드를 만들었다.

ArrayList return 메소드 만드는 예제는 https://link2me.tistory.com/1698 를 참조하면 된다.

사용법은 ArrayList<Holidays> arr = LunarCalendar.holidayArray("2019"); 로 결과를 얻어서 처리하면 된다.

import com.ibm.icu.util.ChineseCalendar;
import com.tistory.link2me.item.Holidays;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;

public class LunarCalendar {
    static ArrayList<Holidays> holidaysArrayList = new ArrayList<>();

    /**
     * 음력날짜를 양력날짜로 변환
     * @param 음력날짜 (yyyyMMdd)
     * @return 양력날짜 (yyyyMMdd)
     */
    public static String Lunar2Solar(String yyyymmdd) {
        ChineseCalendar cc = new ChineseCalendar();
        Calendar cal = Calendar.getInstance();

        if (yyyymmdd == null)
            return "";

        String date = yyyymmdd.trim();
        if (date.length() != 8) {
            if (date.length() == 4)
                date = date + "0101";
            else if (date.length() == 6)
                date = date + "01";
            else if (date.length() > 8)
                date = date.substring(0, 8);
            else
                return "";
        }

        cc.set(ChineseCalendar.EXTENDED_YEAR, Integer.parseInt(date.substring(0, 4)) + 2637);
        cc.set(ChineseCalendar.MONTH, Integer.parseInt(date.substring(4, 6)) - 1);
        cc.set(ChineseCalendar.DAY_OF_MONTH, Integer.parseInt(date.substring(6)));

        cal.setTimeInMillis(cc.getTimeInMillis());

        int y = cal.get(Calendar.YEAR);
        int m = cal.get(Calendar.MONTH) + 1;
        int d = cal.get(Calendar.DAY_OF_MONTH);

        StringBuffer ret = new StringBuffer();
        ret.append(String.format("%04d", y));
        ret.append(String.format("%02d", m));
        ret.append(String.format("%02d", d));

        return ret.toString();
    }

    /**
     * 양력날짜를 음력날짜로 변환
     * @param 양력날짜 (yyyyMMdd)
     * @return 음력날짜 (yyyyMMdd)
     */
    public static String Solar2Lunar(String yyyymmdd) {
        ChineseCalendar cc = new ChineseCalendar();
        Calendar cal = Calendar.getInstance();

        if (yyyymmdd == null)
            return "";

        String date = yyyymmdd.trim() ;
        if( date.length() != 8 ) {
            if( date.length() == 4 )
                date = date + "0101" ;
            else if( date.length() == 6 )
                date = date + "01" ;
            else if( date.length() > 8 )
                date = date.substring(0,8) ;
            else
                return "" ;
        }

        cal.set( Calendar.YEAR, Integer.parseInt(date.substring(0,4)) ) ;
        cal.set( Calendar.MONTH, Integer.parseInt(date.substring(4,6))-1 ) ;
        cal.set( Calendar.DAY_OF_MONTH, Integer.parseInt(date.substring(6)) ) ;

        cc.setTimeInMillis( cal.getTimeInMillis() ) ;

        // ChinessCalendar.YEAR 는 1~60 까지의 값만 가지고 ,
        // ChinessCalendar.EXTENDED_YEAR 는 Calendar.YEAR 값과 2637 만큼의 차이를 가진다.
        int y = cc.get(ChineseCalendar.EXTENDED_YEAR)-2637 ;
        int m = cc.get(ChineseCalendar.MONTH)+1 ;
        int d = cc.get(ChineseCalendar.DAY_OF_MONTH) ;

        StringBuffer ret = new StringBuffer() ;
        if( y < 1000 )          ret.append( "0" ) ;
        else if( y < 100 )      ret.append( "00" ) ;
        else if( y < 10 )       ret.append( "000" ) ;
        ret.append( y ) ;

        if( m < 10 ) ret.append( "0" ) ;
        ret.append( m ) ;

        if( d < 10 ) ret.append( "0" ) ;
        ret.append( d ) ;

        return ret.toString() ;
    }


    public static ArrayList<Holidays> holidayArray(String yyyy){
        holidaysArrayList.clear(); // 데이터 초기화
        // 양력 휴일
        addHolidaysItem(yyyy,"0101" ,"신정");
        addHolidaysItem(yyyy,"0301" ,"삼일절");
        addHolidaysItem(yyyy,"0505" ,"어린이날");
        addHolidaysItem(yyyy,"0606" ,"현충일" );
        addHolidaysItem(yyyy,"0815" ,"광복절");
        addHolidaysItem(yyyy,"1003" ,"개천절");
        addHolidaysItem(yyyy,"1009" ,"한글날");
        addHolidaysItem(yyyy,"1225" ,"성탄절");

        // 음력 휴일
        String prev_seol = String.valueOf(Integer.parseInt(Lunar2Solar(yyyy+"0101")) -1);
        addHolidaysItem(yyyy,prev_seol.substring(4) ,"");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0101"),"설날");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0102"),"");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0408"),"석탄일");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0814"),"");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0815"),"추석");
        addHolidaysItem(yyyy,SolarDays(yyyy, "0816"),"");

        try {
            // 어린이날 대체공휴일 검사 : 어린이날은 토요일, 일요일인 경우 그 다음 평일을 대체공유일로 지정
            int childDayChk = WeekendValue(yyyy+"0505");
            if(childDayChk == 1) addHolidaysItem(yyyy,"0506" ,"대체공휴일");
            if(childDayChk == 7) addHolidaysItem(yyyy,"0507" ,"대체공휴일");

            // 설날 대체공휴일 검사
            if(WeekendValue(Lunar2Solar(yyyy+"0101"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0103"),"대체공휴일");
            if(WeekendValue(Lunar2Solar(yyyy+"0101"))==2) addHolidaysItem(yyyy,SolarDays(yyyy, "0103"),"대체공휴일");
            if(WeekendValue(Lunar2Solar(yyyy+"0102"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0103"),"대체공휴일");

            // 추석 대체공휴일 검사
            if(WeekendValue(Lunar2Solar(yyyy+"0814"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0817"),"대체공휴일");
            if(WeekendValue(Lunar2Solar(yyyy+"0815"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0817"),"대체공휴일");
            if(WeekendValue(Lunar2Solar(yyyy+"0816"))==1) addHolidaysItem(yyyy,SolarDays(yyyy, "0817"),"대체공휴일");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Collections.sort(holidaysArrayList); // 오름차순 정렬

        return holidaysArrayList;
    }

    private static String SolarDays(String yyyy, String date){
        return Lunar2Solar(yyyy+date).substring(4);
    }

    private static void addHolidaysItem(String year, String date, String name ){
        Holidays item = new Holidays();
        item.setYear(year);
        item.setDate(date);
        item.setName(name);
        holidaysArrayList.add(item);
    }

    private static int WeekendValue(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(date));
        return cal.get(Calendar.DAY_OF_WEEK);
        // Calendar.SUNDAY : 1
        // Calendar.SATURDAY : 7
    }

}


사용 샘플 예제

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.tistory.link2me.item.Holidays;
import com.tistory.link2me.util.Lunar2Solar;
import com.tistory.link2me.util.LunarCalendar;

import java.util.ArrayList;
import java.util.Calendar;

public class CalendarActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calendar);

        System.out.println("Calendar.SUNDAY : "+Calendar.SUNDAY);
        System.out.println("Calendar.SATURDAY : "+Calendar.SATURDAY);

        ArrayList<Holidays> arr = LunarCalendar.holidayArray("2019");
        for(int i=0; i < arr.size();i++){
            System.out.println(arr.get(i).getYear() +"년 " + arr.get(i).getDate() +", " + arr.get(i).getName() );
        }

    }
}


결과 Logcat 화면


블로그 이미지

Link2Me

,