Date와 DateFormatter 에 대한 내용을 가끔 쓰는데 쓸때 마다 조금씩 헷갈려서 내용을 정리해 두려고 한다.
고고
📅 Date란?
struct Date
A specific point in time, independent of any calendar or time zone.
시간의 특정한 포인트로, 어떠한 캘린더나 타임존으로 부터 자유하다고 한다.
그래서 지금 시간을 찍어보면
Date 를 찍어보면 이런 식으로 나온다.
2022-10-01 11:40:34 +0000
년도-월-일 시간:분:초 +시간대
이런 포멧이다
사실은 지금이 8시 인데 11시 로 나오는 이유는 표준 시간대(UTF)를 사용하기 때문이다.
(그래서 영국 시간 기준인가? 봤더니 지금 영국도 써머타임 때문에 저 시간에서 약간 오차가 있는 거 같다.)
secondsSince1970: 1972년 1월 1일부터로부터 몇초가 경과했는지
이런것도 지원하고
iso8601: 날짜와 시간과 관련된 데이터 교환을 다루는 국제 표준
이런것도 지원한다.
아직 저 2개는 잘쓸 일이 없어서...
📅 Date formatted
Date 에는 formatted 란 메서드가 존재한다.
애플이 다양한 포멧들을 미리 정해 놓았고, 이 포멧들에 따라 출력을 해준다.
🟡 formatted
let date = Date()
date.formatted(.dateTime)
// "10/2/2022, 1:10 AM"
date.formatted(date: .long, time: .omitted)
// "October 2, 2022"
date.formatted(date: .abbreviated, time: .omitted)
// "Oct 2, 2022"
date.formatted(date: .complete, time: .omitted)
// "Sunday, October 2, 2022"
date.formatted(date: .numeric, time: .omitted)
// "10/2/2022"
date.formatted(date: .omitted, time: .complete)
// "1:10:39 AM GMT+9"
date.formatted(date: .omitted, time: .standard)
// "1:10:39 AM"
date.formatted(date: .omitted, time: .shortened)
// "1:10 AM"
date.formatted(date: .omitted, time: .omitted)
// "10/2/2022, 1:10 AM"
이런식의 출력을 보여준다.
이렇게 정해져 있는 포멧도 있는데 조금더 세부적으로 선택할 수도 있다.
Date.FormatStyle
라는 타입을 이용하면 된다.
🟡 year
date.formatted(Date.FormatStyle().year(.defaultDigits))
// "2022"
date.formatted(Date.FormatStyle().year(.twoDigits))
// "22"
date.formatted(Date.FormatStyle().year(.padded(6)))
// "002022"
🟡 weekday
date.formatted(Date.FormatStyle().weekday(.abbreviated))
// "Sun"
date.formatted(Date.FormatStyle().weekday(.short))
// "Su"
date.formatted(Date.FormatStyle().weekday(.narrow))
// "S"
date.formatted(Date.FormatStyle().weekday(.oneDigit))
// "1"
date.formatted(Date.FormatStyle().weekday(.twoDigits))
// "1"
date.formatted(Date.FormatStyle().weekday(.wide))
// "Sunday"
🟡 week
date.formatted(Date.FormatStyle().week(.defaultDigits))
// "41"
date.formatted(Date.FormatStyle().week(.twoDigits))
// "41"
date.formatted(Date.FormatStyle().week(.weekOfMonth))
// "2"
date.formatted(Date.FormatStyle().week())
// "41"
🟡 quarter
date.formatted(Date.FormatStyle().quarter(.abbreviated))
// "Q4"
date.formatted(Date.FormatStyle().quarter(.narrow))
// "4"
date.formatted(Date.FormatStyle().quarter(.oneDigit))
// "4"
date.formatted(Date.FormatStyle().quarter(.twoDigits))
// "04"
date.formatted(Date.FormatStyle().quarter(.wide))
// "4th quarter"
date.formatted(Date.FormatStyle().quarter())
// "Q4"
🟡 month
date.formatted(Date.FormatStyle().month(.abbreviated))
// "Oct"
date.formatted(Date.FormatStyle().month(.narrow))
// "O"
date.formatted(Date.FormatStyle().month(.defaultDigits))
// "10"
date.formatted(Date.FormatStyle().month(.twoDigits))
// "10"
date.formatted(Date.FormatStyle().month(.wide))
// "October"
date.formatted(Date.FormatStyle().month())
// "Oct"
🟡 era
date.formatted(Date.FormatStyle().era(.abbreviated))
// "AD"
date.formatted(Date.FormatStyle().era(.narrow))
// "A"
date.formatted(Date.FormatStyle().era(.wide))
// "Anno Domini"
date.formatted(Date.FormatStyle().era())
// "AD"
🟡 dayOfYear
date.formatted(Date.FormatStyle().dayOfYear(.defaultDigits))
// "275"
date.formatted(Date.FormatStyle().dayOfYear(.twoDigits))
// "275"
date.formatted(Date.FormatStyle().dayOfYear(.threeDigits))
// "275"
date.formatted(Date.FormatStyle().dayOfYear())
// "275"
🟡 day
date.formatted(Date.FormatStyle().day(.defaultDigits))
// "2"
date.formatted(Date.FormatStyle().day(.ordinalOfDayInMonth))
// "1"
date.formatted(Date.FormatStyle().day(.twoDigits))
// "02"
date.formatted(Date.FormatStyle().day())
// "2"
🟡 hour
date.formatted(Date.FormatStyle().hour(.defaultDigits(amPM: .abbreviated)))
// "1 AM"
date.formatted(Date.FormatStyle().hour(.defaultDigits(amPM: .wide)))
// "1 AM"
date.formatted(Date.FormatStyle().hour(.defaultDigits(amPM: .narrow)))
// "1 a"
date.formatted(Date.FormatStyle().hour(.defaultDigits(amPM: .omitted)))
// "01"
date.formatted(Date.FormatStyle().hour(.conversationalDefaultDigits(amPM: .abbreviated)))
// "1 AM"
date.formatted(Date.FormatStyle().hour(.conversationalDefaultDigits(amPM: .wide)))
// "1 AM"
date.formatted(Date.FormatStyle().hour(.conversationalDefaultDigits(amPM: .narrow)))
// "1 a"
date.formatted(Date.FormatStyle().hour(.conversationalDefaultDigits(amPM: .omitted)))
// "01"
date.formatted(Date.FormatStyle().hour(.conversationalTwoDigits(amPM: .abbreviated)))
// "01 AM"
date.formatted(Date.FormatStyle().hour(.conversationalTwoDigits(amPM: .wide)))
// "01 AM"
date.formatted(Date.FormatStyle().hour(.conversationalTwoDigits(amPM: .narrow)))
// "01 a"
date.formatted(Date.FormatStyle().hour(.conversationalTwoDigits(amPM: .omitted)))
// "01"
date.formatted(Date.FormatStyle().hour(.twoDigits(amPM: .abbreviated)))
// "01 AM"
date.formatted(Date.FormatStyle().hour(.twoDigits(amPM: .wide)))
// "01 AM"
date.formatted(Date.FormatStyle().hour(.twoDigits(amPM: .narrow)))
// "01 a"
date.formatted(Date.FormatStyle().hour(.twoDigits(amPM: .omitted)))
// "01"
🟡 minute
date.formatted(Date.FormatStyle().minute())
// "50"
date.formatted(Date.FormatStyle().minute(.twoDigits))
// "50"
date.formatted(Date.FormatStyle().minute(.defaultDigits))
// "50"
🟡 timeZone
date.formatted(Date.FormatStyle().timeZone())
// "GMT+9"
date.formatted(Date.FormatStyle().timeZone(.identifier(.long)))
// "Asia/Seoul"
date.formatted(Date.FormatStyle().timeZone(.identifier(.short)))
// "krsel"
date.formatted(Date.FormatStyle().timeZone(.exemplarLocation))
// "Seoul"
date.formatted(Date.FormatStyle().timeZone(.genericLocation))
// "South Korea Time"
date.formatted(Date.FormatStyle().timeZone(.genericName(.long)))
// "Korean Standard Time"
date.formatted(Date.FormatStyle().timeZone(.genericName(.short)))
// "South Korea Time"
date.formatted(Date.FormatStyle().timeZone(.iso8601(.long)))
// "+09:00"
date.formatted(Date.FormatStyle().timeZone(.iso8601(.short)))
// "+0900"
date.formatted(Date.FormatStyle().timeZone(.localizedGMT(.long)))
// "GMT+09:00"
date.formatted(Date.FormatStyle().timeZone(.localizedGMT(.short)))
// "GMT+9"
date.formatted(Date.FormatStyle().timeZone(.specificName(.long)))
// "Korean Standard Time"
date.formatted(Date.FormatStyle().timeZone(.specificName(.short)))
// "GMT+9"
🟡 종합해서 쓰기
date.formatted(
Date.FormatStyle()
.year(.defaultDigits)
.month(.abbreviated)
.day(.twoDigits)
.hour(.defaultDigits(amPM: .abbreviated))
.minute(.twoDigits)
.timeZone(.identifier(.long))
.era(.wide)
.dayOfYear(.defaultDigits)
.weekday(.abbreviated)
.week(.defaultDigits)
)
// "Sun, Oct 02, 2022 Anno Domini (week: 41), 1:36 AM Asia/Seoul"
📅 DateFormatter
그런데
2022년 8월 2일 이렇게 한글로 쓰고 싶으면 어떻게 해야할까?
number 엔 numberFormatter 가 있듯 dateFormatter 가 있다.
보통은 전역적으로 생성을 해 놓고 많이 사용하는 것 같다.
데이터포멧터에도 미리 지정된 스타일들이 좀 있고 아예 커스텀을 할 수 있는 방법들이 있다.
먼저 미리 지정된 스타일들을 보자.
🟡 basic
let dateformatter = DateFormatter()
dateformatter.dateStyle = .short
dateformatter.string(from: date)
// "10/2/22"
dateformatter.dateStyle = .medium
dateformatter.string(from: date)
// "Oct 2, 2022"
dateformatter.dateStyle = .long
dateformatter.string(from: date)
// "October 2, 2022"
dateformatter.dateStyle = .full
dateformatter.string(from: date)
// "Sunday, October 2, 2022"
dateformatter.dateStyle = .none
dateformatter.string(from: date)
// ""
🟡 Locale
원래 아까 봤듯 Date 의 시간대는 UTF 표준시 인데
Locale 을 이용하면 시간도 한국 시간대로 언어도 한국어로 바꿔줄 수 있다.
let dateformatter = DateFormatter()
dateformatter.locale = Locale(identifier: "ko_KR")
dateformatter.dateStyle = .short
dateformatter.string(from: date)
// "2022. 10. 2."
dateformatter.dateStyle = .medium
dateformatter.string(from: date)
// "2022. 10. 2."
dateformatter.dateStyle = .long
dateformatter.string(from: date)
// "2022년 10월 2일"
dateformatter.dateStyle = .full
dateformatter.string(from: date)
// "2022년 10월 2일 일요일"
dateformatter.dateStyle = .none
dateformatter.string(from: date)
// ""
🟡 cusotom format
커스텀 포멧은 이 표를 보고 만들면 된다.
Format | |
---|---|
yyyy | 년도 |
MM | 월 |
dd | 일 |
HH | 24단위 시간 |
hh | 12 단위 시간 |
a | 오전 오후 표기 |
mm | 분 |
ss | 초 |
SSS | 밀리초 |
let dateformatter = DateFormatter()
dateformatter.locale = Locale(identifier: "ko_KR")
dateformatter.dateFormat = "yyyy년 MM월 dd일 a hh시 mm분"
dateformatter.string(from: date)
// "2022년 10월 02일 오전 02시 17분"
이런식으로 활용하면 된다!
지금 02일 이런식으로 나오는데 2일 으로 하고 싶으면
dateformatter.dateFormat = "yyyy년 MM월 d일 a h시 mm분"
dateformatter.string(from: date)
// "2022년 10월 2일 오전 2시 17분"
dd -> d 이렇게 바꾸면 된다.
년도 월 일 시간 분 다 마찬가지다.
이런식으로 바꿔주면 된다.
🟡 String -> Date
그럼 반대로
String 으로 된 날짜를 Date 타입으로 변경해보자.
dateformatter.dateFormat = "yyyy년 MM월 dd일 a hh시 mm분"
let dateString = dateformatter.string(from: date)
// "2022년 10월 02일 오전 02시 17분"
dateformatter.date(from: dateString)
// "2022-10-01 17:21:00 +0000\n"
이렇게 된다. 시간대가 달라진것을 보면 알겠지만 다시 UTF 시간대로 돌아감...
dateformatter 의 locale 이 한국으로 되어 있어서 한국시간을 넣었군... 다시 UTF 시간대로 돌려 놔야지 이런 느낌이다.
🟡 Locale, timeZone 찾기
Locale identifier 찾는 곳
위의 깃허브에서 찾아도 되고,
for locale in Locale.availableIdentifiers {
print(locale)
}
이 메서드를 통해서 모든 Locale Identifier 를 뽑아 볼 수 있다.
for timeZone in TimeZone.knownTimeZoneIdentifiers {
print(timeZone)
}
타임존도 이 방법으로 모든 타임존을 뽑아볼 수 있다.
'🍎 iOS > 🕊️ swift' 카테고리의 다른 글
[swift]@property wrapper (0) | 2023.01.06 |
---|---|
[swift] 의존성 주입으로 코드를 예쁘게 하자! (0) | 2023.01.06 |
[swift] 부동 소수점 오류가 나는 이유 (0) | 2023.01.06 |
[swift] 고차 함수 요목조목 보기 (0) | 2023.01.06 |
[iOS] Number Fomatter (0) | 2023.01.06 |