iOS에서의 날짜/시간 관련 코드를 살펴보기 전에 "국제적인 표준 시간 - 협정 세계시(UTC)"를 알 필요가 있습니다.
- iOS에서는 날짜와 시간은 "국제적인 표준 시간 - 협정 세계시(UTC)"를 사용하고 있으며,
협정 세계시(UTC)는 영국의 그리니치 천문대(GMT)를 기준으로 동쪽으로 15º씩 이동할 때마다 1시간이 추가됩니다. 반대로 서쪽으로 15º씩 이동할 때마다 1시간씩 감소합니다.
- 대한민국과 영국의 시간 차이는 9시입니다.
- UTC와 GMT는 초의 소수점 단위에서만 차이가 나기 때문에 일상에서는 혼용되어 사용하지만, 기술적인 표기에서는 UTC를 사용합니다.
Date는 Swift(애플)에서 개발자들의 원활한 코드 작성을 위해 기본적으로 제공해주는 구조체 중 하나이며, 날짜/시간 관련 기능을 다루고 있습니다.
iOS 환경에서 날짜/시간 관련 기능을 사용하기 위해서는 필수적으로 사용/작성해야 하는 구조체입니다.
✅ Date 구조체로부터 인스턴스 생성
let today = Date() print(today) // 영국 기준으로 출력 // 2022-12-05 13:03:04 +0000
Date 구조체로부터 인스턴스 생성 시 생성 시점의 날짜와 시간 데이터를 생성하여 인스턴스에 할당합니다. (해당 날짜와 시간은 초 단위 기준값을 가지고 있습니다)
✅ 기준 시간부터 현재 시간까지 초 단위로 출력하기
- Swift(애플)에서의 기준 시간(Reference Date)은 2001.1.1.00:00:00 UCT입니다.
- 참고로 유닉스에서의 기준 시간은 1970.1.1.00:00:00 UCT입니다.
today.timeIntervalSinceReferenceDate // 2001.1.1.00:00:00 ~ 2022-12-05 13:03:04 // 691938184.6941741 (초단위) today.timeIntervalSince1970 // 1970.1.1.00:00:00 ~ 2022-12-05 13:03:04 // 1670245384.694174 (초단위)
✅ 변수에 초(시간) 타입 데이터 할당
- TimeInterval 타입은 초(시간)를 표현하기 위해 사용되는 데이터 타입입니다.
- 하지만 실제 데이터 타입을 확인해 보면 Double 타입인 것을 확인할 수 있습니다.
이는 직관성을 높이기 위해 타입 별칭(Type alias) 기능을 활용한 사례입니다.var second1 = TimeInterval(10.0) // 10초 할당 var second2: TimeInterval = 20.0 // 20초 할당 print(type(of: second1)) // Double print(type(of: second2)) // Double
✅ Date 구조체의 다양한 기능
let today = Date() let yesterday = today - 86400 // 60(초)*60(분)*24(시) = 1일 today.timeIntervalSince(yesterday) // 86400 // timeIntervalSince: 해당 시점으로부터 시차를 초로 반환 today.distance(to: yesterday) // -86400 // distance: 지금 시점을 기준으로 그 시간까지의 거리를 초로 반환 today.advanced(by: 86400) // "Dec 6, 2022 at 10:52 PM" // advanced(by: 86400): 해당 시점으로부터 다음날 날짜/시간 반환 today.addingTimeInterval(86400) // "Dec 6, 2022 at 10:52 PM" // addingTimeInterval(86400): 해당 시점으로부터 다음날 날짜/시간 반환 today + 86400 // "Dec 6, 2022 at 10:52 PM"
Date 구조체로 만들어진 인스턴스의 날짜 데이터와 시간 데이터는 절대적 시점의 데이터(초 단위)이기 때문에 날것으로 사용하기에는 무리가 있으므로 특정 변환 작업이 필요합니다.
변환 작업은 "Calendar 구조체"와 "DateFormatter 클래스"를 통해 변환할 수 있습니다.
Calendar는 달력에 포함되어 있는 요소 및 기능이 포함된 구조체입니다.
Calendar 구조체를 사용하여 Date 구조체로부터 만들어진 절대적 시점의 시간 데이터를 "년/월/일 or 시/분/초 or 요일"로 보기 편하게 변환할 수 있습니다.
✅ 타입 속성으로 현재의 달력 반환(기본 설정)
현재 대한민국을 포함한 많은 나라에서 양력(태양력)을 사용하고 있습니다.
let calendar = Calendar.current // 현재의 달력(양력) 반환 + 가장 많이 사용하는 방법⭐️ let calendar2 = Calendar(identifier: .gregorian) // 양력(태양력) 달력
하지만 특정 국가와 특정 종교에서는 양력(태양력)이 아닌 특별한 기준을 사용한 달력을 사용하고 있습니다. 그 때문에 애플에서는 양력(태양력) 외에도 다양한 기준의 달력을 제공하고 있습니다.
let calendar = Calendar.current let calendar = Calendar(identifier: .gregorian) // 양력(태양력)을 지정 설정 let calendar = Calendar(identifier: .buddhist) // 불교에서 사용하는 기준을 지정 설정
✅ 달력의 지역 위치(기본 설정)
달력을 사용하는 지역에 따라 표현 방법과 지역 시간이 다르므로 필요시 변환하여 작업해야 합니다.
미국의 연월일 표기: 12/31/2022
한국의 연월일 표기: 2022/12/31let calendar = Calendar.current calendar.locale // en_US (current) -> 미국식 표현법 calendar.timeZone // Asia/Seoul (fixed (equal to current)) -> 한국 시간
달력의 지역 위치 및 기준 시간을 변경하는 방법은 아래와 같습니다.
let calendar = Calendar.current calendar.locale = Locale(identifier: "ko_KR") // 한국식 표기법으로 변경 calendar.locale // ko_KR (fixed) calendar.timeZone = TimeZone(identifier: "Asia/Seoul")! // 기준 시간을 한국으로 변경 calendar.timeZone // Asia/Seoul (fixed (equal to current))
✅ 절대적 시점의 시간 데이터에서 원하는 요일/시간 추출
calendar 구조체의 component() 메서드를 사용하여 원하는 요일 및 시간을 추출할 수 있습니다.
let today = Date() // 절대적 시점의 시간 데이터 var calendar = Calendar.current // 타입 속성으로 현재의 달력(양력) 반환 calendar.component(.year, from: today) // 년도: 2022 calendar.component(.month, from: today) // 월: 12 calendar.component(.day, from: today) // 일: 6 calendar.component(.hour, from: today) // 시: 20 calendar.component(.minute, from: today) // 분: 37 calendar.component(.second, from: today) // 초: 14 calendar.component(.weekday, from: today) // 요일: 3 //일요일 = 1 //월요일 = 2 //... //토요일 = 7
calendar 구조체의 dateComponents() 메서드를 사용하여 원하는 요일 및 시간을 컬렉션 타입으로 추출할 수 있습니다.
var todayCalendar = calendar.dateComponents([.year, .month, .day], from: today) todayCalendar.year // 년도: 2022 todayCalendar.month // 월: 12 todayCalendar.day // 일: 6
DateFormatter는 절대적 시점의 데이터(초 단위)를 원하는 형식의 문자열로 변환해주는 클래스입니다.
절대적 시점의 데이터(초 단위)를 문자열로 변환하는 방법은 크게 "기본 형식의 문자열"과 "커스텀 형식의 문자열"이 있습니다.
✅ 문자열로 변환하는 인스턴스 생성
let formatter = DateFormatter()
✅ 절대적 시점의 데이터(초 단위)를 문자열로 변환_1
1. 지역 설정(초기 설정, 생략 가능)
2. 시간대 설정(초기 설정, 생략 가능)// 1. 지역 설정 formatter.locale = Locale(identifier: "ko_KR") // 2. 시간대 설정 formatter.timeZone = TimeZone(identifier: "Asia/Seoul")
3. 날짜 형식(애플에서 제공해주는 기본 설정)
en_US ko_KR .full Tuesday, December 6, 2022 2022년 12월 6일 화요일 .long December 6, 2022 2022년 12월 6일 .medium Dec 6, 2022 2022. 12. 6. .short 12/6/22 2022. 12. 6. .none (날짜 없어짐) (날짜 없어짐) 4. 시간 형식(애플에서 제공해주는 기본 설정)
en_US ko_KR .full 10:08:04 PM Korean Standard Time 오후 10시 8분 04초 대한민국 표준시 .long 10:08:04 PM GMT+9 오후 10시 8분 04초 GMT+9 .medium 10:08:04 PM 오후 10:08:04 .short 10:08 PM 오후 10:08 .none (시간 없어짐) (시간 없어짐) // 3. 날짜 형식 formatter.dateStyle = .full //formatter.dateStyle = .long //formatter.dateStyle = .medium //formatter.dateStyle = .short //formatter.dateStyle = .none // 4. 시간 형식 formatter.timeStyle = .full //formatter.timeStyle = .long //formatter.timeStyle = .medium //formatter.timeStyle = .short //formatter.timeStyle = .none let result = formatter.string(from: Date()) print(result) /*출력 결과 2022년 12월 6일 화요일 오후 10시 8분 4초 대한민국 표준시 */
✅ 절대적 시점의 데이터(초 단위)를 문자열로 변환_2
1. 지역 설정(초기 설정, 생략 가능)
2. 시간대 설정(초기 설정, 생략 가능)// 1. 지역 설정 formatter.locale = Locale(identifier: "ko_KR") // 2. 시간대 설정 formatter.timeZone = TimeZone(identifier: "Asia/Seoul")
3. 날짜와 시간 형식을 커스텀 형식으로 생성
커스텀 형식의 표현 방법은 유니코드(unicode)를 기반으로 커스텀할 수 있습니다.// 3. 날짜와 시간을 커스텀 형식으로 생성 formatter.dateFormat = "yyyy-MMMM-d일 E요일" let result2 = formatter.string(from: Date()) print(result2) /*출력 결과 2022-12월-6일 화요일 */
✅ 요일/시간 문자열을 절대적 시점의 데이터(초 단위)로 변환
let formatter = DateFormatter() formatter.dateFormat = "yyyy/MM/dd" let date = formatter.date(from: "2022/12/6")! print(date) /*출력 결과 2022-12-05 15:00:00 +0000 // 영국 기준으로 출력 */
Calendar 구조체와 DateFormatter 클래스 외에도 날짜/시간 관련 기능이 있는 커스텀 타입이 몇 가지 더 존재합니다. (그건 나중에 알아보는 걸로...)