JAVA로 달력 만들기 (2)

류영준·2021년 12월 27일
0

JAVA

목록 보기
3/9
post-thumbnail

이 글은 만들어 가면서 배우는 JAVA 플레이그라운드를 수강하고 공부한 내용을 정리하는 용도로 작성되었습니다.

기능

  1. 날짜, 일정 이름, 장소, 게스트들을 입력 받아 저장하는 기능
  2. 날짜로 일정을 검색하는 기능
  3. 연도와 월을 입력 받아 달력을 출력하는 기능
    • [예외처리] : 1월~12월 이외의 달을 입력한 경우 -> 재입력
  4. 파일로 일정을 저장하는 기능 (다시 실행했을 때도 이전에 등록한 정보 검색 가능)

구조

1. Prompt

package Calendar;

import java.util.Scanner;

public class Prompt {
    public void printMenu() {
        System.out.println("+----------------------+");
        System.out.println("| 1. 일정 등록");
        System.out.println("| 2. 일정 검색");
        System.out.println("| 3. 달력 보기");
        System.out.println("| h. 도움말 q. 종료");
        System.out.println("+----------------------+");
        System.out.print("SELECT > ");
    }

    public void runPrompt(Scanner sc) {
        final String COMMAND_KEYS = "commands (1, 2, 3, h, q)";
        boolean isLoop = true;

        printMenu();

        Command cmds = new Command();

        while(isLoop) {
            String cmd = sc.nextLine();
            switch(cmd) {
                case("1"):
                    cmds.cmdRegister(sc);
                    System.out.println(COMMAND_KEYS);
                    break;
                case("2"):
                    cmds.cmdSearch(sc);
                    System.out.println(COMMAND_KEYS);
                    break;
                case("3"):
                    cmds.cmdPrintCalendar(sc);
                    System.out.println(COMMAND_KEYS);
                    break;
                case("h"):
                    printMenu();
                    break;
                case("q"):
                    isLoop = false;
                    System.out.print("Have a nice day!");
                    break;
            }
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Prompt prompt = new Prompt();
        prompt.runPrompt(sc);
        sc.close();
    }
}

2. Calendar

package Calendar;

public class RealCalendar {

    private static final int[] MAX_DAYS = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    private static final int[] LEAP_MAX_DAYS = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    public static boolean isLeapYear(int year) {
        if((year % 4 == 0 && year % 100 != 0) || (year % 400 ==0))
            return true;
        return false;
    }

    public static int getMaxDaysOfMonth(int year, int month) {
        if(isLeapYear(year))
            return LEAP_MAX_DAYS[month-1];
        return MAX_DAYS[month-1];
    }

    public static int getFirstDay(int year, int month) {
        final int START_YEAR = 1970;
        final int START_DAY_OF_THE_WEEK = 4;
        int yearFirstDay = 0;
        int firstDay = 0;
        int daySum = 0;

        daySum += START_DAY_OF_THE_WEEK + year - START_YEAR;

        for(int i = START_YEAR; i < year; i++)
            if(isLeapYear(i))
                daySum++;

        yearFirstDay = daySum % 7;

        for(int i = 1; i < month; i++)
            yearFirstDay += getMaxDaysOfMonth(year, i);

        firstDay = yearFirstDay % 7;

        return firstDay;
    }

    public static void printCalendar(int year, int month) {
        int firstDay = getFirstDay(year, month);
        int lastDay = getMaxDaysOfMonth(year, month);
        int count = 0;

        System.out.printf("     <%d년 %d월>    \n", year, month);
        System.out.println("SU MO TU WE TH FR SA");
        System.out.println("---------------------");

        for(int i = 0; i < firstDay; i++) {
            System.out.printf("   ");
            count++;
        }

        for(int i = 1; i <= lastDay; i++) {
            System.out.printf("%2d ", i);
            count++;
            if(count % 7 == 0)
                System.out.println();
        }
        System.out.println();
    }
}

3. PlanItem

package Calendar;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Date;
import java.text.SimpleDateFormat;

public class PlanItem {
    String format;
    String event;
    String location;
    ArrayList<String> guests;

    public PlanItem() {
        guests = new ArrayList<>();
    }

    public PlanItem(String event, String location, ArrayList<String> guests) {
        this.event = event;
        this.location = location;
        this.guests = guests;
    }

    public void planEvent(Scanner sc, Date date) {
        System.out.println("일정 이름을 입력하세요.");
        System.out.print("EVENT> ");
        event  = sc.nextLine();

        format = new SimpleDateFormat("yyyy-mm-dd").format(date);
        System.out.printf("%s : %s\n", format, event);
        System.out.println("Successfully Registered!\n");
    }

    public void planLocation(Scanner sc) {
        System.out.println("장소를 입력하세요.");
        System.out.print("LOCATION> ");
        location  = sc.nextLine();
    }

    public void planGuests(Scanner sc) {
        System.out.println("게스트를 입력하세요. (press q to quit)");

        while(true) {
            System.out.print("GUEST> ");
            String guest = sc.nextLine();
            if(guest.equals("q")) {
                System.out.println("GUESTS : " + guests);
                System.out.println();
                break;
            }
            guests.add(guest);
        }
    }
}

4. Command

package Calendar;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;


public class Command {
    HashMap<Date, PlanItem> plan;

    public Command() {
        plan = new HashMap<>();
        File f = new File("plan.dat");
        if(!f.exists())
            return;
        try {
            Scanner sc = new Scanner(f);
            while(sc.hasNext()) {
                String line = sc.nextLine();
                String[] words = line.split(",");

                Date date = null;
                try {
                    date = new SimpleDateFormat("yyyy-mm-dd").parse(words[0]);
                } catch (ParseException e) {
                    e.printStackTrace();
                }

                String event = words[1];
                String location = words[2];
                String[] strGuests = Arrays.copyOfRange(words, 3, words.length);
                ArrayList<String> allGuests = toStringFromArrayList(strGuests);
                PlanItem p = new PlanItem(event, location, allGuests);
                plan.put(date, p);
            }
            sc.close();
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void cmdRegister(Scanner sc) {
        System.out.println("\n[Register]");
        System.out.println("날짜를 입력해주세요. (yyyy-mm-dd)");
        System.out.print("DATE > ");
        Date date = null;
        String strDate = sc.nextLine();

        try {
            date = new SimpleDateFormat("yyyy-mm-dd").parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        System.out.println();
        PlanItem newPlan = new PlanItem();
        newPlan.planEvent(sc, date);
        newPlan.planLocation(sc);
        newPlan.planGuests(sc);

        plan.put(date, newPlan);

        try {
            FileWriter fw = new FileWriter("plan.dat", true);
            fw.write(newPlan.format + "," + newPlan.event + "," + newPlan.location + "," + newPlan.guests + "\n");
            fw.close();
        } catch(IOException e) {
            System.out.println("IO error occured!");
            e.printStackTrace();
        }
    }

    public void cmdSearch(Scanner sc) {
        Date sdate = null;
        System.out.println("\n[Search]");
        System.out.println("날짜를 입력해주세요. (yyyy-mm-dd)");
        System.out.print("DATE > ");
        String strSearchDate = sc.nextLine();

        try {
            sdate = new SimpleDateFormat("yyyy-mm-dd").parse(strSearchDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        PlanItem result = plan.get(sdate);
        System.out.println("EVENT : " + result.event);
        System.out.println("LOCATION : " + result.location);
        for(String guest : result.guests)
            System.out.println("GUEST : " + guest);
        System.out.println();
    }

    public void cmdPrintCalendar(Scanner sc) {
        int year, month;

        System.out.println("연도를 입력하세요.");
        System.out.print("YEAR> ");
        year = sc.nextInt();
        System.out.println("월을 입력하세요.");
        System.out.print("MONTH> ");
        month = sc.nextInt();

        if (year < 0 || month > 12 || month < 1) {
            System.out.println("유효한 값이 아닙니다.");
            year = sc.nextInt();
            month = sc.nextInt();
        }

        RealCalendar.printCalendar(year, month);
    }

    public ArrayList<String> toStringFromArrayList(String[] strGuests) {
        ArrayList<String> allGuests = new ArrayList<>();
        for(String a : strGuests) {
            String temp = a.replace("[", "").replace("]", "").replace(" ", "");
            allGuests.add(temp);
        }
        return allGuests;
    }
}

먼저 Date형식에서 String으로 변환, 혹은 String에서 Date형식으로 변환하는 SimpleDateFormat 을 사용하였다. SimpleDateFormat 객체를 생성한다. 객체를 생성할 때 파싱할 문자열의 포맷을 생성자의 인자로 입력해줘야한다. 위 코드에서는 yyyy-mm-dd 로 넣어주었다. 그런 다음 .parse(strDate) 코드를 실행하면 yyyy-mm-dd 포맷으로 strDate 문자열을 파싱해서 Date 객체로 만들어준다.
만약 yyyy-mm-dd 패턴과 다른 문자가 입력되면 ParseException 을 발생시킨다.

5. plan.dat

2021-12-31,study,pusan,[jisoo, rm, bang]
2021-02-15,Birthday,House,[Mom, Dad, Sister]

일정을 처음 등록하면 plan.dat 파일이 생성되고 새로 등록할 때마다 위와 같은 형태로 dat 파일에 저장된다. 파일에 저장되어있기 때문에 다시 실행했을 때도 이전에 등록한 정보 검색이 가능하다.

profile
Backend Developer

0개의 댓글