✅ Weekday 변환이 실제로 쓰이는 곳: buildWeekDates()
주간 요약을 만들기 위해서는 해당 주(일요일~토요일)에 어떤 날짜가 있는지 알아야 해.
예를 들어
2025년 11월 20일 이 포함된 주라면:
일: 11/16
월: 11/17
화: 11/18
수: 11/19
목: 11/20
금: 11/21
토: 11/22
이렇게 요일 → 날짜 매핑이 필요해.
그 역할을 하는 것이 바로:
func buildWeekDates(from interval: DateInterval)
🔥 문제는 Calendar의 요일 값이 ‘정수’라는 점이다.
Apple Calendar는 요일을 숫자로 줘:
| index | 요일 |
| 1 | Sunday |
| 2 | Monday |
| 3 | Tuesday |
| 4 | Wednesday |
| 5 | Thursday |
| 6 | Friday |
| 7 | Saturday |
하지만 우리가 앱에서 사용하는 요일 타입은 enum:
enum Weekday: String, CaseIterable {
case sun, mon, tue, wed, thu, fri, sat
}
즉,
Calendar → Int
우리 앱 → Weekday enum
👉 타입이 서로 안 맞음
👉 변환 과정 없이는 절대 정확한 매핑을 만들 수 없음
✨ 그래서 필요한 것이 바로 “weekdayIndex 초기화”
extension DiaryCoreDataManager.Weekday {
init?(weekdayIndex: Int) {
switch weekdayIndex {
case 1: self = .sun
case 2: self = .mon
case 3: self = .tue
case 4: self = .wed
case 5: self = .thu
case 6: self = .fri
case 7: self = .sat
default: return nil
}
}
}
이 코드는:
🟡 Calendar의 숫자 요일 → 앱의 enum 요일로 변환해주는 "다리"
🟡 잘못된 값이 들어오면 nil 처리 → crash 방지
🟡 어디서든 재사용 가능
📌 Weekday 변환이 buildWeekDates()에서 실제로 쓰이는 과정
buildWeekDates는 다음 일을 한다:
1. 주(weekInterval)의 시작일(일요일)부터 7일 반복
2. 매일 하루씩 증가
3. 요일 index(Int) 계산
4. 그 index를 enum Weekday로 변환 (바로 여기!)
5. 변환된 enum 요일에 해당 날짜를 저장
🔍 buildWeekDates 동작 코드 + 변환 적용
초보자도 바로 이해하도록 상세 주석을 추가해서 다시 정리하면:
/// 주간(일~토) 날짜를 요일 enum로 매핑해주는 함수
func buildWeekDates(from interval: DateInterval) -> [DiaryCoreDataManager.Weekday: Date] {
let cal = calendar
var dict: [DiaryCoreDataManager.Weekday: Date] = [:]
// 이번 주의 7일 반복
for offset in 0..<7 {
// 매일 하루씩 증가한 날짜
let day = cal.date(byAdding: .day, value: offset, to: interval.start)!
// Calendar 방식(1~7) 요일 index
let weekdayIndex = cal.component(.weekday, from: day)
// 요일 index(Int) → Weekday enum 변환
if let weekday = DiaryCoreDataManager.Weekday(weekdayIndex: weekdayIndex) {
dict[weekday] = day
}
}
return dict
}
📌 실행 흐름을 그림으로 이해해보자
주간 범위: 2025-11-16 ~ 2025-11-22
buildWeekDates는 다음을 수행함:
| offset | 날짜(day) | weekdayIndex(Int) | Enum 변환 | 결과 저장 |
| 0 | 11/16 | 1 | .sun | [.sun: 11/16] |
| 1 | 11/17 | 2 | .mon | [.mon: 11/17] |
| 2 | 11/18 | 3 | .tue | [.tue: 11/18] |
| 3 | 11/19 | 4 | .wed | [.wed: 11/19] |
| 4 | 11/20 | 5 | .thu | [.thu: 11/20] |
| 5 | 11/21 | 6 | .fri | [.fri: 11/21] |
| 6 | 11/22 | 7 | .sat | [.sat: 11/22] |
[
.sun: 11/16,
.mon: 11/17,
.tue: 11/18,
.wed: 11/19,
.thu: 11/20,
.fri: 11/21,
.sat: 11/22
]
이제 WeeklySummaryCell에서
1. 특정 날짜가 이번 달인지?
2. 이전 달 날짜인지?
3. 다음 달 날짜인지?
정확하게 판단할 수 있게 됨.
🤔 궁금증...
- 왜 offset = 0인데 weekdayIndex = 1이 나오냐?
- 왜 extension에 init? 생성자로 만들었나? 그냥 var로 mapping 하면 안 되나?
✅ 1. offset은 “일수 증가”이고, weekdayIndex는 “요일 번호”이다 (전혀 다른 값)
먼저 코드 상황을 보자:
for offset in 0..<7 {
let day = cal.date(byAdding: .day, value: offset, to: interval.start)!
let weekdayIndex = cal.component(.weekday, from: day)
}
확실히 offset = 0이면 → interval.start 날짜 그대로지?
그런데 weekdayIndex는 offset과 전혀 상관없다.
📌 weekdayIndex란?
Calendar.component(.weekday, from:) 는 달력 기준의 요일 번호를 반환한다:
| iOS weekdayIndex | 요일 |
| 1 | 일요일 |
| 2 | 월요일 |
| 3 | 화요일 |
| 4 | 화요일 |
| 5 | 목요일 |
| 6 | 금요일 |
| 7 | 토요일 |
즉, offset은 단순히 날짜 증가를 위한 "반복자"이고,
weekdayIndex는 날짜(day)가 실제 달력에서 어떤 요일인지에 따라 정해진 값이다.
🔎 예시
예를 들어 interval.start = 2025-11-16 (일요일)이면:
1. offset = 0
→ 날짜: 2025-11-16
→ 요일: 일요일
→ weekdayIndex = 1
2. offset = 1
→ 날짜: 2025-11-17
→ 요일: 월요일
→ weekdayIndex = 2
3. offset = 2
→ 날짜: 2025-11-18
→ 요일: 화요일
→ weekdayIndex = 3
이런 식으로 offset 값과 weekdayIndex는 완전히 다른 개념이야.
✅ 2. 왜 extension에 init?(weekdayIndex:) 형태의 초기화를 사용했나?
바로 이 문제 때문이야:
📌 Calendar는 요일을 Int로 준다
하지만
📌 우리는 요일을 enum Weekday로 관리한다
Int → Weekday enum
이 변환이 자주 필요함.
그래서 아래처럼 생성자로 제공하는 것이 가장 Swift스러운 방법이야:
init?(weekdayIndex: Int) {
switch weekdayIndex {
case 1: self = .sun
case 2: self = .mon
case 3: self = .tue
case 4: self = .wed
case 5: self = .thu
case 6: self = .fri
case 7: self = .sat
default: return nil
}
}
✔️ init이 가장 좋은 이유 정리
1. Swift의 타입 변환 규칙과 동일하다
2. 코드 읽을 때 역할이 명확하다
3. 실패 가능성(nil)을 자연스러운 optional initializer로 표현할 수 있다
4. 호출이 깔끔하다:
if let weekday = Weekday(weekdayIndex: weekdayIndex) {
dict[weekday] = day
}'감정일기(가칭)' 카테고리의 다른 글
| 📅 Swift로 "주차(Week Number)" 계산하는 법 완전 정리 (0) | 2025.11.21 |
|---|---|
| 👉 주어진 날짜(date)가 속한 “주(week)”의 시작 요일(일요일)을 구하는 함수 & 일요일 ~ 토요일까지의 범위(DateInterval)를 생성하는 함수 (0) | 2025.11.21 |
| Popover 위에 “어두운 배경(딤)” 깔고 싶다 (0) | 2025.11.19 |
| 📌 화면 진입 시 감정 선택창 자동 오픈하기, 저장 완료 후 화면 닫기 처리 (0) | 2025.11.18 |
| 📑 DiaryEditor 유효성 검사 설계부터 UI 처리까지 (0) | 2025.11.18 |