はじめに
文脈で分かり切っている場合、年の部分を省略して、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ヶ月先なので過去側)
当処理部分のコード抜粋:
// (年指定なしの)月日から年月日へ変換
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);
}
テストコード
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