---
title: "📓 작업일지 — 엑셀 날짜 숫자셀 하루 밀림 차단 (serial 직접분해로 타임존 의존성 제거)"
category: "worklog"
parent: "Claude Code 작업일지"
updated: "2026-08-11"
priority: "High"
purpose: "데이터 가져오기(dataBackup.ts)의 parseDateCell이 엑셀 서식 없는 순수 숫자 serial 날짜를 UTC 기준 ms → 로컬 getter 경로로 변환하면서, 시각 성분이 로컬 자정을 넘나들 때(또는 UTC 음수 오프셋 지역) 날짜가 하루 밀리던 결함을 SSF.parse_date_code() 직접분해로 근본 수정한 기록."
read_when: ["parseDateCell", "엑셀 날짜 하루 밀림", "dataBackup.ts import", "SSF.parse_date_code", "타임존 날짜 오프바이원"]
document_type: "개발일지"
source_status: "generated"
knowledge_group: "03_history"
work_timestamp: "20260811_173228"
source_of_truth: "https://dallog-tools.hansbridge.co.kr/knowledge/"
context: "달록 본레포(ccy-hansbridge/dallog), 커밋 26448fc8(2026-08-11). 엑셀 날짜 숫자셀 하루 밀림 차단 — serial 직접분해로 타임존 의존성 제거."
---

# 작업일지 — 엑셀 날짜 숫자셀 하루 밀림 차단 (serial 직접분해로 타임존 의존성 제거)

> `dataBackup.ts`의 `parseDateCell`에서, 셀 서식이 없는 순수 숫자(serial) 날짜를 처리하는 분기가 `new Date(UTC 기준 ms)`로 변환한 뒤 로컬 getter(`isoOf`)로 연·월·일을 읽는 구조였다. 이 조합은 시각 성분이 로컬 자정을 넘나드는 경우(그리고 UTC 음수 오프셋 지역에서는 시각 성분이 없어도 상시) 날짜가 하루 밀리는 결함으로 이어졌다.

## 1. 무엇을 했나

- 원인: SheetJS 자체 `cellDates` 변환(`numdate`)은 로컬 기준(naive) 왕복이라 안전하지만, 이 분기는 직접 구현한 UTC-anchored 변환이라 그 관례와 어긋났던 것이 하루 밀림의 근본 원인.
- 조치: `XLSX.SSF.parse_date_code()`로 연·월·일만 직접 분해해, `Date` 인스턴스와 타임존을 완전히 배제하는 방식으로 근본 해결.
- 검증: 커밋 메시지 기준 Asia/Seoul·America/New_York·UTC·Pacific/Kiritimati 4개 타임존에서 자정 근접 시각을 포함한 재현 테스트로 검증(모두 2026-07-20 고정일로 확인).
- 커밋 메시지 기준, 로컬 pre-commit 훅(`scripts/deleted-path-ref-guard.cjs`)이 demo-dallog 전용이라 main 기반 브랜치에는 파일이 없어 훅 실행 자체가 MODULE_NOT_FOUND로 실패(가드 위반 아님) → 이전 커밋(f33740d9)과 동일 사유로 오너 승인 하 `--no-verify` 반복 우회.

## 2. 주요 변경 파일

| 파일 | 내용 |
|---|---|
| `src/lib/dataBackup.ts` | `parseDateCell`의 numeric 분기를 `SSF.parse_date_code()` 직접분해 방식으로 교체(+6/-3줄) |

### 변경 내용

```diff
   if (typeof raw === 'number') {
-    // 엑셀 serial (1900 시스템) → JS Date
-    const d = XLSX.SSF ? new Date(Math.round((raw - 25569) * 86400 * 1000)) : null
-    if (d && !isNaN(d.getTime())) return { ok: true, iso: isoOf(d) }
+    // 엑셀 serial(1900 시스템) → 연·월·일만 직접 분해(SSF.parse_date_code, 타임존 무관).
+    //   과거 new Date(UTC 기준 ms)+로컬 getter 조합은 시각 성분이 자정을 넘나들 때 하루 밀림(2026-08-11 확인).
+    const dc = XLSX.SSF ? XLSX.SSF.parse_date_code(raw) : null
+    if (dc && Number.isFinite(dc.y) && Number.isFinite(dc.m) && Number.isFinite(dc.d)) {
+      return { ok: true, iso: `${dc.y}-${pad(dc.m)}-${pad(dc.d)}` }
+    }
     return { ok: false, reason: '날짜 숫자 오류' }
   }
```

## 3. 관련 커밋

- `26448fc8` fix(import): 엑셀 날짜 숫자셀 하루 밀림 차단 — serial 직접분해로 타임존 의존성 제거 (2026-08-11)

## 4. 남은 이슈

커밋 메시지 기준 별도로 언급된 남은 이슈는 없음.
