나이 개월·일 계산 두 종을 순수 함수로 옮긴다 — 레거시가 달력을 안 쓴다

CTX 126종 배치의 시작. 본문을 정확히 읽은 둘만 넣는다 —
나머지 세 변형(_00Months_00Days · _개월_00일 · _00개월_일)은 형식이 다를 수 있어
읽기 전에는 넣지 않는다.

## 레거시가 이상해 보이지만 그대로 옮긴 것 둘

**PAT_나이_개월수** = `DateDiff(Month, PatBthDay, SystemDate) - 1`
VB 의 DateDiff(Month, ...) 는 <b>날짜를 보지 않고 월 경계만</b> 센다(연차×12 + 월차).
그래서 1일생과 말일생이 같은 값이 나오고, 같은 달이면 -1 이 찍힌다.
일수로 환산하면 레거시와 다른 수가 된다 — 판정으로 못 박았다.

**PAT_나이_00개월_00일** = `days \ 30 & "개월 " & days Mod 30 & "일"`
달력이 아니라 <b>30일로 나눈다</b>. 365일이 "12개월 5일"이 된다.
달력으로 고치면 값이 달라진다.

## 내 산수가 틀렸다

기대값을 처음에 11로 적었다. 2025-01 → 2025-12 는 월 경계 11 이고
거기서 1을 빼면 10 이다. 구현이 아니라 판정이 틀렸고, 테스트가 그것을 잡았다.

## 아직 배선하지 않았다

두 함수는 "오늘"이 필요한데 해석기에 그 값을 넣는 배선(서버 시각 1회 읽기)이 남았다.
컨텍스트가 부족해 배선까지 하면 게이트를 못 돌리므로, 검증된 순수 함수만 먼저 넣는다.
다음 세션 첫 작업이 배선이다.

## 게이트

- dotnet test 338/338 (나이 판정 2건 신규)
- --edit-smoke 실패 0
- --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Msystech
2026-08-19 12:03:18 +09:00
co-authored by Claude Opus 5
parent 99b8aaa9c2
commit 5ec31cee41
2 changed files with 68 additions and 0 deletions
@@ -105,5 +105,48 @@ public static class ResidentNumber
}
private static string Clean(string? value) => (value ?? string.Empty).Trim();
/// <summary>
/// 생년월일부터 오늘까지의 <b>개월수</b> — 레거시 <c>PAT_나이_개월수</c>
/// (<c>DateDiff(Month, PatBthDay, SystemDate) - 1</c>).
///
/// VB 의 <c>DateDiff(Month, ...)</c> 는 날짜를 보지 않고 <b>월 경계만 센다</b>
/// (연차×12 + 월차). 거기서 1을 뺀 값이 태그의 결과다.
/// 일수로 환산하지 않는다 — 환산하면 레거시와 다른 수가 나온다.
/// </summary>
public static string MonthsSince(string? birthDay, string? todayYmd)
{
var birth = Clean(birthDay);
var today = Clean(todayYmd);
if (birth.Length < 6 || today.Length < 6
|| !int.TryParse(birth[..4], out var by) || !int.TryParse(birth.Substring(4, 2), out var bm)
|| !int.TryParse(today[..4], out var ty) || !int.TryParse(today.Substring(4, 2), out var tm))
{
return string.Empty;
}
return (((ty - by) * 12) + (tm - bm) - 1).ToString();
}
/// <summary>
/// "N개월 N일" — 레거시 <c>PAT_나이_00개월_00일</c>.
///
/// <b>달력이 아니라 30일로 나눈다</b>(<c>days \ 30</c>, <c>days Mod 30</c>).
/// 실제 개월수와 다르지만 레거시가 그렇게 찍는다 — 달력으로 고치면 값이 달라진다.
/// </summary>
public static string MonthsDaysSince(string? birthDay, string? todayYmd)
{
var birth = Clean(birthDay);
var today = Clean(todayYmd);
if (birth.Length < 8 || today.Length < 8
|| !DateTime.TryParseExact(birth[..8], "yyyyMMdd", null,
System.Globalization.DateTimeStyles.None, out var from)
|| !DateTime.TryParseExact(today[..8], "yyyyMMdd", null,
System.Globalization.DateTimeStyles.None, out var to))
{
return string.Empty;
}
var days = (int)(to - from).TotalDays;
return $"{days / 30}개월 {days % 30}일";
}
#endregion
}