iOS에서 날짜/시간 다루기

썹스·2022년 12월 5일
0

iOS에서의 날짜/시간

iOS에서의 날짜/시간 관련 코드를 살펴보기 전에 "국제적인 표준 시간 - 협정 세계시(UTC)"를 알 필요가 있습니다.

  • iOS에서는 날짜와 시간은 "국제적인 표준 시간 - 협정 세계시(UTC)"를 사용하고 있으며,
    협정 세계시(UTC)는 영국의 그리니치 천문대(GMT)를 기준으로 동쪽으로 15º씩 이동할 때마다 1시간이 추가됩니다. 반대로 서쪽으로 15º씩 이동할 때마다 1시간씩 감소합니다.

  • 대한민국과 영국의 시간 차이는 9시입니다.

  • UTC와 GMT는 초의 소수점 단위에서만 차이가 나기 때문에 일상에서는 혼용되어 사용하지만, 기술적인 표기에서는 UTC를 사용합니다.

Date 구조체

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는 달력에 포함되어 있는 요소 및 기능이 포함된 구조체입니다.

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/31

let 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 클래스

DateFormatter는 절대적 시점의 데이터(초 단위)를 원하는 형식의 문자열로 변환해주는 클래스입니다.

절대적 시점의 데이터(초 단위)를 문자열로 변환하는 방법은 크게 "기본 형식의 문자열""커스텀 형식의 문자열"이 있습니다.

✅ 문자열로 변환하는 인스턴스 생성

let formatter = DateFormatter()

✅ 절대적 시점의 데이터(초 단위)를 문자열로 변환_1

1. 지역 설정(초기 설정, 생략 가능)
2. 시간대 설정(초기 설정, 생략 가능)

// 1. 지역 설정
formatter.locale = Locale(identifier: "ko_KR")

// 2. 시간대 설정
formatter.timeZone = TimeZone(identifier: "Asia/Seoul")

3. 날짜 형식(애플에서 제공해주는 기본 설정)

en_USko_KR
.fullTuesday, December 6, 20222022년 12월 6일 화요일
.longDecember 6, 20222022년 12월 6일
.mediumDec 6, 20222022. 12. 6.
.short12/6/222022. 12. 6.
.none(날짜 없어짐)(날짜 없어짐)

4. 시간 형식(애플에서 제공해주는 기본 설정)

en_USko_KR
.full10:08:04 PM Korean Standard Time오후 10시 8분 04초 대한민국 표준시
.long10:08:04 PM GMT+9오후 10시 8분 04초 GMT+9
.medium10:08:04 PM오후 10:08:04
.short10: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 클래스 외에도 날짜/시간 관련 기능이 있는 커스텀 타입이 몇 가지 더 존재합니다. (그건 나중에 알아보는 걸로...)

profile
응애 나 코린이(비트코인X 코딩O)

0개의 댓글