.dateDecodingStrategy는 JSONDecoder에서 날짜(Date)를 어떤 형식으로 파싱할지 정하는 옵션Codable을 사용할 때 Date 타입이 포함된 JSON을 자동으로 파싱할 수 있도록 도와주는 설정{
"title": "할 일",
"dueDate": "2025-06-21T14:00:00Z"
}
이런 JSON을 디코딩하려고 하는데,
struct Todo: Codable {
let title: String
let dueDate: Date
}
모델을 이렇게 만들면, Swift는 Date를 어떻게 파싱할지 모르기 때문에 에러가 발생함.
→ 이걸 해결해주는 게 바로 .dateDecodingStrategy❗️
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601 // 또는 .formatted(…) 등
let todo = try decoder.decode(Todo.self, from: jsonData)
| 전략 | 설명 | 예시 |
|---|---|---|
.iso8601 | ISO 8601 형식 지원 | "2025-06-21T14:00:00Z" |
.secondsSince1970 | 유닉스 초 기준 | 1729564800 |
.millisecondsSince1970 | 유닉스 밀리초 기준 | 1729564800000 |
.formatted(DateFormatter) | 커스텀 포맷 직접 지정 | "2025년 06월 21일" |
.custom((Decoder) throws -> Date) | 직접 파싱 로직 구현 | 복잡한 케이스 대응 |
// JSON
{
"title": "회의",
"dueDate": "2025-06-21 14:30:00"
}
// 파싱
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
DateFormatter를 세팅해줘야 정확히 파싱됨JSONDecoder는 기본적으로 하나의 dateDecodingStrategy만 설정 가능custom 활용[
{ "title": "회의", "date": "2025-06-21T14:30:00Z" }, // ISO 8601
{ "title": "점심", "date": "2025-06-21 12:00:00" }, // yyyy-MM-dd HH:mm:ss
{ "title": "리마인더", "date": "1729564800" } // Unix timestamp (초)
]
JSON의 날짜가 이렇게 서로 다르게 생겼다면 다음처럼 custom 전략을 만들어서 처리❗️
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom { decoder in
let container = try decoder.singleValueContainer()
// 1. 숫자일 경우 (Unix Time)
if let timestamp = try? container.decode(Double.self) {
return Date(timeIntervalSince1970: timestamp)
}
// 2. 문자열일 경우
let dateString = try container.decode(String.self)
// 시도할 포맷 배열
let formats = [
"yyyy-MM-dd'T'HH:mm:ssZ", // ISO 8601
"yyyy-MM-dd HH:mm:ss", // 일반 날짜+시간
"yyyy/MM/dd", // 다른 일반 날짜
"yyyyMMdd" // 연속된 숫자
]
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
for format in formats {
formatter.dateFormat = format
if let date = formatter.date(from: dateString) {
return date
}
}
throw DecodingError.dataCorruptedError(
in: container,
debugDescription: "지원하지 않는 날짜 형식: \(dateString)"
)
}
.custom 전략을 활용하면 다양한 날짜 형식을 유연하게 처리 가능DateFormatter 여러 개를 순서대로 시도해보고, 처리 가능한 첫 번째 포맷으로 파싱formats 배열만 수정하면 됨💡 날짜 인코딩(dateEncodingStrategy)도 가능
JSONEncoder에서Date타입을 어떤 형식으로 JSON 문자열로 바꿀지 지정하는 옵션- 즉, Swift 객체 → JSON으로 인코딩할 때
Date를 어떻게 문자열로 표현할지