[개발 회고] date-only 문자열과 full datetime은 같지 않다
date-only 문자열과 full datetime은 같지 않다
개발 회고 — 2026-07-28 (화)
오늘 작업 요약
대규모 그리드 리팩토링 브랜치를 메인 개발 브랜치로 병합하고, 그 과정에서 발견된 타입 불일치와 문법 오류를 수정했다. 동시에 캘린더의 날짜 계산과 타임존 처리 관련 버그 두 건을 근본 원인부터 해결했고, 테스트 환경 의존성 문제도 함께 정비했다.
- 그리드 셀의 헤더 아이콘 갱신 로직 정비 — 유효성 검사 함수 통일, 아이콘 크기 반영 누락 수정
- 대규모 리팩토링 브랜치를 메인으로 병합 — 리베이스 중 발생한 문법 오류와 토큰 참조 불일치 사전 수정
- 리스트뷰의 날짜 계산을 실제 달력 점유 기준으로 통일 — 날짜 범위 계산 버그 수정, 계산 함수 재추출로 중복 제거
- 프레임 최초 저장 시 ID 치환 로직 통합 — 여러 곳에 흩어져 있던 ID 치환 코드를 한곳으로 모음
- 캘린더 더보기 팝오버의 타임존 버그 2건 수정 — date-only 문자열과 full datetime의 파싱 경로 차이로 인한 오류 해결
- 캘린더 타임존 회귀 테스트 환경 의존성 제거 — 특정 타임존을 전제하던 테스트를 실행 환경에 무관하게 재작성
커밋 요약: 6개 주요 커밋, 캘린더/프레임/그리드 여러 컴포넌트 변경
STAR 정리
Situation (상황)
그리드 리팩토링 브랜치를 메인으로 병합하려던 중, 리베이스 과정에서 불완전한 코드 병합(dangling condition)이 있었고, 토큰 참조 이름이 리팩토링 후 달라진 부분이 있었다. 한편 캘린더에서는 리스트뷰의 날짜 계산이 두 가지 다른 방식으로 구현되어 있어 결과가 일치하지 않는 버그가 있었고, 더보기 팝오버에서 날짜 문자열을 파싱할 때 “날짜만” 형식과 “날짜+시간” 형식을 구분하지 않아 타임존에 따라 값이 하루씩 어긋나는 현상이 발생했다. 또한 타임존 테스트가 특정 타임존(UTC보다 큰 오프셋)을 전제하고 있어 CI 환경(UTC)에서는 실패하는 상황이었다.
Task (과제)
- 리팩토링 브랜치 병합 시 발생한 문법 오류와 참조 불일치 수정
- 리스트뷰 날짜 계산 로직을 통일해 결과의 일관성 확보
- 프레임 저장 시 ID 치환 로직을 여러 곳에서 하나로 통합
- 캘린더의 date-only vs full datetime 파싱 경로 차이로 인한 버그 해결
- 타임존 테스트를 실행 환경에 무관하게 재설계
Action (행동)
- 그리드 셀의 헤더 아이콘 갱신 로직에서, 유효성을 검사하는 함수를 여러 이름으로 호출하던 것을 하나로 통일하고, 아이콘 크기를 반영하지 않던 부분을 수정함
- 리팩토링 브랜치의 리베이스 중에 발생한 불완전한 조건 분기(else-if 없이 끝나는 구문)를 찾아 수정하고, 토큰 이름이 변경된 부분을 현재 코드베이스 버전으로 맞춤
- 리스트뷰의 날짜 범위를 계산하는 로직을 분석해, 버그가 있는 버전을 고정하고, 동일한 계산을 하는 다른 함수와 중복을 제거하기 위해 계산 함수를 재추출함
- 프레임 저장 시 ID 치환이 두 가지 다른 저장 경로(단일 저장, 배치 저장)에서 각각 다르게 구현되어 있던 것을 발견하고, 이를 한곳으로 모은 통합 함수로 정리함
- 캘린더 더보기 팝오버에서 날짜 문자열을 파싱할 때, “YYYY-MM-DD” 형식(date-only)의 문자열을 UTC로 파싱하면 타임존 오프셋에 따라 실제 날짜가 하루씩 어긋나는 문제를 발견함. 이를 “날짜+시간”이 포함된 전체 datetime 형식으로 통일해 해결함
- 타임존 회귀 테스트가 Asia/Seoul(UTC+9) 타임존을 전제하고 있어 UTC 환경의 CI에서 실패하는 문제를 확인하고, 테스트가 특정 타임존에 의존하지 않고 계산 결과의 일관성을 검증하도록 재작성함
Result (결과)
- 리팩토링 브랜치가 성공적으로 메인으로 병합됨
- 리스트뷰 날짜 계산의 일관성이 확보됨
- 프레임 ID 치환 로직이 중앙화되어 누락이나 불일치 위험이 감소함
- 캘린더의 타임존 관련 버그 2건이 근본 원인부터 해결됨 — 이제 date-only와 full datetime이 구분되어 파싱됨
- 타임존 테스트가 모든 타임존 환경에서 결정적으로 통과하도록 개선됨
- 신규 테스트 53개가 추가되었으나, 일부 엣지 케이스(DST 경계, 분단위 UTC 오프셋 등)는 아직 검증 전 상태
실제 측정 가능한 지표
| 지표 | 확인 방법 | 비고 |
|---|---|---|
| 병합된 커밋 수 | git log (merge commit 포함) |
리팩토링 브랜치의 전체 커밋 수 확인 가능 |
| 수정된 문법 오류 개수 | 리베이스 과정에서 수정한 dangling condition 개수 | 1곳 이상 |
| 토큰 참조 불일치 지점 | 코드베이스에서 구 토큰명으로 검색 | 리팩토링 전후 불일치한 참조 개수 |
| 추가된 회귀 테스트 수 | 테스트 파일의 신규 it()/test() 블록 수 |
53개 |
| Date-only vs full datetime 파싱 차이 | 더보기 팝오버에서 두 형식을 각각 파싱한 결과 비교 | 타임존에 따라 하루 차이 확인됨 (수정 후 일치) |
| 타임존 테스트의 CI 통과 여부 | CI 환경(UTC)에서의 테스트 실행 결과 | 환경 의존성 제거 후 일관되게 통과 |
추정 가능한 효과 (근거 포함)
- 프레임 ID 치환 로직 중앙화로 회귀 위험 감소 (추정): 여러 곳에 흩어져 있던 ID 치환 코드를 한곳으로 모으면서, 새로운 저장 경로가 추가되어도 중앙 함수만 호출하면 되는 구조가 됨. 근거: ID 치환을 전담하는 통합 함수가 작성되고, 기존 두 가지 저장 경로에서 이를 호출하도록 변경된 것을 확인함. 이후 새로운 저장 경로가 추가될 때 이 함수를 빠뜨릴 가능성이 감소함
- date-only/full datetime 파싱 통일로 타임존 버그 재발 방지 (추정): 날짜 문자열을 파싱할 때 일관된 형식(full datetime)을 사용하면서, 타임존 오프셋에 따라 계산이 달라지는 버그가 재발할 가능성이 줄어들 것으로 예상됨. 근거: 더보기 팝오버의 날짜 소스를 full datetime 형식으로 통일한 것을 확인함. 다만 캘린더 라이브러리의 다른 부분에서 date-only 파싱이 남아있는지는 아직 확인 전
- 타임존 테스트 환경 의존성 제거로 CI 안정성 향상 (추정): 테스트가 특정 타임존을 전제하지 않고 상대적인 계산 결과의 일관성을 검증하도록 재작성됨으로써, 모든 타임존 환경에서 일관되게 통과할 수 있게 됨. 근거: 테스트가 절대 UTC offset 값 대신 계산 결과의 동일성을 검증하도록 변경된 것을 확인함
더 측정하면 좋은 지표
- date-only 파싱이 캘린더 코드베이스에 남아있는지 전수 조사: grep으로 패턴 검색해 모든 date-only 파싱 위치 파악
- 타임존 엣지 케이스 검증: DST 경계(봄/가을 시간 변경), 분단위 UTC 오프셋(인도 등), 음수 UTC offset 지역에서의 동작 확인
- 프레임 ID 치환 로직의 실제 사용처: 저장 경로 외에 프레임 상태 갱신 시에도 이 함수가 일관되게 호출되는지 확인
- 리스트뷰 날짜 계산 통일 후 실제 표시 변화: 사용자 화면에서 리스트뷰의 날짜 범위 표시가 실제로 달라졌는지 시각적 검증
- 신규 테스트 53개의 실제 커버리지: 코드 커버리지 도구로 리스트뷰/더보기 팝오버/프레임 저장 코드의 실제 커버리지 확인
오늘 배운 것
- 날짜 문자열과 datetime 문자열을 파싱할 때 사용되는 함수가 다르면, 타임존 오프셋에 따라 계산 결과가 달라질 수 있다는 것을 다시 확인함. “날짜만”을 의도하는 경우도 유연한 datetime 형식으로 감싸서 처리하면 일관성을 높일 수 있다는 점
- 테스트 코드의 전제(특정 타임존의 UTC offset 부호)가 실행 환경에 종속되면, 로컬과 CI에서 다른 결과를 낼 수 있다는 것을 실감함. 결정적인 테스트는 환경 변수에 좌우되지 않도록 상대적 검증으로 설계해야 함
- 같은 기능이 여러 코드 경로에서 구현되어 있으면(프레임 ID 치환의 두 가지 저장 경로), 누락이나 불일치가 발생하기 쉬우므로 한곳으로 모아 관리하는 것이 유지보수에 유리하다는 것을 다시 배움
- 대규모 리팩토링 브랜치를 병합할 때는 리베이스 과정에서 문법 오류가 생기기 쉬우므로, 병합 전에 문법 체크와 참조 검증을 반드시 거쳐야 한다는 점
어려웠던 점 / 막힌 부분
- 캘린더 더보기 팝오버의 타임존 버그를 파악하는 데 시간이 걸렸음. date-only와 full datetime 파싱의 경로 차이가 여러 함수에 산재되어 있어서, 각 함수의 입출력을 추적해야 근본 원인을 찾을 수 있었음
- 타임존 회귀 테스트가 로컬 환경(Asia/Seoul)에서는 통과하지만 CI(UTC)에서 실패하는 문제를 재현하는 데 시간이 걸렸음. 환경 변수를 바꿔가며 테스트를 반복해 원인을 특정할 수 있었음
- 프레임 ID 치환 로직이
saveFrameInfo와saveFramesBatch두 경로에서 각각 다르게 구현되어 있었는데, 이를 모두 찾아내기 위해 코드베이스를 전수 검색해야 했음
내일 하면 좋은 작업
- 추가 타임존 엣지케이스 검증 — DST 경계, 분단위 UTC 오프셋, 캘린더 라이브러리의 exclusive-end 보정 자체가 타임존 변경에 강한지 확인
- 신규 테스트 53개의 커버리지 최종 점검 — 9개 파일 범위에서 실제 커버되지 않은 분기가 있는지 확인
- 배치 저장 시 다중 프레임 순서, contentCollapsedFrameIds 중복 같은 엣지케이스 확인
한 줄 요약
대규모 리팩토링 브랜치를 성공적으로 병합하고, date-only와 full datetime의 파싱 차이로 인한 타임존 버그를 근본부터 해결하며, 테스트 환경 의존성까지 제거한 종합적인 정산의 하루였다.
댓글남기기