Calendar 를 사용하면 날짜를 다룰 수 있습니다
Calendar 구조체는 달력 단위 (일, 월, 연도)와 절대적인 시간 지점 사이의 관계를 정의합니다.
추가로 Calendar는 날짜를 계산하고 비교하는 기능을 제공합니다.
Calendar는 연도의 시작, 길이, 그리고 분할을 정의하는 시간 계산 시스템에 관한 정보를 캡슐화합니다. 이 구조체는 달력에 대한 정보를 제공하고, 주어진 달력 단위의 범위를 결정하거나 절대 시간에 단위를 추가하는 등의 달력 계산을 지원합니다.
Calendar 만들기
enum Calendar.Identifier
이용 가능한 캘린더들의 종류를 담고 있는 enumeration 입니다.
- buddhist
- 불교 달력의 식별자입니다.
- chinese
- 중국 달력의 식별자입니다.
- coptic
- 콥트 달력의 식별자입니다.
- ethiopicAmeteAlem
- 에티오피아의 아메테 알렘 달력의 식별자입니다.
- ethiopicAmeteMihret
- 에티오피아의 아메테 미흐렛 달력의 식별자입니다.
- gregorian
- 그레고리력의 식별자입니다.
- hebrew
- 히브리 달력의 식별자입니다.
- indian
- 인도 달력의 식별자입니다.
- islamic
- 이슬람 달력의 식별자입니다.
- islamicCivil
- 이슬람 시민 달력의 식별자입니다.
- islamicTabular
- 이슬람 표 달력의 식별자입니다.
- islamicUmmAlQura
- 사우디아라비아에서 사용되는 이슬람 움 알-쿠라 달력의 식별자입니다.
- iso8601
- ISO8601 달력의 식별자입니다.
- japanese
- 일본 달력의 식별자입니다.
- persian
- 페르시아 달력의 식별자입니다.
- republicOfChina
- 중화민국(대만) 달력의 식별자입니다.
유저의 캘린더 가져오기
static var autoupdatingCurrent: Calendar
- locale 또는 timeZone 를 현재 사용자가 선호하는 달력 변경 사항에 맞게 자동으로 설정해줍니다.
- 이것은 사용자가 시스템 설정에서 달력을 변경하면 자동으로 업데이트됩니다.
- 예를들어 달력을 인도달력으로 변경하면 이 속성은 자동을 인도달력에 맞게 설정합니다.
var calendar = Calendar(identifier: .iso8601)
calendar.locale = .autoupdatingCurrent
calendar.timeZone = .autoupdatingCurrent
static var current: Calendar
- 시스템 설정에서 선택한 달력을 반영하며 autoupdatingCurrent와 달리 사용자 설정이 변경되더라도 자동 업데이트 되지 않고 프로그램 실행 시점의 사용자 설정을 기준으로 달력을 제공합니다.
let today = Date()
let calendar = Calendar.current
let year = calendar.component(.year, from: today)
let month = calendar.component(.month, from: today)
let day = calendar.component(.day, from: today)
print("오늘은 \(year)년 \(month)월 \(day)일입니다.")
캘린더 구성요소 추출하기
func date(Date, matchesComponents: DateComponents) -> Bool
- 주어진 날짜(Date)가 지정된 날짜 구성 요소(DateComponents)와 모두 일치하는지 확인합니다.
let calendar = Calendar.current
let date = Date()
var components = DateComponents() // 일요일인지 확인
components.weekday = 1 // 일요일
let isSunday = calendar.date(date, matchesComponents: components)
print("오늘이 일요일인가? \(isSunday)")
func component(Calendar.Component, from: Date) -> Int
- 특정 날짜 구성 요소(예: 연도, 월, 일)의 값을 반환합니다.
let calendar = Calendar.current
let date = Date()
let year = calendar.component(.year, from: date)
print("현재 연도는 \(year)입니다.")
func dateComponents(Set<Calendar.Component>, from: Date) -> DateComponents
- 주어진 날짜의 모든 구성 요소를 반환합니다. 반환된 구성 요소는 달력의 시간대를 사용합니다.
let calendar = Calendar.current
let date = Date()
let components: Set<Calendar.Component> = [.year, .month, .day]
let dateComponents = calendar.dateComponents(components, from: date)
print("현재 날짜 구성 요소: \(dateComponents)")
func dateComponents(Set<Calendar.Component>, from: Date, to: Date) -> DateComponents
- 두 날짜 사이의 차이를 반환합니다.
let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2024, month: 8, day: 1))!
let endDate = calendar.date(from: DateComponents(year: 2024, month: 8, day: 11))!
let components: Set<Calendar.Component> = [.day, .hour]
let difference = calendar.dateComponents(components, from: startDate, to: endDate)
print("날짜 차이: \(difference.day!)일")
- 두 날짜를 DateComponents 형식으로 지정하여 그 차이를 반환합니다.
let calendar = Calendar.current
let startComponents = DateComponents(year: 2024, month: 8, day: 1)
let endComponents = DateComponents(year: 2024, month: 8, day: 11)
let components: Set<Calendar.Component> = [.day]
let difference = calendar.dateComponents(components, from: startComponents, to: endComponents)
print("날짜 차이: \(difference.day!)일")
func dateComponents(in: TimeZone, from: Date) -> DateComponents
- 특정 시간대에 있는 것처럼 날짜의 모든 구성 요소를 반환합니다.
let calendar = Calendar.current
let date = Date()
let timeZone = TimeZone(identifier: "America/New_York")!
let dateComponents = calendar.dateComponents(in: timeZone, from: date)
print("뉴욕 시간대의 날짜 구성 요소: \(dateComponents)")
- 달력 날짜의 다양한 구성 요소를 나타내는 열거형입니다. 예를 들어, 연도, 월, 일, 시, 분, 초 등과 같은 다양한 날짜 및 시간 단위를 나타냅니다.
-
- .year: 연도
- .month: 월
- .day: 일
- .hour: 시간
- .minute: 분
- .second: 초
- .weekday: 요일
- .weekdayOrdinal: 주간 차수 (예: 매월의 첫 번째 일요일)
- .quarter: 분기
- .weekOfMonth: 월의 주
- .weekOfYear: 연도의 주
- 기타 날짜 및 시간 관련 구성 요소
캘린더 정보 가져오기
var identifier: Calendar.Identifier
- 캘린더의 identifier 를 반환합니다
var calendar = Calendar(identifier: .iso8601)
print(calendar.identifier) // iso8601 출력
var locale: Locale?
- 캘린더의 locale 정보를 가져옵니다.
- 달력에서 주의 첫 번째 날을 나타냅니다. 일반적으로 1은 일요일, 2는 월요일을 의미합니다.
// 현재 사용자의 캘린더를 가져옵니다.
var calendar = Calendar.current
// 사용자가 설정한 첫 번째 요일을 확인합니다.
let firstDay = calendar.firstWeekday
// 현재 캘린더의 주의 첫 번째 요일을 출력합니다.
print("The first day of the week is: \(firstDay)")
// 주의 첫 번째 요일을 수요일(4)로 변경합니다.
calendar.firstWeekday = 4
// 변경된 첫 번째 요일을 확인합니다.
let updatedFirstDay = calendar.firstWeekday
print("The updated first day of the week is: \(updatedFirstDay)")
var minimumDaysInFirstWeek: Int
- 첫 번째 주에 필요한 최소 일 수를 나타냅니다. 이 속성은 연도나 월의 첫 번째 주로 간주되기 위한 최소 일 수를 정의합니다.
- 아래 8월인 경우에는 최소 일 수가 4일입니다
var timeZone: TimeZone
- 달력의 시간대입니다. 이 속성은 날짜 및 시간 계산에 사용되는 시간대를 설정합니다.
func maximumRange(of: Calendar.Component) -> Range<Int>?
- 지정된 구성 요소(예: 일, 월, 연도 등)의 값을 가질 수 있는 최대 범위를 반환합니다.
- .day: 1..<32
- .month: 1..<13
- .year: 1..<144684
func minimumRange(of: Calendar.Component) -> Range<Int>?
- 지정된 구성 요소의 값이 가질 수 있는 최소 범위를 반환합니다.
- .day: 1..<29
- .month: 1..<13
- .year: 1..<140743
func ordinality(of: Calendar.Component, in: Calendar.Component, for: Date) -> Int?
- 주어진 절대 시간에서, 작은 캘린더 구성 요소(예: 일)가 특정 큰 캘린더 구성 요소(예: 주) 내에서 몇 번째인지를 반환합니다.
print(calendar.ordinality(of: .day, in: .month, for: Date()))
func range(of: Calendar.Component, in: Calendar.Component, for: Date) -> Range<Int>?
- 주어진 절대 시간을 포함하는 큰 캘린더 구성 요소 내에서 작은 캘린더 구성 요소가 가질 수 있는 값의 범위를 반환합니다.
- 주어진 for 날짜에서 해당 in 에 포함된 Component 인 of 의 범위를 반환하며 커스텀 달력을 만들 때 유용하게 사용됩니다.
- 예를들어 아래 코드처럼 만약 Date()가 8월이라면 1..<32 의 범위를 반환합니다.
let calendar = Calendar(identifier: .iso8601)
print(calendar.range(of: .day, in: .month, for: Date()))
날짜 탐색
func startOfDay(for: Date) -> Date
- 주어진 날짜의 첫 순간을 Date 형식으로 반환합니다. 이는 하루의 시작 시각(자정)을 의미합니다.
let calendar = Calendar.current
let now = Date()
// 현재 날짜의 자정을 구합니다.
let startOfToday = calendar.startOfDay(for: now)
// 결과 출력
print("Start of today: \(startOfToday)")
func enumerateDates(startingAfter: Date, matching: DateComponents, matchingPolicy: Calendar.MatchingPolicy, repeatedTimePolicy: Calendar.RepeatedTimePolicy, direction: Calendar.SearchDirection, using: (Date?, Bool, inout Bool) -> Void)
- 지정된 구성 요소와 일치(또는 가장 유사)하는 날짜를 계산하고, 열거를 중지할 때까지 각각에 대해 클로저를 호출합니다.
let calendar = Calendar.current
let now = Date()
// 일요일을 찾기 위한 구성 요소 설정
var components = DateComponents()
components.weekday = 1 // 1은 일요일
// 열거할 방향 설정 (정방향 검색)
let direction = Calendar.SearchDirection.forward
// 열거를 시작하고 일치하는 날짜를 찾습니다.
calendar.enumerateDates(startingAfter: now, matching: components, matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: direction) { (date, exactMatch, stop) in
if let date = date {
print("Found a matching date: \(date)")
// 특정 조건에 따라 열거를 중지할 수 있습니다.
stop = true
}
}
- 주어진 구성 요소와 일치(또는 가장 유사)하는 다음 날짜를 계산합니다.
let calendar = Calendar.current
let now = Date()
// 다음 월요일을 찾기 위한 구성 요소 설정
var components = DateComponents()
components.weekday = 2 // 2는 월요일
// 다음 월요일을 찾습니다.
if let nextMonday = calendar.nextDate(after: now, matching: components, matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .forward) {
print("Next Monday is: \(nextMonday)")
} else {
print("No matching date found.")
}
- 날짜 검색 알고리즘에 대한 힌트를 제공하여 날짜 검색 방법을 제어합니다.
- .strict: 정확히 일치하는 날짜만 찾습니다.
- .nextTime: 가능한 다음 시간을 찾습니다.
- .nextTimePreservingSmallerComponents: 작은 구성 요소를 유지하면서 가능한 다음 시간을 찾습니다.
enum Calendar.RepeatedTimePolicy
- 특정 날에 시간이 반복될 때(예: 서머타임 전환 시) 사용할 결과를 결정합니다.
- .first: 첫 번째 반복 시간을 사용합니다.
- .last: 마지막 반복 시간을 사용합니다.
주어진 구성요소로 날짜 계산하기
func date(from: DateComponents) -> Date?
- 지정된 구성 요소에서 Date를 생성하여 반환합니다.
var components = DateComponents()
components.year = 2024
components.month = 8
components.day = 11
let calendar = Calendar.current
if let date = calendar.date(from: components) {
print("Created date from components: \(date)")
} else {
print("Could not create date from components.")
}
func date(byAdding: DateComponents, to: Date, wrappingComponents: Bool) -> Date?
- 주어진 날짜에 구성 요소를 추가하여 계산된 새로운 날짜를 반환합니다.
- - wrappingComponents가 true일 경우, 구성 요소가 범위를 넘어가면 랩핑됩니다.
let calendar = Calendar.current
let now = Date()
var componentsToAdd = DateComponents()
componentsToAdd.day = 5
componentsToAdd.month = 1
if let futureDate = calendar.date(byAdding: componentsToAdd, to: now, wrappingComponents: false) {
print("Date after adding components: \(futureDate)")
} else {
print("Could not calculate future date.")
}
func date(byAdding: DateComponents, to: Date, wrappingComponents: Bool) -> Date?
- 주어진 날짜에 특정 구성 요소를 일정량 추가하여 계산된 새로운 날짜를 반환합니다.
- wrappingComponents가 true일 경우, 구성 요소가 범위를 넘어가면 랩핑됩니다.
let calendar = Calendar.current
let now = Date()
// 현재 날짜에 10일을 추가합니다.
if let futureDate = calendar.date(byAdding: .day, value: 10, to: now, wrappingComponents: false) {
print("Date after adding 10 days: \(futureDate)")
}
// 현재 날짜에서 2개월을 뺍니다.
if let pastDate = calendar.date(byAdding: .month, value: -2, to: now, wrappingComponents: true) {
print("Date after subtracting 2 months (with wrapping): \(pastDate)")
}
func date(byAdding: Calendar.Component, value: Int, to: Date, wrappingComponents: Bool) -> Date?
- 주어진 날짜에 특정 구성 요소를 일정량 추가하여 계산된 새로운 날짜를 반환합니다.
- - wrappingComponents가 true일 경우, 구성 요소가 범위를 넘어가면 랩핑됩니다.
- 예를들어 특정 날짜를 더하거나 뺄 수 있습니다.
let calendar = Calendar.current
let now = Date()
// 현재 날짜에 10일을 추가합니다.
if let futureDate = calendar.date(byAdding: .day, value: 10, to: now, wrappingComponents: false) {
print("Date after adding 10 days: \(futureDate)")
}
// 현재 날짜에서 2개월을 뺍니다.
if let pastDate = calendar.date(byAdding: .month, value: -2, to: now, wrappingComponents: true) {
print("Date after subtracting 2 months (with wrapping): \(pastDate)")
}
func date(bySetting: Calendar.Component, value: Int, of: Date) -> Date?
- 특정 구성 요소를 지정된 값으로 설정하고, 가능한 경우 하위 구성 요소를 동일하게 유지하여 계산된 새로운 날짜를 반환합니다.
let calendar = Calendar.current
let now = Date()
// 현재 날짜의 월을 12월로 설정합니다.
if let newDate = calendar.date(bySetting: .month, value: 12, of: now) {
print("Date with month set to December: \(newDate)")
} else {
print("Could not set month.")
}
- 지정된 날짜에 시간, 분, 초를 설정하여 계산된 새로운 날짜를 반환합니다.
let calendar = Calendar.current
let now = Date()
// 현재 날짜의 시간을 10:30:00으로 설정합니다.
if let newDate = calendar.date(bySettingHour: 10, minute: 30, second: 0, of: now, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .forward) {
print("Date with time set to 10:30:00: \(newDate)")
} else {
print("Could not set time.")
}
Intervals 계산하기
func dateInterval(of: Calendar.Component, for: Date) -> DateInterval?
- 주어진 날짜를 포함하는 특정 캘린더 구성 요소의 시작 시간과 지속 시간을 포함하는 DateInterval을 반환합니다.
let calendar = Calendar.current
let date = Date()
// 주어진 날짜를 포함하는 주의 시작과 끝을 구합니다.
if let weekInterval = calendar.dateInterval(of: .weekOfYear, for: date) {
print("Week starts on \(weekInterval.start) and ends on \(weekInterval.end)")
} else {
print("Could not find week interval.")
}
- 주어진 날짜를 포함하는 특정 캘린더 구성 요소의 시작 시간과 지속 시간을 두 개의 inout 매개변수를 통해 반환합니다.
let calendar = Calendar.current
let date = Date()
var start = Date()
var interval: TimeInterval = 0
// 주어진 날짜를 포함하는 달의 시작과 지속 시간을 구합니다.
if calendar.dateInterval(of: .month, start: &start, interval: &interval, for: date) {
print("Month starts on \(start) and lasts \(interval) seconds")
} else {
print("Could not find month interval.")
}
func dateIntervalOfWeekend(containing: Date) -> DateInterval?
- 주어진 날짜를 포함하는 주말의 DateInterval을 반환하거나, 날짜가 주말이 아닌 경우 nil을 반환합니다.
let calendar = Calendar.current
let date = Date()
// 주어진 날짜가 주말에 속하는지 확인하고 주말의 기간을 구합니다.
if let weekendInterval = calendar.dateIntervalOfWeekend(containing: date) {
print("Weekend starts on \(weekendInterval.start) and ends on \(weekendInterval.end)")
} else {
print("The date is not within a weekend.")
}
- 주어진 날짜 주변의 주말 범위를 두 개의 참조 매개변수를 통해 반환합니다.
let calendar = Calendar.current
let date = Date()
var start = Date()
var interval: TimeInterval = 0
// 주어진 날짜를 포함하는 주말의 시작과 지속 시간을 구합니다.
if calendar.dateIntervalOfWeekend(containing: date, start: &start, interval: &interval) {
print("Weekend starts on \(start) and lasts \(interval) seconds")
} else {
print("The date is not within a weekend.")
}
func nextWeekend(startingAfter: Date, direction: Calendar.SearchDirection) -> DateInterval?
- 지정된 날짜 이후 시작하는 다음 주말의 DateInterval을 반환합니다.
let calendar = Calendar.current
let date = Date()
// 지정된 날짜 이후의 다음 주말을 구합니다.
if let nextWeekendInterval = calendar.nextWeekend(startingAfter: date, direction: .forward) {
print("Next weekend starts on \(nextWeekendInterval.start) and ends on \(nextWeekendInterval.end)")
} else {
print("Could not find the next weekend.")
}
- 지정된 날짜 이후 시작하는 다음 주말의 범위를 두 개의 inout 매개변수를 통해 반환합니다.
let calendar = Calendar.current
let date = Date()
var start = Date()
var interval: TimeInterval = 0
// 지정된 날짜 이후의 다음 주말의 시작과 지속 시간을 구합니다.
if calendar.nextWeekend(startingAfter: date, start: &start, interval: &interval, direction: .forward) {
print("Next weekend starts on \(start) and lasts \(interval) seconds")
} else {
print("Could not find the next weekend.")
}
- 시간을 검색할 방향을 나타냅니다.
- .forward: 미래 방향으로 검색
- .backward: 과거 방향으로 검색
날짜 비교하기
func compare(Date, to: Date, toGranularity: Calendar.Component) -> ComparisonResult
- 이 메서드는 두 날짜를 주어진 구성 요소의 수준까지 비교하고, 그 결과를 ComparisonResult로 반환합니다.
- ComparisonResult는 .orderedAscending, .orderedSame, .orderedDescending 중 하나의 값을 가집니다.
let calendar = Calendar.current
let date1 = Date() // 현재 날짜
let date2 = calendar.date(byAdding: .day, value: 1, to: date1)! // 하루 후 날짜
// 두 날짜를 비교합니다 (날짜 단위로 비교).
let result = calendar.compare(date1, to: date2, toGranularity: .day)
switch result {
case .orderedAscending:
print("date1 is earlier than date2")
case .orderedSame:
print("date1 and date2 are the same day")
case .orderedDescending:
print("date1 is later than date2")
}
func isDate(Date, equalTo: Date, toGranularity: Calendar.Component) -> Bool
- 이 메서드는 두 날짜가 주어진 구성 요소의 toGranularity 범위에서 동일한지 여부를 Bool 값으로 반환합니다.
let calendar = Calendar.current
let date1 = Date() // 현재 날짜
let date2 = calendar.date(byAdding: .day, value: 0, to: date1)! // 같은 날짜
// 두 날짜가 같은 날인지 확인합니다.
let areDatesEqual = calendar.isDate(date1, equalTo: date2, toGranularity: .day)
if areDatesEqual {
print("date1 and date2 are on the same day")
} else {
print("date1 and date2 are on different days")
}
func isDate(Date, inSameDayAs: Date) -> Bool
- 이 메서드는 두 날짜가 동일한 날인지 여부를 Bool 값으로 반환합니다.
let calendar = Calendar.current
let date1 = Date() // 현재 날짜
let date2 = calendar.date(byAdding: .day, value: 0, to: date1)! // 같은 날짜
// 두 날짜가 동일한 날인지 확인합니다.
if calendar.isDate(date1, inSameDayAs: date2) {
print("date1 and date2 are on the same day")
} else {
print("date1 and date2 are on different days")
}
func isDateInToday(Date) -> Bool
- 이 메서드는 주어진 날짜가 오늘인지 여부를 Bool 값으로 반환합니다.
let calendar = Calendar.current
let date = Date() // 현재 날짜
// 주어진 날짜가 오늘인지 확인합니다.
if calendar.isDateInToday(date) {
print("The date is today")
} else {
print("The date is not today")
}
func isDateInTomorrow(Date) -> Bool
- 이 메서드는 주어진 날짜가 내일인지 여부를 Bool 값으로 반환합니다.
let calendar = Calendar.current
let date = calendar.date(byAdding: .day, value: 1, to: Date())! // 내일 날짜
// 주어진 날짜가 내일인지 확인합니다.
if calendar.isDateInTomorrow(date) {
print("The date is tomorrow")
} else {
print("The date is not tomorrow")
}
func isDateInYesterday(Date) -> Bool
- 이 메서드는 주어진 날짜가 어제인지 여부를 Bool 값으로 반환합니다.
let calendar = Calendar.current
let date = calendar.date(byAdding: .day, value: -1, to: Date())! // 어제 날짜
// 주어진 날짜가 어제인지 확인합니다.
if calendar.isDateInYesterday(date) {
print("The date is yesterday")
} else {
print("The date is not yesterday")
}
func isDateInWeekend(Date) -> Bool
- 이 메서드는 주어진 날짜가 주말인지 여부를 Bool 값으로 반환합니다.
let calendar = Calendar.current
let date = Date() // 현재 날짜
// 주어진 날짜가 주말인지 확인합니다.
if calendar.isDateInWeekend(date) {
print("The date is on a weekend")
} else {
print("The date is on a weekday")
}
'SwiftUI' 카테고리의 다른 글
SwiftUI - 버튼, 텍스트 터치 영역 확장시키기 (0) | 2024.08.18 |
---|---|
SwiftUI - 커스텀 달력 만들기 (0) | 2024.08.17 |
SwiftUI - 나만의 SPM 만들어 사용해보기 (0) | 2024.08.08 |
SwiftUI - DragGesture 사용해서 화면 드래그하는법 (0) | 2024.08.07 |
SwiftUI - 컨텐츠를 원하는 위치에 배치하기 (0) | 2024.08.06 |