API 에러 응답 설계 가이드 — HTTP Status는 대분류, 비즈니스 의미는 바디

개요 HTTP Status Code만으로는 서비스 로직의 원인을 전달하기 부족함 400대와 500대는 네트워크 관점의 대분류 신호에 가깝고 실제로 필요한 것은 비즈니스 맥락의 구체적 사유임 결론은 단순함 HTTP Status는 대분류 신호로 두고 실제 의미와 추가 컨텍스트는 Response Body에 싣는 구조가 현실적 해법임 핵심 원칙 HTTP Status는 큰 범주 신호등 역할 2xx 성공 4xx 클라이언트 오류 5xx 서버 오류 비즈니스 의미는 Response Body의 커스텀 에러 구조로 표현 클라이언트가 코드 기반으로 분기하고 UI를 결정할 수 있어야 함 운영 관측을 위해 traceId 제공 업계에서 검증된 기본 구조 아래 형태가 가장 보편적으로 쓰이는 패턴임 ...

December 31, 2025

date-fns로 자바스크립트 날짜·시간 처리 23가지 실전 패턴

개요 자바스크립트에서 날짜·시간을 다루는 일은 사소해 보이지만 버그가 가장 잦은 영역 중 하나임 day.js, moment.js, luxon 등 대안 존재하나 date-fns는 모듈화, 작은 크기, 불변성 중심 설계로 프런트엔드와 백엔드 모두에 적합함 아래는 date-fns와 date-fns-tz를 활용해 바로 써먹을 수 있는 23가지 패턴 정리 핵심 개념 Date 객체는 타임존이 아닌 UTC 타임스탬프를 보유하는 값이라는 점이 핵심 date-fns 함수는 대부분 불변 동작, 인자로 받은 Date를 변경하지 않음 포맷팅은 format, 상대 표기는 formatDistance 계열, 구간 계산은 differenceIn*, intervalToDuration 등 사용 파싱은 parseISO 또는 parse로 명시적 포맷 지정 권장 타임존 변환은 date-fns-tz의 utcToZonedTime, zonedTimeToUtc, formatInTimeZone 사용 실전 패턴 현재 날짜와 시간 가져오기 const now = new Date() 특정 날짜·시간 설정 import { setMinutes, setHours } from 'date-fns' const specific = setHours(setMinutes(new Date(), 30), 17) // 17:30 날짜 포맷팅 import { format } from 'date-fns' const ymd = format(new Date(), 'yyyy-MM-dd') 기간 더하기·빼기 import { addDays, subMonths } from 'date-fns' const inAWeek = addDays(new Date(), 7) const aMonthAgo = subMonths(new Date(), 1) 특정 요일까지 남은 일수 import { nextDay, differenceInDays } from 'date-fns' const nextMon = nextDay(new Date(), 1) // 0 일요일, 1 월요일 const d = differenceInDays(nextMon, new Date()) 두 날짜 차이 계산 import { differenceInDays } from 'date-fns' const diff = differenceInDays(new Date(2023, 11, 31), new Date(2023, 0, 1)) 동일한 날짜 비교 import { isSameDay } from 'date-fns' const same = isSameDay(new Date(2023, 0, 1), new Date('2023-01-01T05:00:00Z')) 윤년 확인 import { isLeapYear } from 'date-fns' const isLeap = isLeapYear(new Date(2024, 0, 1)) 날짜 유효성 검사 import { isValid } from 'date-fns' const ok = isValid(new Date('2023-02-30')) // false 로컬과 특정 타임존 간 변환 import { utcToZonedTime, zonedTimeToUtc, formatInTimeZone } from 'date-fns-tz' const tz = 'America/New_York' const utc = zonedTimeToUtc(new Date(), tz) const inNY = utcToZonedTime(new Date(), tz) const shown = formatInTimeZone(new Date(), tz, 'yyyy-MM-dd HH:mm:ssXXX') 문자열 파싱 import { parseISO, parse } from 'date-fns' const a = parseISO('2023-01-01') const b = parse('01/02/2023 17:30', 'MM/dd/yyyy HH:mm', new Date()) 상대 시간 표현 import { formatDistanceToNow } from 'date-fns' import { ko } from 'date-fns/locale' const rel = formatDistanceToNow(new Date(Date.now() - 3 * 24 * 60 * 60 * 1000), { addSuffix: true, locale: ko }) 과거·미래 판별 import { isPast, isFuture } from 'date-fns' const past = isPast(new Date('2023-01-01')) const future = isFuture(new Date(Date.now() + 60_000)) 특정 기간의 날짜 배열 생성 루프 대신 eachDayOfInterval 사용 권장 ...

December 17, 2025