年なしで月日だけ(M/D)と指定された時に、年を補って年月日(Y/M/D)で返す

# はじめに

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

# 処理方法

年部分無しでM/D(M月D日)と指定された時、今月とこの先のNヶ月は未来側の年月日として、それ以外は過去側の年月日として、年の部分を補って、DateTime型の値を返すようにします。

例えば、
例1: 現在が2024/2/1で、N=6とする時、
* 3/2と指定されたら2024/3/2と返す、(2月から1ヶ月先なので未来側)
* 8/3と指定されたら2024/8/3と返す、(2月から6ヶ月先なので未来側)
* 9/4と指定されたら2023/9/4と返す、(2月から7ヶ月先なので過去側)
* 12/5と指定されたら2023/12/5と返す、(2月から10ヶ月先なので過去側)
* 1/6と指定されたら2024/1/6と返す。(2月から11ヶ月先なので過去側)

例2: 現在が2024/10/31で、N=6とする時、
* 11/12と指定されたら2024/11/12と返す、(10月から1ヶ月先なので未来側)
* 1/13と指定されたら2025/1/13と返す、(10月から3ヶ月先なので未来側)
* 4/14と指定されたら2025/4/14と返す、(10月から6ヶ月先なので未来側)
* 5/15と指定されたら2024/5/15と返す、(10月から7ヶ月先なので過去側)
* 9/16と指定されたら2024/9/16と返す。(10月から11ヶ月先なので過去側)

当処理部分のコード抜粋: 
```C#
        // (年指定なしの)月日から年月日へ変換
        public static DateTime MonthDayToDateTime(int n_M, int n_D, // (年指定なしの)月日
            int n_M_future = 6, // 現在からnヶ月先までを未来側の年、11-nヶ月前までを過去側の年、として変換
            DateTime t_now = default) { // 現在日時

            if (t_now == default)
                t_now = DateTime.Now;

            // sec: 月の差を算出

            var n_M_diff = n_M - t_now.Month;
            if (n_M_diff < 0)
                n_M_diff += 12;

            if (n_M_diff <= n_M_future) // if: 現在からnヶ月先まで＝未来側
                ; // n_M_diffのまま
            else // if: それ以外＝過去側
                n_M_diff -= 12; // 負値にして過去側へ

            // sec: 年を算出

            var n_Y = t_now.AddMonths(n_M_diff).Year;
            return new DateTime(n_Y, n_M, n_D);
        }
```

# テストコード
```C#:Program 2401-1 月日から年月日へ変換.cs
using System;

namespace ConsoleApp1 {
    class Program {
        static void Main(string[] args) {
            /* 結果: OK
年なしで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と返す。

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;

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

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

        // (年指定なしの)月日から年月日へ変換
        public static DateTime MonthDayToDateTime(int n_M, int n_D, // (年指定なしの)月日
            int n_M_future = 6, // 現在からnヶ月先までを未来側の年、11-nヶ月前までを過去側の年、として変換
            DateTime t_now = default) { // 現在日時

            if (t_now == default)
                t_now = DateTime.Now;

            // sec: 月の差を算出

            var n_M_diff = n_M - t_now.Month;
            if (n_M_diff < 0)
                n_M_diff += 12;

            if (n_M_diff <= n_M_future) // if: 現在からnヶ月先まで＝未来側
                ; // n_M_diffのまま
            else // if: それ以外＝過去側
                n_M_diff -= 12; // 負値にして過去側へ

            // sec: 年を算出

            var n_Y = t_now.AddMonths(n_M_diff).Year;
            return new DateTime(n_Y, n_M, n_D);
        }
        public static DateTime MonthDayToDateTime(string text_MperD, // "M/d"形式の文字列
            int n_M_future = 6, // 現在からnヶ月先までを未来側の年、11-nヶ月前までを過去側の年、として変換
            DateTime t_now = default) { // 現在日時

            var t_MD = DateTime.ParseExact(text_MperD, "M/d", null);
            return MonthDayToDateTime(t_MD.Month, t_MD.Day, n_M_future, t_now);
        }
    }
}
```

# 環境
Microsoft Visual Studio Community 2019 Version 16.11.22
VisualStudio.16.Release
Microsoft .NET Framework
Version 4.8.04084
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606924/a80b2b96-ebec-1c6b-a5a2-700f34441206.png)