나이 계열 7종·주민번호 마스킹 3종 — 215종 → 225종 (조사 라운드 7 시작)

PAT_나이(bzDataInterface.vb:373 Case Else — 통합 대표행의 AgeMonth
파생 컬럼과 같은 식을 SQL 로: UDF_GETAGE_FROMRESNUM(복호화, 적용일시),
dtCommonLib.vb:3725 확인. CGCH 분기·암호화 N 갈래 미이식),
PAT_나이_세(:417 — 산정코드 24* 는 UDF_GETAGE(PatBthDay), 그 밖은
AgeCheck), PAT_성별_나이(:359 — "성별/나이". HIMCHAN_BP·BSYD 분기
미이식), PAT_나이_개월수(:430 — 월 경계 -1, 기존 MonthsSince 재사용),
개월·일 4종(:436-508 — 30일 나눗셈, 새 DaysSince 로 분해).

AgeCheck(clsCommonLib.vb:665-974)를 ResidentNumber.AgeOf 로 이식 —
세기 접두 규칙(1·2→19, 3·4→20, 5·6→출생2자리<20 이면 20xx 아니면
19xx+월일 0101 강제, 7·8→서버 연도 2자리 비교, 그 외→18xx. REDCROSS·
BSYD·BSGH 특례 미이식), 만나이(생일 당일 차감 없음 — 2024-09-25 이후
전 병원 규칙), 1세 이하는 고정 365일. 테스트 5건 — 기대값 하나가
틀려 있었다(출생 2자리 "20"은 <20 이 아니라 1920년으로 강제 — 구현이
맞고 판정을 고침). 개월·일 4종의 기준일은 레거시가 PC 시계(Now)라
서버 오늘로 바꿈(의도적 이탈 — 단말마다 값이 갈리면 안 된다).

PAT_주민번호_Blind/SexTyp_Blind/SexTyp_BlindStar(:105-186 Case Else —
앞6 " - " 뒤 XXXXXXX / 성별1+XXXXXX / 성별1+******. SYBS 의 J-계열
서식 전체 노출 분기 미이식).

대조군 교체: PAT_나이가 이식되면서 ⑬·edit-smoke 의 "안 옮긴 태그"
대조군이 깨졌다(의도된 동작) — ETC_수술실간호사로 교체.
㊱ 신설: 나이 UDF 2종이 실값을 돌려준다(접두 없이 동작 확인).

- dotnet test 342/342 (AgeOf 5건 추가) · --edit-smoke 실패 0
- --db-patient ①~㊱ 전건 통과
- --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Msystech
2026-08-20 08:41:22 +09:00
co-authored by Claude Fable 5
parent abb08d0c6b
commit 8256b79800
6 changed files with 352 additions and 13 deletions
@@ -165,5 +165,44 @@ public sealed class ResidentNumberTests
Assert.AreEqual("880101 - 1234567", ResidentNumber.WithDash("8801011234567"));
Assert.AreEqual("880101", ResidentNumber.WithDash("880101"));
}
[TestMethod]
public void _세기_접두를_7번째_자리로_정한다()
{
// 1·2 → 19xx, 3·4 → 20xx (AgeCheck, clsCommonLib.vb:686-700)
Assert.AreEqual(38L, ResidentNumber.AgeOf("8801011234567", "20260820", "20260820"));
Assert.AreEqual(6L, ResidentNumber.AgeOf("2001013234567", "20260820", "20260820"));
// 7·8 — 서버 오늘의 연도 2자리(26)보다 크면 19xx: 88 > 26 → 1988년생
Assert.AreEqual(38L, ResidentNumber.AgeOf("8801017234567", "20260820", "20260820"));
// 그 외(9) → 18xx
Assert.AreEqual(138L, ResidentNumber.AgeOf("8801019234567", "20260820", "20260820"));
}
[TestMethod]
public void _생일_전이면_하나_줄고_당일은_줄지_않는다()
{
Assert.AreEqual(37L, ResidentNumber.AgeOf("8812311234567", "20260820", "20260820"));
Assert.AreEqual(38L, ResidentNumber.AgeOf("8808201234567", "20260820", "20260820"));
}
[TestMethod]
public void _살_이하는_고정_365일로_가른다()
{
// 총 일수차 < 365 → 0세, 이상 → 1세 (윤년 무시 — 레거시 고정 365)
Assert.AreEqual(0L, ResidentNumber.AgeOf("2510013234567", "20260820", "20260820"));
Assert.AreEqual(1L, ResidentNumber.AgeOf("2501013234567", "20260820", "20260820"));
Assert.AreEqual(0L, ResidentNumber.AgeOf("", "20260820", "20260820"));
}
[TestMethod]
public void _5_6은_출생_2자리로_갈린다()
{
// 출생 2자리 < 20 → 20xx 그대로, >= 20 → 19xx + 월일 0101 강제.
// 경계 주의: "20" 은 < 20 이 아니라서 2020년생이 아니라 1920-01-01 로 강제된다(레거시 그대로)
Assert.AreEqual(20L, ResidentNumber.AgeOf("0601015234567", "20260820", "20260820"));
Assert.AreEqual(106L, ResidentNumber.AgeOf("2001015234567", "20260820", "20260820"));
// 88 >= 20 → 1988-01-01 로 강제 → 만 38세
Assert.AreEqual(38L, ResidentNumber.AgeOf("8812315234567", "20260820", "20260820"));
}
#endregion
}