일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- optional
- Foundation
- Git
- extension
- interpace
- Protocol
- initalizer
- String
- initializer
- Swift
- Terminal
- 이니셜라이저
- 디자인패턴
- Xcode
- property
- instance
- url
- Class
- init
- enum
- tuist
- 코딩테스트
- Unicode
- Method
- delegate
- 스위프트
- IOS
- UIKit
- struct
- type
- Today
- Total
아리의 iOS 탐구생활
[Swift] 시간과 날짜를 다루는 타입에 대해서 알아보자. 본문
Date 관련 타입들은 앱 개발을 할때 굉장히 많이 사용하게 되는 타입중 하나이다.
시간과 날짜를 다루는 타입들은 swift 기본 프레임워크인 Foundation에 포함되어 있다.
🔍 Date
Foundation의 Date 타입은 전 세계적으로 정확히 같은 시간을 표현하기 위한 타입이다.
- init()
현재 시간을 나타내준다.
- init(timeIntervalSinceNow: TimeInterval)
현재 시각으로 부터 입력한 초 이후의 시점을 나타낸다.
- init(timeInterval: TimeInterval, since: Date)
다른 Date()객체로부터 입력한 초 이후의 시점을 나타낸다.
- init(timeIntervalSince1970: TimeInterval)
1970년 1월 1일 00:00:00 UTC를 기준으로 주어진 초 단위로 초기화된 'Date'를 리턴한다.
- init(timeIntervalSinceReferenceDate: TimeInterval)
2001년 1월 1일 00:00:00 UTC를 기준으로 지정된 초 단위로 초기화된 날짜 값을 생성합니다.
👉🏻 example
// 1. 현재 시간
let date1 = Date()
// 2. 지금으로부터 300초 지난 시점
let date2 = Date(timeIntervalSinceNow: 300)
// 3. date2로부터 300초 지난 시점
let date3 = Date(timeInterval: 300, since: date2)
// 4. 유닉스 시간인 1970년 1월 1일 00:00:00 UTC로부터 300초 지난 시점
let date4 = Date(timeIntervalSince1970: 300)
// 5. 2001년 1월 1일 00:00:00 UTC로부터 300초 지난 시점
let date5 = Date(timeIntervalSinceReferenceDate: 300)
print(date1) // 2021-08-24 11:49:10 +0000
print(date2) // 2021-08-24 11:54:10 +0000
print(date3) // 2021-08-24 11:59:10 +0000
print(date4) // 1970-01-01 00:05:00 +0000
print(date5) // 2001-01-01 00:05:00 +0000
- Date를 이용하여 특정 코드의 연산 실행시간도 측정할 수가 있다.
// Date를 이용하여 특정 코드의 연산 실행시간을 측정할 수 있다.
let currentDate = Date()
print("실행 시간 : \(-currentDate.timeIntervalSinceNow)")
// print가 되기 전까지의 실행시간을 나타낸다.
🔍 TimeInterval
TimeInterval 타입은 날짜 및 시간 관련한 표현에 사용하는 타입으로 초(second)를 나타낸다. 즉, 값이 1이면 1초를 나타낸다. 그러나 사실 TimeInterval은 이름만 다른 Double 타입이다. 타입 별칭(Type alias)이라는 기능을 활용하여 이름만 달라진 것이다. 이미 존재하는 타입의 기능을 똑같이 구현할 필요는 없으나 Double이라는 이름보다는 TimeInterval이라는 이름으로 표현하는 것이 더 직관적이므로 타입 별칭을 사용해준 것이다.
🔍 DateFormmatter
시각(Date)과 문자열 표현(String)을 상호 변환해주는 역할을 수행하는 타입이다. 시간을 원하는 타입으로 만들 수 있다. Date타입은 날짜의 한 지점을 나타내지만 이것을 텍스트로 표현하고 싶을 때에 주로 활용한다. DateFormatter을 인스턴스화 시켜 사용하며 dateStyle, timeStyle, locale, 그리고 dateFormat을 통해 다양한 방법으로 Date를 표시한다.
👉🏻 example
let date = Date()
let dateFormatter = DateFormatter() // 인스턴스 생성
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .medium
dateFormatter.locale = Locale(identifier: "en_US")
print(dateFormatter.string(from: date)) // Aug 24, 2021 at 8:55:52 PM
dateFormatter.locale = Locale(identifier: "fr_FR")
print(dateFormatter.string(from: date)) // 24 août 2021 à 20:55:52
dateFormatter.locale = Locale(identifier: "ko_KR")
print(dateFormatter.string(from: date)) // 2021. 8. 24. 오후 8:55:52
dateFormatter.dateFormat = "YY년 M월 d일 h시 mm분 ss초"
print(dateFormatter.string(from: date)) // 21년 8월 24일 8시 55분 52초
DateFormatter를 사용하면 String으로부터 Date를 얻어오는 것도 가능해진다. 이 때 String이 DateFormatter의 형식과 맞지 않을 경우에는 nil을 리턴해야 하므로 반환형이 Optional이다.
// 인스턴스 생성
let formatter = DateFormatter()
// Date to String
let now = Date()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy년 MM월 dd일 HH시 mm분 ss초"
let result = formatter.string(from: now)
print(result) // 2021년 08월 24일 20시 08분 32초
// String to Date
let dateString = "2021년08월24일 20시10분11초 +0000"
formatter.dateFormat = "yyyy년MM월dd일 HH시mm분ss초 ZZZZ"
let date = formatter.date(from: dateString)!
print(date) // 2021-08-24 20:10:11 +0000
변환하는 결과가 옵셔널인 이유는 변환할 문자열이 포맷이랑 동일하지 않을 수도 있기 때문이다. 위 예제에서는 강제 언래핑을 사용하고 있지만 에러가 발생할 수 있으므로 옵셔널 바인딩을 해야한다.
👉🏻 포맷 용어 정리
Format | Desctiption | Example |
y (년도) | 연도 출력 | 2021 |
yy | 연도 뒷자리 두개 출력 | 21 |
yyyy | 연도 네자리 출력 M 월 출력 | 2021 |
M (월) | 월에서 뒷자리 하나 (ex: 2) | 8 |
MM | 월을 두자리로 (ex: 02) | 08 |
MMM | 영문 약어로 (ex: feb, sept) | Aug |
MMMM | 영문으로 (ex: february, september) d 날짜 출력 h, H 시간 출력 |
August |
d (일) | 일 출력 | 25 |
dd | 일을 두자리로 출력 | 25 |
E, EE, EEE (요일) | 요일을 약어로 출력 (Locale에 따라 다름) | Wed |
EEEE | 요일을 전체적으로 출력 | Wednesday |
EEEEE | 요일을 한글자로 출력 | W |
EEEEEE | 요일을 두글자로 출력 | We |
a (오전, 오후) | 오전, 오후를 출력 (Locale에 따라 다름) | PM or AM |
h (시간) | 시간을 12시간으로 한자리로 출력 | 2 |
hh | 시간을 12시간으로 두자리로 출력 | 02 |
H | 시간을 24시간으로 한자리로 출력 | 14 |
HH | 시간을 24시간으로 두자리로 출력 | 14 |
m (분) | 분을 한자리로 출력 | 5 |
mm | 분을 두자리로 출력 | 05 |
s (초) | 초를 한자리로 출력 | 1 |
ss | 초를 두자리로 출력 | 11 |
S (밀리초) | 밀리초를 한자리로 출력 | 0 |
SS | 밀리초를 두자리로 출력 | 12 |
SSS | 밀리초를 세자리로 출력 | 123 |
zzz (시간대) | 타임존을 3글자로 출력한다. 이름을 모르는 경우 GMT-08:00으로 대체 | GMT+9 |
zzzz | 타임존의 이름을 상세하게 출력한다. | Korean Standard Time |
ZZZZ | 타임존의 약어와 hour offset를 출력 | GMT+09:00 |
Z | RFC 822 GMT 포맷 방식 출력 | +0900 |
ZZZZZ | ISO 8601 타임존 포맷 방식 출력 | +09:00 |
🔍 TimeZone
말 그대로 타임존의 명칭을 의미한다. 세계의 각 지역에 따라 시간대가 다른데, 그 시간대를 나타내기 위한 Foundation의 타입이다. 날짜 계산이나 날짜 표현 등의 작업을 수행할 때 꼭 TimeZone을 잘 확인해야 한다. 같은 시각이라도 TimeZone에 따라서 날짜 표현이 달라질 수 있기 때문이다.
👉🏻 example
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.locale = Locale(identifier: "ko_kr") // 한국의 시간을 지정해준다.
formatter.timeZone = TimeZone(abbreviation: "KST") // 한국의 시간대로 지정한다.
//formatter.timeZone = TimeZone.current // 현재 사용자의 시간대를 지정한다.
let kr = formatter.string(from: date) // Date to String
print(kr) // 2021-08-25 01:17:53
🔍 Calendar
달력과 관련된 정보를 담는 구조체이다. 달력과 관련된 계산과 각 달력의 요소인 DateComponent를 얻을 수 있다.
Calendar의 생성은 Calendar.Identifier 열거형을 init 메소드에 전달함으로써 이루어지는데 이는 나라 또는 종교 별로 달력이 다르기 때문이다. 인스턴스로 만든 뒤에는 달력의 요소를 나타내는 DateComponent 구조체에 관한 다양한 메서드를 사용할 수 있다. Date에서 DateComponent를 뽑아낼 수도 있고 반대로 DateComponent를 통해 Date를 만들어 낼 수도 있다.
👉🏻 example
let date = Date()
var calendar = Calendar(identifier: .gregorian)
print(calendar.dateComponents([.day, .month], from: date)) // month: 8 day: 25 isLeapMonth: false
var dateComponents = DateComponents()
dateComponents.year = 1995
print(calendar.date(from: dateComponents)) // Optional(1994-12-31 15:00:00 +0000)
그 외에도 AM/PM, WeekDay, Month, Quarter, Era 등 locale 설정 별로 달라질 수 있는 Symbols의 배열을 얻을 수도 있다.
// Calendar로부터 날짜 요소별 Symbol 얻기
var calendar = Calendar(identifier: .gregorian)
calendar.locale = Locale(identifier: "ko_kr")
print(calendar.amSymbol, calendar.pmSymbol) // 오전 오후
print(calendar.eraSymbols) // ["BC", "AD"]
print(calendar.weekdaySymbols) // ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
print(calendar.quarterSymbols) // ["제 1/4분기", "제 2/4분기", "제 3/4분기", "제 4/4분기"]
print(calendar.monthSymbols) // ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"]
print(calendar.longEraSymbols) // ["기원전", "서기"]
🔍 DateComponents
자료형을 살펴보면 Optional타입이다. 그래서 모든 파라미터를 전달하지 않더라도 기본값이 nil이기 때문에 원하는 파라미터만 골라서 사용할 수 있다.
👉🏻 example
아래는 DateComponents를 활용하여 원하는 년,월,일만 생성하여 원하는 포맷으로 설정하는 과정이다.
var calendar = Calendar(identifier: .gregorian) // 인스턴스 생성: 캘린더 유형 설정
let dateComponents = DateComponents(year: 2222, month: 2, day: 22) // 원하는 요소만 입력하여 날짜 추출
let myDate = calendar.date(from: dateComponents) // date타입으로 변환. 옵셔널 타입이다.
let formatter = DateFormatter() // 포맷설정을 위해 인스턴스 생성
formatter.locale = Locale(identifier: "ko_kr") // 한국 시간으로 지정
formatter.dateStyle = .full // 날짜스타일 지정
print(formatter.string(from: myDate!)) // 2222년 2월 22일 금요일
아래와 같이 날짜의 각 요소들을 추출할 수도 있다.
let date = Date()
print(calendar.dateComponents([.weekday, .day, .month, .year], from: date)) // year: 2021 month: 8 day: 25 weekday: 4 isLeapMonth: false
Reference
'Swift > iOS' 카테고리의 다른 글
[iOS] Bundle이 뭘까? (0) | 2021.09.28 |
---|---|
[iOS/Xcode] Auto Layout에 대해 알아보자. (1) | 2021.09.27 |
[Swift/iOS] FileManager로 파일 생성(쓰기), 읽기, 삭제하기 (3) | 2021.08.27 |
[Swift/iOS] Codable로 JSON을 파싱해보자. (0) | 2021.08.22 |
[Swift/iOS] 메모리를 관리해주는 ARC에 대해 알아보자. (0) | 2021.08.15 |