스터디 과제 - 캘린더 프로그램

NtoZ·2023년 5월 9일
1

Study

목록 보기
1/9

🚩 캘린더 프로그램

🏁 개요

  • 캘린더 프로그램 : 일정을 추가하고, 수정하고, 삭제할 수 있는 캘린더 프로그램을 만들어보세요. 이를 위해 지네릭스를 사용하여 리스트를 구현하고, LocalDateLocalTime 클래스를 사용하여 일정의 날짜와 시간을 저장합니다. 또한 애너테이션을 사용하여 일정의 카테고리를 지정할 수 있습니다.

🏁 구현 계획

  1. 리스트<제네릭스>를 활용하면 객체를 추가, 수정, 삭제할 수 있다.
    (add(), remove(), set() 등)

  2. 지네릭스는 특정 객체의 타입을 명시하여 컴파일 단계에서 오류를 체크하기 위한 문법이다. LocalDateLocalTime 클래스를 has a 관계로 가지고 있는 클래스를 정의하여 리스트에 담아 줄 것이다.
    ➡️[Java8 Time API] LocalDate, LocalTime, LocalDateTime 사용법

  3. 애너테이션은 다른 프로그램에게 정보를 제공하기 위한 자바 문법이다. 사용자 정의 애너테이션을 작성하여 정보를 명시할 수 있다. 모든 애너테이션은 java.util.annotation의 상속을 받는다.

🏁 구현

  • MyCalendar.java
package calendar.object;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;

public class MyCalendar  {

    private LinkedList<MySchedule> list_MySchedules = new LinkedList<>();

    private MySchedule mySchedule = new MySchedule(LocalDate.of(1,1,1), LocalTime.now());

    public MyCalendar(LinkedList<MySchedule> list_MySchedules) {
        this.list_MySchedules = list_MySchedules;
    }

    public MyCalendar() {

    }

    //현재 가지고 있는 리스트에 해당 날짜의 일정이 존재하면 해당 객체 반환. 없으면 null 반환
    public boolean getSchedule(int year, int month, int date) {
        LocalDate localDate = LocalDate.of(year, month, date);
        for(MySchedule ms : list_MySchedules) {
            if(ms.getLocalDate().isEqual(localDate)) {
                System.out.println("저장된 일정을 가져왔습니다." + ms.getLocalDate().toString());
                this.mySchedule = ms;
                return true;
            }
        }
        System.out.println("해당 일자에 일정이 없습니다.");
        this.mySchedule = new MySchedule(LocalDate.of(year, month, date), LocalTime.now());
        return false;
    }

    public void printCalendar() {
        Scanner sc = new Scanner(System.in);
        System.out.print("연도를 입력해주세요. >> ");
        int year = sc.nextInt();
        sc.nextLine();
        System.out.print("개월을 입력해주세요. >> ");
        int month = sc.nextInt();
        sc.nextLine();

        int date = 1; //일
        int day; //요일
        LocalDate firstDate = LocalDate.of(year, month, date);
        day = firstDate.getDayOfWeek().getValue(); //요일. 월1 ~ 일7

        //해당 연-월의 각 일자에 스케줄이 존재하면 schedule_date_list에 일자들을 넣는 메서드
        List schedule_date_list = getScheduleDateList(year, month);

        //달력 출력
        System.out.println(month >= 10 ?
                String.format("%16s[%d년 %d월]", " ", year, month) : String.format("%16s[%d년 %02d월]", " ", year, month));

        System.out.println(String.format("%6s%5s%5s%5s%5s%5s%5s",
                                "일","월","화","수","목","금","토"));

        //1일 전까지의 공백 생성
        for (int i = 0; i < day %7; i++) {
            System.out.printf("%6s", " ");
        }

        //달력 일 출력
        for(int i=1; i<=firstDate.lengthOfMonth(); i++) {
            String str_date = date+"";
            if(schedule_date_list.contains(date)) str_date +="*";
            System.out.printf("%6s", str_date);

            date++;
            day++;

            if(day % 7 == 0) {      //다음 주로 줄 바꿈.
                System.out.println();
            }
        }

    }

    private List getScheduleDateList(int year, int month) {
        List schedule_date_list = new ArrayList<Integer>();
        for (MySchedule ms : list_MySchedules) {
            //연, 월이 같으면 일자를 schedule_date_list에 넣기.
            if (ms.getLocalDate().getYear() == year && ms.getLocalDate().getMonthValue() == month) {
                schedule_date_list.add(ms.getLocalDate().getDayOfMonth());
            }
        }
        return schedule_date_list;
    }

    public void printAllSchedule() {
        Collections.sort(list_MySchedules);
        for(MySchedule mySchedule : list_MySchedules) {
            System.out.println(mySchedule.toString());
            System.out.println();
        }
    }

    public void renewalScheduleDate() {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            int year, month, date = 0;
            String str = "";
            System.out.println("계획을 추가/수정/삭제 하고 싶은 날이 언제인가요?");
            System.out.println("연-월-일을 순서대로 입력해주세요.");
            System.out.print("연: ");
            year = scanner.nextInt();
            scanner.nextLine();
            System.out.print("월: ");
            month = scanner.nextInt();
            scanner.nextLine();
            if(!(month>=1 || month<=12)) {
                System.out.println("유효한 값을 입력해주세요. 현재 입력한 값: " +month);
                continue;
            }
            System.out.print("일: ");
            date = scanner.nextInt();
            scanner.nextLine();
            if(!(date>=1||date<=this.mySchedule.getLocalDate().lengthOfMonth())) {
                System.out.println("유효한 일자를 입력해주세요. 현재 입력한 값:" + date);
                continue;
            }
            System.out.println(String.format("입력하신 [연-월-일]이 [%d-%d-%d]이 맞습니까?", year, month, date));
            System.out.println("맞으면 Y, 다시 입력하려면 다른 키, 취소하려면 C를 입력해주세요.");
            str = scanner.nextLine();
            if(str.equalsIgnoreCase("Y")) {
                this.getSchedule(year, month, date); //⭐일종의 연도-개월-일자 싱글턴 패턴
                break;
            }else if(str.equalsIgnoreCase("C")) {
                break;
            } else continue;
        }
    }

    //해당 날짜의 스케줄 입력하기
    public void addSchedule() {
        Scanner scanner = new Scanner(System.in);
        //날짜 갱신하기
        renewalScheduleDate();
        if(this.mySchedule.getLocalDate()==null) return;

        //스케줄 보여주기
        if(this.mySchedule.hasSchedule())
        System.out.println(this.mySchedule.getLocalDate().toString()+"의 스케줄은 \n" + this.mySchedule.getSchedule() + " 입니다.");

        //스케줄 입력하기
        System.out.println("아래에 스케줄을 입력해주세요. : ");
        String toDo = scanner.nextLine();
        this.mySchedule.getSchedule().append("\n"+toDo);

        System.out.println(this.mySchedule.getLocalDate().toString()+"의 스케줄은 \n" + this.mySchedule.getSchedule() + " 입니다.");

        this.mySchedule.setHasSchedule(true);

        if(!list_MySchedules.contains(this.mySchedule))
            list_MySchedules.add(this.mySchedule); // 현재 갱신된 날짜가 리스트에 들어있지 않으면 추가
    }

    //해당 날짜의 스케줄 삭제하기
    public void removeSchedule() {
        Scanner sc = new Scanner(System.in);
        //날짜 갱신하기
        renewalScheduleDate();
        System.out.println(this.mySchedule.toString());
        System.out.println("현재 날짜의 모든 일정을 삭제하시겠습니까? 맞으면 Y, 틀리면 다른 키를 입력해주세요.");
        String input = sc.nextLine();
        if(input.equalsIgnoreCase("y")) {
            for(MySchedule ms : list_MySchedules) {
                if(getSchedule(this.mySchedule.getLocalDate().getYear(),
                        this.mySchedule.getLocalDate().getMonthValue(), this.mySchedule.getLocalDate().getDayOfMonth())) {
                    System.out.println(ms.getLocalDate().toString()+"의 스케줄이 삭제되었습니다.");
                }
            }
            list_MySchedules.remove(this.mySchedule);
        }

//        if(this.mySchedule.getSchedule().toString().isEmpty()) {
//            System.out.println("현재 날짜에 등록된 스케줄이 없습니다.");
//            return;
//        }
//        this.mySchedule.getSchedule().delete(0, this.mySchedule.getSchedule().length()+1);
//        System.out.println(this.mySchedule.getLocalDate().toString()+"의 스케줄이 삭제 되었습니다.");
    }

    //해당 날짜의 스케줄 변경하기
    public void setSchedule() {
        //날짜 갱신하기
        renewalScheduleDate();
        if(this.mySchedule.getSchedule().toString().isEmpty()) {
            System.out.println("현재 날짜에 등록된 스케줄이 없습니다.");
            return;
        }
        Scanner scanner = new Scanner(System.in);
        System.out.println(this.mySchedule.getLocalDate().toString()+"의 현재 등록된 스케줄 : " +this.mySchedule.getSchedule().toString());
        String exists = this.mySchedule.getSchedule().toString();
        System.out.println("무엇으로 변경하시겠습니까? 변경할 스케줄을 입력해주십시오.");
        String replace = scanner.nextLine();

        System.out.println(String.format("%s을(를) %n %s로 바꾸시겠습니까? %n 바꾸시려면 (Y), 취소하시려면 이외의 문자를 입력해주세요.", exists, replace));
        String input = scanner.nextLine();
        if(input.equals("Y")) {
            this.mySchedule.getSchedule().delete(0, this.mySchedule.getSchedule().length()+1);
            addSchedule();
        }
    }
}
  • MySchedule.java
package calendar.object;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Scanner;

public class MySchedule implements Comparable {
    private LocalDate localDate;
    private LocalTime localTime = LocalTime.now();

    private StringBuilder schedule = new StringBuilder("");

    //해당 날짜에 일정이 있는지 체크
    private boolean hasSchedule;

    public MySchedule() {

    }

    public MySchedule(LocalDate localDate, LocalTime localTime) {
        this.localDate = localDate;
        this.localTime = localTime;
        this.hasSchedule = true;
    }

    public MySchedule(LocalDate localDate, LocalTime localTime, String schedule) {
        this.localDate = localDate;
        this.localTime = localTime;
        this.schedule = new StringBuilder(schedule);
    }

    public LocalDate getLocalDate() {
        return localDate;
    }

    public void setLocalDate(LocalDate localDate) {
        this.localDate = localDate;
    }

    public LocalTime getLocalTime() {
        return localTime;
    }

    public StringBuilder getSchedule() {
        return schedule;
    }

    public boolean hasSchedule() {
        return hasSchedule;
    }

    public void setHasSchedule(boolean hasSchedule) {
        this.hasSchedule = hasSchedule;
    }

    public boolean checkSchedule(int year, int month, int day) {
        LocalDate ld = LocalDate.of(year, month, day);
        if(ld.isEqual(this.localDate)) return true;
        return false;
    }

    @Override
    public String toString() {
        return String.format(
                "%s%n"
                + "%s 일정에 대해 안내 드리겠습니다. %n"
                +"%s%n"
                ,"=".repeat(40),this.localDate.toString(), this.schedule.toString());
    }

    @Override
    //localDate, localTime끼리 비교하는 메서드 (리스트의 정렬에 사용)
    public int compareTo(Object o) {
        if(!(o instanceof MySchedule)) return Integer.MAX_VALUE; //우측정렬
        MySchedule other = (MySchedule) o;
        //연과 달이 같으면
        if(this.localDate.getYear()==other.localDate.getYear()&&
            this.localDate.getDayOfMonth()==other.localDate.getDayOfMonth()) {
            return this.localTime.compareTo(other.localTime);
        }
        return this.localDate.compareTo(other.localDate);
    }


}
  • Main.java
import calendar.object.MyCalendar;
import calendar.object.MySchedule;

import java.util.Scanner;

public class Main {
    public static void printMenu() {
        System.out.println("메뉴를 출력하겠습니다.");
        System.out.println("=".repeat(40));
        System.out.println("1. 일정 추가하기");
        System.out.println("2. 일정 삭제하기");
        System.out.println("3. 일정 수정하기");
        System.out.println("4. 일정에 대한 월력 출력하기");
        System.out.println("5. 현재까지의 모든 일정 확인하기");
        System.out.println("0. 프로그램 종료하기");
        System.out.println("=".repeat(40));

    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        MyCalendar myCalendar = new MyCalendar();
        MySchedule mySchedule = new MySchedule();

        while (true) {
            System.out.println();
            System.out.println("안녕하세요. 마이_캘린더에 오신 것을 환영합니다.");
            printMenu();
            System.out.print("숫자를 입력해주세요. >> ");
            int choice = scanner.nextInt();
            scanner.nextLine();
            switch (choice) {
                case 1 :
                    myCalendar.addSchedule();
                    break;
                case 2 :
                    myCalendar.removeSchedule();
                    break;
                case 3 :
                    myCalendar.setSchedule();
                    break;
                case 4 :
                    myCalendar.printCalendar();
                    break;
                case 5 :
                    myCalendar.printAllSchedule();
                    break;
                case 0 :
                    System.out.println("프로그램을 종료합니다.");
                    System.exit(0);
                default:
                    System.out.println("잘못된 숫자를 입력하셨습니다.");
            }

        }
    }
}

profile
9에서 0으로, 백엔드 개발블로그

0개의 댓글