Search
Duplicate

스위프트에서 날짜와 시간 다루기

생성일
2023/07/12 13:28
태그
Framework

스위프트에서 날짜와 시간 다루기

UTC

국제적인 표준 시간 - 협정 세계시

유닉스 기준 시간

1970.01.01 00:00:00 UTC
.timeIntervalSince1970
Date() - 유닉스 기준 시간
TimeInterval 타입 (타임 인터벌의 개념 - 초단위)

Date 구조체의 이해

Date()
지금 현재시점 Date 인스턴스 생성
특정 달력(양력, 음력) 이나 타임존에 영향을 받지 않는 독립적인 시간(값)
기준시간 (Reference Date) : 2001.01.01 00:00:00 UTC
.timeIntervalSinceReferenceDate
Date() - Reference Date (초단위)
TimeInterval 타입 (타임 인터벌의 개념 - 초단위)
// 날짜와 시간을 다루는 Date 구조체의 인스턴스 let now = Date() // 생성시점의 날짜와 시간을 생성해서 (기준시간으로부터) 초단위 기준값을 가지고 있음 print(now) // 그냥 출력하면 항상 UTC 기준의 시간으로 출력 // 2023-07-12 23:52:27 +0000 now.timeIntervalSinceReferenceDate // 710,898,747.820513 now.timeIntervalSince1970 // 1,689,206,014.177338 let oneSecond = TimeInterval(1.0) // 1초 간격 /**============================================ - 60초(1분) * 60분(1시간) * 24시간 = 하루를 초기준으로 - 1) 3600초 (1시간) - 2) 3600 * 24 = 86,400 초 (하루) ===============================================**/ let yesterday = now - 86400 print(yesterday) now.timeIntervalSince(yesterday) // 해당 시점으로부터 차이를 초로 (86,400초 차이) now.distance(to: yesterday) // 지금시점을 기준으로 그 시간까지의 거리를 초로 yesterday.distance(to: now) now.advanced(by: 86400) // 내일 now.addingTimeInterval(3600 * 24) now + 86400 let tomorrow = Date(timeIntervalSinceNow: 86400)
Swift
복사

Calendar 구조체의 이해

달력 및 달력의 요소를 다루는 Calendar 구조체 (양력/음력)
달력을 이루는 요소 기준
년/월/일 + 시/분/초 + 요일
“절대 시점(Date)”를 연대/연도/날짜/요일과 같은 “달력의 요소”로 변환을 돕는 객체
// 그레고리력 - 양력 (전세계표준 달력) ⭐️ var calendar = Calendar.current // 타입 속성 --> 현재의 달력(양력) 변환 /**================================================================================ let calendar1 = Calendar(identifier: .gregorian) // 직접 생성하기 (이런 방식으로 잘 사용하지는 않음) let calendar2 = Calendar.autoupdatingCurrent // 유저가 선택한 달력 기준(세계적 서비스를 한다면) ==================================================================================**/
Swift
복사
지역설정 → 나라(지역)마다 날짜와 시간을 표시하는 형식과 언어가 다름
calendar.locale // 달력의 지역 (영어/한국어) (달력 표기 방법과 관련된 개념) calendar.timeZone // 타임존 --> Asia/Seoul (UTC 시간관련된 개념) // 필요할때 찾아서 쓰면됨 calendar.locale = Locale(identifier: "ko_KR") //calendar.timeZone = TimeZone(identifier: "Asia/Seoul") /**================================================================================== - 지역설정 문자열: https://gist.github.com/xta/6e9b63db1fa662bb3910b680f9ebd458 (700여개) - 타임존 문자열: https://gist.github.com/mhijack/2b63b84d96802ccc719291474ac9df72 (440여개) ==================================================================================**/
Swift
복사
Date의 “년/월/일/시/분/초”를 확인하는 방법
// 1) 날짜 - 년 / 월 / 일 let year: Int = calendar.component(.year, from: now) let month: Int = calendar.component(.month, from: now) let day: Int = calendar.component(.day, from: now) // 2) 시간 - 시 / 분 / 초 let timeHour: Int = calendar.component(.hour, from: now) let timeMinute: Int = calendar.component(.minute, from: now) let timeSecond: Int = calendar.component(.second, from: now) // 3) 요일 let weekday: Int = calendar.component(.weekday, from: now) // 일요일 - 1 // 월요일 - 2 // 화요일 - 3 // ... // 토요일 - 7 print("\(year)\(month)\(day)일")
Swift
복사
하나의 요소가 아닌 여러 개의 데이터를 얻는 방법은? DateComponents
let myCal = Calendar.current var myDateCom = myCal.dateComponents([.year, .month, .day], from: now) //myCal.dateComponents(<#T##components: Set<Calendar.Component>##Set<Calendar.Component>#>, from: <#T##Date#>) myDateCom.year myDateCom.month myDateCom.day print("\(myDateCom.year!)\(myDateCom.month!)\(myDateCom.day!)일")
Swift
복사
실제 프로젝트에서 활용하는 방식
달력을 기준으로, 나이 계산 하기
class Dog { var name: String var yearOfBirth: Int init(name: String, year: Int) { self.name = name self.yearOfBirth = year } // 나이를 계산하는 계산 속성 var age: Int { get { let now = Date() let year = Calendar.current.component(.year, from: now) return year - yearOfBirth } } } let choco = Dog(name: "초코", year: 2015) choco.age
Swift
복사
열거형으로 요일을 만들고, 오늘의 요일을 계산하기
// (원시값)열거형으로 선언된 요일 enum weekday: Int { case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday // 타입 계산 속성 static var today: Weekday { let weekday: Int = Calendar.current.component(.weekday, from: Date()) // 요일을 나타내는 정수 return Weekday(rawValue: weekday)! } } // 오늘이 무슨 요일인지 let today = Weekday.today
Swift
복사
두 날짜 사이의 일 수 계산하기
let startDate = Date() let endDate = startDate.addingTimeInterval(3600 * 24 * 60) let calendar2 = Calendar.current let someDays = calendar2.dateComponents([.day], from: startDate, to: endDate).day! print("\(someDays)일 후")
Swift
복사

날짜를 제대로 다루려면?

1.
달력을 다루는 Calendar 구조체의 도움도 필요 (양력, 음력인지)
2.
문자열로 변형해주는 DateFormatrer 클래스의 도움도 필요
스위프트 내부에 미리 정의된 타임존 확인해보기
for localeName in TimeZone.knownTimeZoneIdentifiers { print(localeName) }
Swift
복사

DateFormatter

“형식” 문자열(String)로 변형해 주는 DateFormatter 클래스
표시하기 위한 문자열
Date를 특정 형식의 문자열로 변환하려면, 1) 지역설정 + 2) 시간대설정 + 3) 날짜형식 + 4) 시간형식
// 날짜 + 시간 <--> String let formatter = DateFormatter() // 지역 및 시간대 설정 /**========================================== (1) 지역 설정 ============================================**/ // 나라 / 지역마다 날짜와 시간을 표시하는 형식과 언어가 다름 formatter.locale = Locale(identifier: "ko_KR") // "2021년 5월 8일 토요일 오후 11시 44분 24초 대한민국 표준시" formatter.locale = Locale(identifier: "en_US") // "Saturday, May 8, 2021 at 11:45:51 PM Korean Standard Time" /**========================================== (2) 시간대 설정(기본설정이 있긴 하지만) ============================================**/ formatter.timeZone = TimeZone.current
Swift
복사
표시하려는 날짜와 시간 설정
/**========================================== 1) (애플이 미리 만들어 놓은) 기존 형식으로 생성 ============================================**/ // (1) 날짜 형식 선택 formatter.dateStyle = .full // "Tuesday, April 13, 2021" //formatter.dateStyle = .long // "April 13, 2021" //formatter.dateStyle = .medium // "Apr 13, 2021" //formatter.dateStyle = .none // (날짜 없어짐) //formatter.dateStyle = .short // "4/13/21" // (2) 시간 형식 선택 formatter.timeStyle = .full // "2:53:12 PM Korean Standard Time" //formatter.timeStyle = .long // "2:54:52 PM GMT+9" //formatter.timeStyle = .medium // "2:55:12 PM" //formatter.timeStyle = .none // (시간 없어짐) //formatter.timeStyle = .short // "2:55 PM" // 실제 변환하기 (날짜 + 시간) ===> 원하는 형식 let someString1 = formatter.string(from: Date()) print(someString1) /**========================================== 2) 커스텀 형식으로 생성 ============================================**/ //formatter.locale = Locale(identifier: "ko_KR") //formatter.dateFormat = "yyyy/MM/dd" formatter.dateFormat = "yyyy년 MMMM d일 (E)" let someString2 = formatter.string(from: Date()) print(someString2) // 문자열로 만드는 메서드 //formatter.string(from: <#T##Date#>) /**============================================================================================== - 날짜/시간 형식: http://www.unicode.org/reports/tr35/tr35-25.html#Date_Format_Patterns (유니코드에서 지정) ===============================================================================================**/
Swift
복사
반대로, (형식)문자열에서 Date로 변환하는 것도 가능
let newFormatter = DateFormatter() newFormatter.dateFormat = "yyyy/MM/dd" let someDate = newFormatter.date(from: "2021/07/12")! print(someDate)
Swift
복사
두 날짜 범위 출력 코드 구현 (두 날짜 사이의 일수를 구하려는 것 아님)
let start = Date() let end = start.addingTimeInterval(3600 * 24 * 60) let formatter2 = DateFormatter() formatter2.locale = Locale(identifier: "ko_KR") formatter2.timeZone = TimeZone.current // formatter2.timeZone = TimeZone(identifier: "Asia/Seoul") formatter2.dataStyle = .long formatter2.timeStyle = .none print("기간: \(formatter2.string(from: start)) - \(formatter2.string(from: end))")
Swift
복사
프로젝트에서 활용 예시
struct InstagramPost { let title: String = "제목" let description: String = "내용설명" private let date: Date = Date() // 게시물 생성을 현재날짜로 // 날짜를 문자열 형태로 바꿔서 리턴하는 계산 속성 var dateString: String { get { let formatter = DdateFormatter() formatter.locale = Locale(identifier: "ko_KR") // formatter.locale = Locale(identifier: Locale.autoupdatingCurrent.identifier) // 애플이 만들어 놓은 formatter.dateStyle = .medium formatter.timeStyle = .full // 개발자가 직접 설정한 // formatter.dataFormat = "yyyy/MM/dd" return formatter.string(from: date) } } } let post1 = InstagramPost() print(post1.dateString)
Swift
복사