ChatGPTに、メジャーではない処理のコードの作り方を聞いてみる → コードは全く意図と違って全然使えず

# はじめに

文脈で分かり切っている場合、年の部分を省略して、2/12等のようによく書きます。
この年部分無しの表記を、現在の日付を基に補って、現在が2024/01/27だった時は、2/12→2024/02/12のように返す処理を、下記の記事で考えました。

https://qiita.com/dl_from_scratch/items/21b38f7248edd2e8ab19

この処理を、**ChatGPT**に言葉で伝えて、ChatGPTにコードの作り方を聞いてみます。ChatGPTが生成したコードを実行して、どのような動作となるかを調べてみます。

# ChatGPTにコードの作り方を聞いてみる

以降の節で、ChatGPTにコードの作り方を聞いてみます。

## 試行1

ChatGPTに、詳しい例を書いて、コードの作り方を聞いてみます。

履歴: https://chat.openai.com/share/400f6ffb-46a5-4ccd-abe6-3553158580af

**質問内容**
年なしでM/D(M月D日)と指定された時、今月とこの先のNヶ月は未来側の年月日として、それ以外は過去側の年月日として、DateTime型の値を返す、C#の関数コードは？
例1: 現在が2024/2/1で、N=6の時、3/2と指定されたら2024/3/2と返す、8/3と指定されたら2024/8/3と返す、9/4と指定されたら2023/9/4と返す、12/5と指定されたら2023/12/5と返す、1/6と指定されたら2024/1/6と返す。
例2: 現在が2024/10/31で、N=6の時、11/12と指定されたら2024/11/12と返す、1/13と指定されたら2025/1/13と返す、4/14と指定されたら2025/4/14と返す、5/15と指定されたら2024/5/15と返す、9/16と指定されたら2024/9/16と返す。

**ChatGPTの回答**
以下は、指定された条件に基づいてDateTime型の値を返すC#の関数のサンプルコードです。このコードでは、引数として現在の日付、指定されたM/D、およびNを受け取り、条件に基づいて未来側と過去側の年月日を計算しています。
```C#
using System;

class Program
{
    static void Main()
    {
        // 現在の日付
        DateTime currentDate = DateTime.Now;

        // テスト例1
        DateTime result1 = CalculateDate(currentDate, "3/2", 6);
        Console.WriteLine(result1);

        DateTime result2 = CalculateDate(currentDate, "8/3", 6);
        Console.WriteLine(result2);

        DateTime result3 = CalculateDate(currentDate, "9/4", 6);
        Console.WriteLine(result3);

        DateTime result4 = CalculateDate(currentDate, "12/5", 6);
        Console.WriteLine(result4);

        DateTime result5 = CalculateDate(currentDate, "1/6", 6);
        Console.WriteLine(result5);

        // テスト例2
        DateTime result6 = CalculateDate(new DateTime(2024, 10, 31), "11/12", 6);
        Console.WriteLine(result6);

        DateTime result7 = CalculateDate(new DateTime(2024, 10, 31), "1/13", 6);
        Console.WriteLine(result7);

        DateTime result8 = CalculateDate(new DateTime(2024, 10, 31), "4/14", 6);
        Console.WriteLine(result8);

        DateTime result9 = CalculateDate(new DateTime(2024, 10, 31), "5/15", 6);
        Console.WriteLine(result9);

        DateTime result10 = CalculateDate(new DateTime(2024, 10, 31), "9/16", 6);
        Console.WriteLine(result10);
    }

    static DateTime CalculateDate(DateTime currentDate, string specifiedDate, int N)
    {
        // 指定されたM/DをパースしてDateTime型に変換
        DateTime targetDate = DateTime.ParseExact(specifiedDate, "M/d", null);

        // 未来側の年月日の条件
        if (targetDate.Month >= currentDate.Month)
        {
            return currentDate.AddMonths(N).Date;
        }
        // 過去側の年月日の条件
        else
        {
            return currentDate.AddMonths(-N).Date;
        }
    }
}
```
このコードは、指定された条件に基づいて未来側と過去側の年月日を計算し、DateTime型で返します。例のテストケースも含まれています。

### 実行結果

上記のChatGPTが生成したコード(関数部分)を実行して、どのような動作となるかを調べてみると、
```C#
        static void Main1_ChatGPT() {
            /* 結果: 間違い
2024/08/01 0:00:00
2024/08/01 0:00:00
2024/08/01 0:00:00
2024/08/01 0:00:00
2023/08/01 0:00:00

2025/04/30 0:00:00
2024/04/30 0:00:00
2024/04/30 0:00:00
2024/04/30 0:00:00
2024/04/30 0:00:00
            */
            /* 正解:
2024/03/02 0:00:00
2024/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2024/01/06 0:00:00

2024/11/12 0:00:00
2025/01/13 0:00:00
2025/04/14 0:00:00
2024/05/15 0:00:00
2024/09/16 0:00:00
            */

            Action<string> WL = Console.WriteLine;
            Func<string, DateTime> DT = DateTime.Parse;

            WL("▼ChatGPT1");
            var t_now = DT("2024/02/01");
            WL($"{CalculateDate1_ChatGPT("3/2", 6, t_now)}");
            WL($"{CalculateDate1_ChatGPT("8/3", 6, t_now)}");
            WL($"{CalculateDate1_ChatGPT("9/4", 6, t_now)}");
            WL($"{CalculateDate1_ChatGPT("12/5", 6, t_now)}");
            WL($"{CalculateDate1_ChatGPT("1/6", 6, t_now)}");
            WL("");

            t_now = DT("2024/10/31");
            WL($"{CalculateDate1_ChatGPT("11/12", 6, t_now)}");
            WL($"{CalculateDate1_ChatGPT("1/13", 6, t_now)}");
            WL($"{CalculateDate1_ChatGPT("4/14", 6, t_now)}");
            WL($"{CalculateDate1_ChatGPT("5/15", 6, t_now)}");
            WL($"{CalculateDate1_ChatGPT("9/16", 6, t_now)}");
            WL("");
        }

        static DateTime CalculateDate1_ChatGPT(string specifiedDate, int N, DateTime currentDate) {
            // 指定されたM/DをパースしてDateTime型に変換
            DateTime targetDate = DateTime.ParseExact(specifiedDate, "M/d", null);

            // 未来側の年月日の条件
            if (targetDate.Month >= currentDate.Month) {
                return currentDate.AddMonths(N).Date;
            }
            // 過去側の年月日の条件
            else {
                return currentDate.AddMonths(-N).Date;
            }
        }
```

上記テストコード内のコメントに、実際の実行結果と正解を併記してあります。ChatGPTが生成したコードは期待するような出力にはなりませんでした。

期待する出力(正解)とその実装コード(人手で作成): 
https://qiita.com/dl_from_scratch/items/21b38f7248edd2e8ab19

## 試行2

試行1では、多量の例を書き過ぎたので、例を半分に減らして、同様にChatGPTにコードの作り方を聞いてみます。

履歴: https://chat.openai.com/share/400f6ffb-46a5-4ccd-abe6-3553158580af

**質問内容**
年なしでM/D(M月D日)と指定された時、今月とこの先のNヶ月は未来側の年月日として、それ以外は過去側の年月日として、DateTime型の値を返す、C#の関数コードは？
例1: 現在が2024/2/1で、N=6の時、3/2と指定されたら2024/3/2と返す、8/3と指定されたら2024/8/3と返す、9/4と指定されたら2023/9/4と返す、12/5と指定されたら2023/12/5と返す、1/6と指定されたら2024/1/6と返す。

**ChatGPTの回答**
失礼しました。前回の回答に誤りがありました。以下は正しいC#の関数コードです。
```C#
using System;

class Program
{
    static void Main()
    {
        // 現在の日付
        DateTime currentDate = DateTime.Now;

        // テスト例1
        DateTime result1 = CalculateDate(currentDate, "3/2", 6);
        Console.WriteLine(result1);

        DateTime result2 = CalculateDate(currentDate, "8/3", 6);
        Console.WriteLine(result2);

        DateTime result3 = CalculateDate(currentDate, "9/4", 6);
        Console.WriteLine(result3);

        DateTime result4 = CalculateDate(currentDate, "12/5", 6);
        Console.WriteLine(result4);

        DateTime result5 = CalculateDate(currentDate, "1/6", 6);
        Console.WriteLine(result5);
    }

    static DateTime CalculateDate(DateTime currentDate, string specifiedDate, int N)
    {
        // 指定されたM/DをパースしてDateTime型に変換
        DateTime targetDate = DateTime.ParseExact(specifiedDate, "M/d", null);

        // 未来側の年月日の条件
        if (targetDate.Month >= currentDate.Month || targetDate.Month >= currentDate.AddMonths(N).Month)
        {
            return new DateTime(currentDate.Year, targetDate.Month, targetDate.Day);
        }
        // 過去側の年月日の条件
        else
        {
            return new DateTime(currentDate.Year - 1, targetDate.Month, targetDate.Day);
        }
    }
}
```
このコードは、指定された条件に基づいて未来側と過去側の年月日を計算し、DateTime型で返します。例のテストケースも含まれています。

### 実行結果

上記のChatGPTが生成したコード(関数部分)を実行して、どのような動作となるかを調べてみると、
```C#
        static void Main2_ChatGPT() {
            /* 結果: 間違い
2024/03/02 0:00:00
2024/08/03 0:00:00
2024/09/04 0:00:00
2024/12/05 0:00:00
2023/01/06 0:00:00

2024/11/12 0:00:00
2023/01/13 0:00:00
2024/04/14 0:00:00
2024/05/15 0:00:00
2024/09/16 0:00:00
            */
            /* 正解:
2024/03/02 0:00:00
2024/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2024/01/06 0:00:00

2024/11/12 0:00:00
2025/01/13 0:00:00
2025/04/14 0:00:00
2024/05/15 0:00:00
2024/09/16 0:00:00
            */

            Action<string> WL = Console.WriteLine;
            Func<string, DateTime> DT = DateTime.Parse;

            WL("▼ChatGPT2");
            var t_now = DT("2024/02/01");
            WL($"{CalculateDate2_ChatGPT("3/2", 6, t_now)}");
            WL($"{CalculateDate2_ChatGPT("8/3", 6, t_now)}");
            WL($"{CalculateDate2_ChatGPT("9/4", 6, t_now)}");
            WL($"{CalculateDate2_ChatGPT("12/5", 6, t_now)}");
            WL($"{CalculateDate2_ChatGPT("1/6", 6, t_now)}");
            WL("");

            t_now = DT("2024/10/31");
            WL($"{CalculateDate2_ChatGPT("11/12", 6, t_now)}");
            WL($"{CalculateDate2_ChatGPT("1/13", 6, t_now)}");
            WL($"{CalculateDate2_ChatGPT("4/14", 6, t_now)}");
            WL($"{CalculateDate2_ChatGPT("5/15", 6, t_now)}");
            WL($"{CalculateDate2_ChatGPT("9/16", 6, t_now)}");
            WL("");
        }

        static DateTime CalculateDate2_ChatGPT(string specifiedDate, int N, DateTime currentDate) {
            // 指定されたM/DをパースしてDateTime型に変換
            DateTime targetDate = DateTime.ParseExact(specifiedDate, "M/d", null);

            // 未来側の年月日の条件
            if (targetDate.Month >= currentDate.Month || targetDate.Month >= currentDate.AddMonths(N).Month) {
                return new DateTime(currentDate.Year, targetDate.Month, targetDate.Day);
            }
            // 過去側の年月日の条件
            else {
                return new DateTime(currentDate.Year - 1, targetDate.Month, targetDate.Day);
            }
        }
```

上記テストコード内のコメントに、実際の実行結果と正解を併記してあります。ChatGPTが生成したコードは期待するような出力にはなりませんでした。

期待する出力(正解)とその実装コード(人手で作成): 
https://qiita.com/dl_from_scratch/items/21b38f7248edd2e8ab19

## 試行3

試行1・2よりも、より簡単・簡潔な表現で、ChatGPTにコードの作り方を聞いてみます。

履歴: https://chat.openai.com/share/400f6ffb-46a5-4ccd-abe6-3553158580af

**質問内容**
文脈で分かり切っている場合、年の部分を省略して、2/12等のようによく書きます。
この年部分無しの表記を、現在の日付を基に補って、現在が2024/01/27だった時は、2/12→2024/02/12のように返し、12/23→2023/12/23のように返す、C#の関数コードは？

**ChatGPTの回答**
理解しました。以下は、年部分が省略された表記を現在の日付を基に補完するC#の関数コードです。
```C#
using System;

class Program
{
    static void Main()
    {
        // 現在の日付
        DateTime currentDate = DateTime.Now;

        // テスト例
        DateTime result1 = CompleteDate(currentDate, "2/12");
        Console.WriteLine(result1);

        DateTime result2 = CompleteDate(currentDate, "12/23");
        Console.WriteLine(result2);
    }

    static DateTime CompleteDate(DateTime currentDate, string inputDate)
    {
        // 指定されたM/DをパースしてDateTime型に変換
        DateTime targetDate = DateTime.ParseExact(inputDate, "M/d", null);

        // 年部分の補完
        int year = currentDate.Year;

        // 未来側の年月日の条件
        if (targetDate.Month >= currentDate.Month || targetDate.Month >= currentDate.AddMonths(1).Month)
        {
            return new DateTime(year, targetDate.Month, targetDate.Day);
        }
        // 過去側の年月日の条件
        else
        {
            return new DateTime(year - 1, targetDate.Month, targetDate.Day);
        }
    }
}
```
このコードは、年部分が省略された表記を現在の日付を基に補完して、DateTime型で返します。例のテストケースも含まれています。

### 実行結果

上記のChatGPTが生成したコード(関数部分)を実行して、どのような動作となるかを調べてみると、
```C#
        static void Main3_ChatGPT() {
            /* 結果: 間違い
2024/03/02 0:00:00
2024/08/03 0:00:00
2024/09/04 0:00:00
2024/12/05 0:00:00
2023/01/06 0:00:00

2024/11/12 0:00:00
2023/01/13 0:00:00
2023/04/14 0:00:00
2023/05/15 0:00:00
2023/09/16 0:00:00
            */
            /* 正解:
2024/03/02 0:00:00
2024/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2024/01/06 0:00:00

2024/11/12 0:00:00
2025/01/13 0:00:00
2025/04/14 0:00:00
2024/05/15 0:00:00
2024/09/16 0:00:00
            */

            Action<string> WL = Console.WriteLine;
            Func<string, DateTime> DT = DateTime.Parse;

            WL("▼ChatGPT3");
            var t_now = DT("2024/02/01");
            WL($"{CalculateDate3_ChatGPT("3/2", 6, t_now)}");
            WL($"{CalculateDate3_ChatGPT("8/3", 6, t_now)}");
            WL($"{CalculateDate3_ChatGPT("9/4", 6, t_now)}");
            WL($"{CalculateDate3_ChatGPT("12/5", 6, t_now)}");
            WL($"{CalculateDate3_ChatGPT("1/6", 6, t_now)}");
            WL("");

            t_now = DT("2024/10/31");
            WL($"{CalculateDate3_ChatGPT("11/12", 6, t_now)}");
            WL($"{CalculateDate3_ChatGPT("1/13", 6, t_now)}");
            WL($"{CalculateDate3_ChatGPT("4/14", 6, t_now)}");
            WL($"{CalculateDate3_ChatGPT("5/15", 6, t_now)}");
            WL($"{CalculateDate3_ChatGPT("9/16", 6, t_now)}");
            WL("");
        }

        static DateTime CalculateDate3_ChatGPT(string specifiedDate, int N, DateTime currentDate) {
            // 指定されたM/DをパースしてDateTime型に変換
            DateTime targetDate = DateTime.ParseExact(specifiedDate, "M/d", null);

            // 年部分の補完
            int year = currentDate.Year;

            // 未来側の年月日の条件
            if (targetDate.Month >= currentDate.Month || targetDate.Month >= currentDate.AddMonths(1).Month)
            {
                return new DateTime(year, targetDate.Month, targetDate.Day);
            }
            // 過去側の年月日の条件
            else
            {
                return new DateTime(year - 1, targetDate.Month, targetDate.Day);
            }
        }
```

上記テストコード内のコメントに、実際の実行結果と正解を併記してあります。ChatGPTが生成したコードは期待するような出力にはなりませんでした。

期待する出力(正解)とその実装コード(人手で作成): 
https://qiita.com/dl_from_scratch/items/21b38f7248edd2e8ab19

# Phindにコードの作り方を聞いてみる

以降の節では、ChatGPTの代わりに、Phindにコードの作り方を聞いてみます。

https://www.phind.com/

## 試行1

Phindに、詳しい例を書いて、コードの作り方を聞いてみます。(ChatGPTへの質問内容と全く同じ)

履歴: https://www.phind.com/search?cache=drtpcjgcgupcsrek6l2t53xj

**質問内容**
年なしでM/D(M月D日)と指定された時、今月とこの先のNヶ月は未来側の年月日として、それ以外は過去側の年月日として、DateTime型の値を返す、C#の関数コードは？
例1: 現在が2024/2/1で、N=6の時、3/2と指定されたら2024/3/2と返す、8/3と指定されたら2024/8/3と返す、9/4と指定されたら2023/9/4と返す、12/5と指定されたら2023/12/5と返す、1/6と指定されたら2024/1/6と返す。
例2: 現在が2024/10/31で、N=6の時、11/12と指定されたら2024/11/12と返す、1/13と指定されたら2025/1/13と返す、4/14と指定されたら2025/4/14と返す、5/15と指定されたら2024/5/15と返す、9/16と指定されたら2024/9/16と返す。

**Phindの回答**
この問題を解決するためには、C#の DateTime クラスのメソッドを使用します。具体的には、DateTime.Now を使用して現在の日付を取得し、DateTime.Parse や DateTime.TryParse を使用して日付文字列をパースし、DateTime.AddMonths を使用して月を追加します。

まず、現在の日付を取得します。5より：
```C#
DateTime now = DateTime.Now;
```
次に、指定された日付文字列（例えば、"3/2"）をパースします。これは、指定された日付が未来か過去かを判断するために必要です。5より：
```C#
DateTime inputDate;
bool success = DateTime.TryParse(input, out inputDate);
```
ここで、success が false であれば、入力が有効な日付でないことを示します。

次に、指定された日付が未来か過去かを判断します。これは、指定された日付が現在の月からNヶ月後またはそれ以前の場合に未来の日付と見なし、それ以外の場合に過去の日付と見なします。
```C#
DateTime futureDate = now.AddMonths(N);
if (inputDate >= now && inputDate <= futureDate) {
    // 未来の日付
} else {
    // 過去の日付
}
```
最後に、未来の日付と過去の日付を適切に計算し、結果を返します。

以上を組み合わせると、次のような関数が得られます：
```C#
public DateTime GetDate(string input, int N) {
    DateTime now = DateTime.Now;
    DateTime inputDate;
    if (!DateTime.TryParse(input, out inputDate)) {
        throw new ArgumentException("Invalid date format");
    }

    DateTime futureDate = now.AddMonths(N);
    if (inputDate >= now && inputDate <= futureDate) {
        // 未来の日付
        return inputDate;
    } else {
        // 過去の日付
        return inputDate.AddYears(-1);
    }
}
```
この関数は、指定された日付が未来の場合はそのままを返し、過去の場合は1年引きます。

### 実行結果

上記のPhindが生成したコード(関数部分)を実行して、どのような動作となるかを調べてみると、
```C#
        static void Main1_Phind() {
            /* 結果: 間違い
2024/03/02 0:00:00
2023/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2023/01/06 0:00:00

2024/11/12 0:00:00
2023/01/13 0:00:00
2023/04/14 0:00:00
2023/05/15 0:00:00
2023/09/16 0:00:00
            */
            /* 正解:
2024/03/02 0:00:00
2024/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2024/01/06 0:00:00

2024/11/12 0:00:00
2025/01/13 0:00:00
2025/04/14 0:00:00
2024/05/15 0:00:00
2024/09/16 0:00:00
            */

            Action<string> WL = Console.WriteLine;
            Func<string, DateTime> DT = DateTime.Parse;

            WL("▼Phind1");
            var t_now = DT("2024/02/01");
            WL($"{GetDate1_Phind("3/2", 6, t_now)}");
            WL($"{GetDate1_Phind("8/3", 6, t_now)}");
            WL($"{GetDate1_Phind("9/4", 6, t_now)}");
            WL($"{GetDate1_Phind("12/5", 6, t_now)}");
            WL($"{GetDate1_Phind("1/6", 6, t_now)}");
            WL("");

            t_now = DT("2024/10/31");
            WL($"{GetDate1_Phind("11/12", 6, t_now)}");
            WL($"{GetDate1_Phind("1/13", 6, t_now)}");
            WL($"{GetDate1_Phind("4/14", 6, t_now)}");
            WL($"{GetDate1_Phind("5/15", 6, t_now)}");
            WL($"{GetDate1_Phind("9/16", 6, t_now)}");
            WL("");
        }

        static DateTime GetDate1_Phind(string input, int N, DateTime now) {
            DateTime inputDate;
            if (!DateTime.TryParse(input, out inputDate)) {
                throw new ArgumentException("Invalid date format");
            }

            DateTime futureDate = now.AddMonths(N);
            if (inputDate >= now && inputDate <= futureDate) {
                // 未来の日付
                return inputDate;
            } else {
                // 過去の日付
                return inputDate.AddYears(-1);
            }
        }
```

上記テストコード内のコメントに、実際の実行結果と正解を併記してあります。Phindが生成したコードは期待するような出力にはなりませんでした。

期待する出力(正解)とその実装コード(人手で作成): 
https://qiita.com/dl_from_scratch/items/21b38f7248edd2e8ab19

## 試行2

試行1では、多量の例を書き過ぎたので、例を半分に減らして、同様にPhindにコードの作り方を聞いてみます。(ChatGPTへの質問内容と全く同じ)

履歴: https://www.phind.com/search?cache=drtpcjgcgupcsrek6l2t53xj

**質問内容**
年なしでM/D(M月D日)と指定された時、今月とこの先のNヶ月は未来側の年月日として、それ以外は過去側の年月日として、DateTime型の値を返す、C#の関数コードは？
例1: 現在が2024/2/1で、N=6の時、3/2と指定されたら2024/3/2と返す、8/3と指定されたら2024/8/3と返す、9/4と指定されたら2023/9/4と返す、12/5と指定されたら2023/12/5と返す、1/6と指定されたら2024/1/6と返す。

**Phindの回答**
この問題を解決するためには、C#の DateTime クラスのメソッドを使用します。具体的には、DateTime.Now を使用して現在の日付を取得し、DateTime.Parse や DateTime.TryParse を使用して日付文字列をパースし、DateTime.AddMonths を使用して月を追加します。

まず、現在の日付を取得します。8より：
```C#
DateTime now = DateTime.Now;
```
次に、指定された日付文字列（例えば、"3/2"）をパースします。これは、指定された日付が未来か過去かを判断するために必要です。3より：
```C#
DateTime inputDate;
bool success = DateTime.TryParse(input, out inputDate);
```
ここで、success が false であれば、入力が有効な日付でないことを示します。

次に、指定された日付が未来か過去かを判断します。これは、指定された日付が現在の月からNヶ月後またはそれ以前の場合に未来の日付と見なし、それ以外の場合に過去の日付と見なします。
```C#
DateTime futureDate = now.AddMonths(N);
if (inputDate >= now && inputDate <= futureDate) {
    // 未来の日付
} else {
    // 過去の日付
}
```
最後に、未来の日付と過去の日付を適切に計算し、結果を返します。

以上を組み合わせると、次のような関数が得られます：
```C#
public DateTime GetDate(string input, int N) {
    DateTime now = DateTime.Now;
    DateTime inputDate;
    if (!DateTime.TryParse(input, out inputDate)) {
        throw new ArgumentException("Invalid date format");
    }

    DateTime futureDate = now.AddMonths(N);
    if (inputDate >= now && inputDate <= futureDate) {
        // 未来の日付
        return inputDate;
    } else {
        // 過去の日付
        return inputDate.AddYears(-1);
    }
}
```
この関数は、指定された日付が未来の場合はそのままを返し、過去の場合は1年引きます。

### 実行結果

上記のPhindが生成したコード(関数部分)を実行して、どのような動作となるかを調べてみると、
```C#
        static void Main2_Phind() {
            /* 結果: 間違い
2024/03/02 0:00:00
2023/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2023/01/06 0:00:00

2024/11/12 0:00:00
2023/01/13 0:00:00
2023/04/14 0:00:00
2023/05/15 0:00:00
2023/09/16 0:00:00
            */
            /* 正解:
2024/03/02 0:00:00
2024/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2024/01/06 0:00:00

2024/11/12 0:00:00
2025/01/13 0:00:00
2025/04/14 0:00:00
2024/05/15 0:00:00
2024/09/16 0:00:00
            */

            Action<string> WL = Console.WriteLine;
            Func<string, DateTime> DT = DateTime.Parse;

            WL("▼Phind2");
            var t_now = DT("2024/02/01");
            WL($"{GetDate2_Phind("3/2", 6, t_now)}");
            WL($"{GetDate2_Phind("8/3", 6, t_now)}");
            WL($"{GetDate2_Phind("9/4", 6, t_now)}");
            WL($"{GetDate2_Phind("12/5", 6, t_now)}");
            WL($"{GetDate2_Phind("1/6", 6, t_now)}");
            WL("");

            t_now = DT("2024/10/31");
            WL($"{GetDate2_Phind("11/12", 6, t_now)}");
            WL($"{GetDate2_Phind("1/13", 6, t_now)}");
            WL($"{GetDate2_Phind("4/14", 6, t_now)}");
            WL($"{GetDate2_Phind("5/15", 6, t_now)}");
            WL($"{GetDate2_Phind("9/16", 6, t_now)}");
            WL("");
        }

        static DateTime GetDate2_Phind(string input, int N, DateTime now) {
            DateTime inputDate;
            if (!DateTime.TryParse(input, out inputDate)) {
                throw new ArgumentException("Invalid date format");
            }

            DateTime futureDate = now.AddMonths(N);
            if (inputDate >= now && inputDate <= futureDate) {
                // 未来の日付
                return inputDate;
            } else {
                // 過去の日付
                return inputDate.AddYears(-1);
            }
        }
```

上記テストコード内のコメントに、実際の実行結果と正解を併記してあります。Phindが生成したコードは期待するような出力にはなりませんでした。

期待する出力(正解)とその実装コード(人手で作成): 
https://qiita.com/dl_from_scratch/items/21b38f7248edd2e8ab19

## 試行3

試行1・2よりも、より簡単・簡潔な表現で、Phindにコードの作り方を聞いてみます。(ChatGPTへの質問内容と全く同じ)

履歴: https://www.phind.com/search?cache=drtpcjgcgupcsrek6l2t53xj

**質問内容**
文脈で分かり切っている場合、年の部分を省略して、2/12等のようによく書きます。
この年部分無しの表記を、現在の日付を基に補って、現在が2024/01/27だった時は、2/12→2024/02/12のように返し、12/23→2023/12/23のように返す、C#の関数コードは？

**Phindの回答**
この問題を解決するためには、C#の DateTime クラスのメソッドを使用します。具体的には、DateTime.Now を使用して現在の日付を取得し、DateTime.ParseExact を使用して日付文字列をパースします。

まず、現在の日付を取得します。2より：
```C#
DateTime now = DateTime.Now;
```
次に、指定された日付文字列（例えば、"2/12"）をパースします。これは、指定された日付が未来か過去かを判断するために必要です。2より：
```C#
DateTime inputDate;
bool success = DateTime.TryParseExact(input, "M/d", null, System.Globalization.DateTimeStyles.None, out inputDate);
```
ここで、success が false であれば、入力が有効な日付でないことを示します。

最後に、指定された日付が未来か過去かを判断します。これは、指定された日付が現在の月からNヶ月後またはそれ以前の場合に未来の日付と見なし、それ以外の場合に過去の日付と見なします。
```C#
DateTime futureDate = now.AddMonths(N);
if (inputDate >= now && inputDate <= futureDate) {
    // 未来の日付
} else {
    // 過去の日付
}
```
最後に、未来の日付と過去の日付を適切に計算し、結果を返します。

以上を組み合わせると、次のような関数が得られます：
```C#
public DateTime GetDate(string input, int N) {
    DateTime now = DateTime.Now;
    DateTime inputDate;
    if (!DateTime.TryParseExact(input, "M/d", null, System.Globalization.DateTimeStyles.None, out inputDate)) {
        throw new ArgumentException("Invalid date format");
    }

    DateTime futureDate = now.AddMonths(N);
    if (inputDate >= now && inputDate <= futureDate) {
        // 未来の日付
        return inputDate;
    } else {
        // 過去の日付
        return inputDate.AddYears(-1);
    }
}
```
この関数は、指定された日付が未来の場合はそのままを返し、過去の場合は1年引きます。

### 実行結果

上記のPhindが生成したコード(関数部分)を実行して、どのような動作となるかを調べてみると、
```C#
        static void Main3_Phind() {
            /* 結果: 間違い
2024/03/02 0:00:00
2023/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2023/01/06 0:00:00

2024/11/12 0:00:00
2023/01/13 0:00:00
2023/04/14 0:00:00
2023/05/15 0:00:00
2023/09/16 0:00:00
            */
            /* 正解:
2024/03/02 0:00:00
2024/08/03 0:00:00
2023/09/04 0:00:00
2023/12/05 0:00:00
2024/01/06 0:00:00

2024/11/12 0:00:00
2025/01/13 0:00:00
2025/04/14 0:00:00
2024/05/15 0:00:00
2024/09/16 0:00:00
            */

            Action<string> WL = Console.WriteLine;
            Func<string, DateTime> DT = DateTime.Parse;

            WL("▼Phind3");
            var t_now = DT("2024/02/01");
            WL($"{GetDate3_Phind("3/2", 6, t_now)}");
            WL($"{GetDate3_Phind("8/3", 6, t_now)}");
            WL($"{GetDate3_Phind("9/4", 6, t_now)}");
            WL($"{GetDate3_Phind("12/5", 6, t_now)}");
            WL($"{GetDate3_Phind("1/6", 6, t_now)}");
            WL("");

            t_now = DT("2024/10/31");
            WL($"{GetDate3_Phind("11/12", 6, t_now)}");
            WL($"{GetDate3_Phind("1/13", 6, t_now)}");
            WL($"{GetDate3_Phind("4/14", 6, t_now)}");
            WL($"{GetDate3_Phind("5/15", 6, t_now)}");
            WL($"{GetDate3_Phind("9/16", 6, t_now)}");
            WL("");
        }

        static DateTime GetDate3_Phind(string input, int N, DateTime now) {
            DateTime inputDate;
            if (!DateTime.TryParseExact(input, "M/d", null, System.Globalization.DateTimeStyles.None, out inputDate)) {
                throw new ArgumentException("Invalid date format");
            }

            DateTime futureDate = now.AddMonths(N);
            if (inputDate >= now && inputDate <= futureDate) {
                // 未来の日付
                return inputDate;
            } else {
                // 過去の日付
                return inputDate.AddYears(-1);
            }
        }
```

上記テストコード内のコメントに、実際の実行結果と正解を併記してあります。Phindが生成したコードは期待するような出力にはなりませんでした。

期待する出力(正解)とその実装コード(人手で作成): 
https://qiita.com/dl_from_scratch/items/21b38f7248edd2e8ab19

# まとめ

本稿で設定したタスク(年の部分を省略した月日から年月日へ変換)に対しては、ChatGPTやPhindが生成したコードは、**期待するような出力にはなりませんでした**。

本稿で設定したタスクは、年の部分を省略した月日から年月日へ変換する、全く**馴染みのないもの**で、**Webを探してもあまり見つかりそうにないもの**でした。このようなタスクに対しては、(当然と言えばその通りですが)、コードを自動生成するのは難しいようです。

既にWebにあるメジャーなもの、単純に組み合わせればよいもの、については、ChatGPTやPhindがとても強く、コード作成は人間にとって置き換わりそうですが、それ以上のものについては、期待通り動作するコードを作成するのは難しいようです。

サンプルコード、テンプレート、簡単な組み合わせで済むもの、については、ChatGPTやPhindが人間を凌駕するものになりそうですが、メジャーではないもの、計算の方法を考えなくてはならないもの、組み合わせが入り組む複雑なもの、等については、ChatGPTやPhindが生成する**コードは全く違って全然使えず**、人間が考えてコードを作成する必要があるようです。

従って、ChatGPTによって、**エンジニアの仕事が無くなるということは到底なさそう**です。
ChatGPTは、使いこなして人間の作業をより楽にするための助っ人として共存するような存在、ということが改めて分かりました。

#   参考

##   ChatGPTの始め方

記事: 【無料】チャットGPTの始め方を解説！

https://www.minotake-gadget.net/chatgpt-howto/

##   バージョン

ChatGPT 3.5
Phind V9 Model