Don't Use Your Brain for Time Calculations
Date/time handling becomes messy quickly. As soon as it's exposed to UI, 'padding', 'days of week', 'diff', and 'timezones' entangle, blowing up the code.
Don't Use Your Brain for Time Calculation: Fixing Format, Parse, Diff in One Flow
One Sentence Conclusion: Separate 'Format', 'Parse', and 'Diff' for date/time logic, and in Next.js, fix the execution context (server/client) to avoid wobbling.
Date/time handling becomes messy quickly. As soon as it's exposed to UI, 'padding', 'days of week', 'diff', and 'timezones' entangle, blowing up the code.
Point is simple. Don't create new helpers (padding function, string concat) every time. Use standard APIs or proven utils to solve it at once for better maintenance.
Background/Problem
Even with a single requirement, boilerplate creates itself instantly.
- “Show current time as
YYYY-MM-DD HH:mm:ss” - “Tell me the day of the week from a string”
- “Calculate days/weeks/months/years between two dates”
Native Date is capable, but usually we end up making helpers like format function + lpad.
function getFormattedDate(date) {
return `${date.getFullYear()}-${lpad(date.getMonth() + 1)}-${lpad(date.getDate())} ` +
`${lpad(date.getHours())}:${lpad(date.getMinutes())}:${lpad(date.getSeconds())}`;
}→ Expectation/Change: Requirements met, but helpers increase for one format, blurring reuse criteria.
Core Concept
Date/Time logic splits into 3 roles.
- Format: Convert to human-readable string
- Parse: Interpret string/input as Date object
- Diff: Calculate difference between two points in desired unit
Fixing the flow 'Input → Parse → Format/Diff' like the diagram below makes implementation simple.
→ Expectation/Change: Separate responsibilities for 'Format/Parse/Diff' so structure effectively handles code growth.
Solution Approach
Conclusion
Even starting with 'just one date format', parsing and calculation eventually follow.
So splitting into 3 roles from the start and fixing execution context in Next.js is the best defense.
| Option | Pros | Cons |
|---|---|---|
| Intl.DateTimeFormat | Standard, Minimal Dependencies | May need custom string assembly |
| Modular Utils (e.g. date-fns) | Use only what you need, clear composition | Team needs to unify format tokens/rules |
| Moment Style | Intuitive Format/Parse/Diff | Hard to bundle/tree-shake effectively |
1. 핵심: 역할 쪼개기 🔪
날짜 로직이 꼬이는 이유는 한 번에 너무 많은 걸 하려 하기 때문입니다. 다음 3가지 단계를 철저히 분리하세요.
- **입력(Parse)**: 문자열 -> Date 객체 (타임존 고려)
- **계산(Diff)**: Date 객체 -> UI 문자열 변환 전 로직
- **표현(Format)**: Date 객체 -> UI 문자열 (YYYY-MM-DD...)
2. 도구 선택장애 해결 🛠️
A. 표준 API (Intl.DateTimeFormat)
라이브러리 없이도 강력합니다. 특히 `formatToParts`는 포맷의 각 부분을 분해해서 커스텀하기 좋습니다.
3. Next.js와 시간의 밀당 (Hydration Error) ⚠️
서버 시간(UTC)과 클라이언트 시간(KST)이 다르면 Hydration Error가 발생합니다. **해결책**: 서버에서 고정된 문자열로 포맷팅해서 내려주거나, 클라이언트에서 `useEffect`로 갱신하세요.
마치며... 👋
시간 처리에 "대충"은 없습니다. 확실한 파이프라인을 구축하세요! 😉