【Java】ChatGPTでカレンダー機能を作成してみた

# はじめ
こんにちは。
学生時代はJava・Pythonなどをはじめとする主流言語を広く浅く学んでいた@shika_ksです。
今回は、
・ChatGPTの無償版と有償版との違いを体感する
・自身の学習の振り返り
の観点から、Java入門のCalendarクラスを使用した機能を作成していきます。

# 動作環境
今回使用するツールは以下の通りです。
|ツール|バージョン|
|:---|:---|
|Java|jdk-17.0.5|
|ChatGPT|ChatGPT 4o mini 無償版|
|VScode|version 1.92|

# カレンダー機能
・うるう年を考慮してほしい
・先月、来月に移動できるようにしてほしい

上記2点の要望をChatGPTにした依頼しました。

```java:CalendarApp.java
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;

public class CalendarApp {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy年M月");

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        LocalDate currentDate = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(currentDate);

        while (true) {
            displayCalendar(currentMonth);

            System.out.println("操作を選択してください:");
            System.out.println("1: 次の月");
            System.out.println("2: 前の月");
            System.out.println("3: 終了");

            int choice = scanner.nextInt();

            switch (choice) {
                case 1:
                    currentMonth = currentMonth.plusMonths(1);
                    break;
                case 2:
                    currentMonth = currentMonth.minusMonths(1);
                    break;
                case 3:
                    System.out.println("アプリケーションを終了します。");
                    scanner.close();
                    return;
                default:
                    System.out.println("無効な選択肢です。もう一度試してください。");
                    break;
            }
        }
    }

    private static void displayCalendar(YearMonth yearMonth) {
        LocalDate firstOfMonth = yearMonth.atDay(1);
        int lengthOfMonth = yearMonth.lengthOfMonth();
        int dayOfWeek = firstOfMonth.getDayOfWeek().getValue(); // Monday=1, Sunday=7

        System.out.println(yearMonth.format(FORMATTER));
        System.out.println("日 月 火 水 木 金 土");

        // 空白のスペース
        for (int i = 1; i < dayOfWeek; i++) {
            System.out.print("   ");
        }

        // 日付を表示
        for (int day = 1; day <= lengthOfMonth; day++) {
            System.out.printf("%2d ", day);
            if ((day + dayOfWeek - 1) % 7 == 0) {
                System.out.println();
            }
        }
        System.out.println();
    }
}
```

結果がこちらです。
```txt:実行結果
2024年8月
日 月 火 水 木 金 土
          1  2  3  4 
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
操作を選択してください:
1: 次の月
2: 前の月
3: 終了
```

本来2024年8月1日は木曜日ですが、
結果は水曜日になっています。
ということで修正です。

# カレンダー機能(訂正版)
・2024年8月1日は木曜日開始
の情報を付けてChatGPTに修正を依頼しました。

```java:CalendarApp.java(訂正版)
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;

public class CalendarApp {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy年M月");

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        LocalDate currentDate = LocalDate.now();
        YearMonth currentMonth = YearMonth.from(currentDate);

        while (true) {
            displayCalendar(currentMonth);

            System.out.println("操作を選択してください:");
            System.out.println("1: 次の月");
            System.out.println("2: 前の月");
            System.out.println("3: 終了");

            int choice = scanner.nextInt();

            switch (choice) {
                case 1:
                    currentMonth = currentMonth.plusMonths(1);
                    break;
                case 2:
                    currentMonth = currentMonth.minusMonths(1);
                    break;
                case 3:
                    System.out.println("アプリケーションを終了します。");
                    scanner.close();
                    return;
                default:
                    System.out.println("無効な選択肢です。もう一度試してください。");
                    break;
            }
        }
    }

    private static void displayCalendar(YearMonth yearMonth) {
        LocalDate firstOfMonth = yearMonth.atDay(1);
        int lengthOfMonth = yearMonth.lengthOfMonth();
        int dayOfWeek = firstOfMonth.getDayOfWeek().getValue(); // Monday=1, ..., Sunday=7

        // 曜日のオフセット調整
        int offset = (dayOfWeek % 7); // Monday=1 → offset=0, Sunday=7 → offset=6

        System.out.println(yearMonth.format(FORMATTER));
        System.out.println("日 月 火 水 木 金 土");

        // 空白のスペース
        for (int i = 0; i < offset; i++) {
            System.out.print("   ");
        }

        // 日付を表示
        for (int day = 1; day <= lengthOfMonth; day++) {
            System.out.printf("%2d ", day);
            if ((day + offset) % 7 == 0) {
                System.out.println();
            }
        }
        System.out.println();
    }
}
```

結果はこちら。

```txt:実行結果
2024年8月
日 月 火 水 木 金 土
             1  2  3 
 4  5  6  7  8  9 10 
11 12 13 14 15 16 17 
18 19 20 21 22 23 24 
25 26 27 28 29 30 31 

操作を選択してください:
1: 次の月
2: 前の月
3: 終了
```

木曜日開始になりましたね。
1を送信→来月のカレンダー
2を送信→先月のカレンダー
3を送信→システムを終了
それ以外→もう一度送信
がしっかり動きます。

# まとめ
**ChatGPTを使用した感想**
無償版、有償版の違いを体感するために、今回は無償版を使用いたしました。
基本的には依頼通りの結果を返してくれますが、やはりミスが目立ちます。
コードの処理内容をある程度理解していれば、無償版を使用しても修正が可能だと感じました。