프로젝트 요구사항 중 작성일자를 사용자의 지역 포멧에 맞게 표현해야 되서 찾아보는 Date Formatter
참고 자료: Developer Document
https://developer.apple.com/documentation/foundation/dateformatter
날짜와 텍스트 표현을 변환하는 형식이다
class DateFormatter: Formatter
DateFormatter의 인스턴스는, NSDate 객체의 문자열 표현을 생성하고 날짜 및 시간의 텍스트 표현을 NSDate 객체로 변환한다. 사용자가 볼 수 있는 날짜 및 시간 표현을 위해 DateFormatter는 다양한 지역화된 사전 설정 및 구성 옵션을 제공한다. 날짜 및 시간의 고정 형식 표현의 경우 사용자 지정 형식 문자열을 지정할 수 있다.
ISO 8601 형식의 날짜 표현을 사용할 때는 대신 ISO 8601 Date Formatter을 사용해야한다
두 NSDate 객체 간의 간격을 나타내려면 대신 DateIntervalFormatter
를 사용해야 한다
NSDateComponents 객체로 지정된 시간을 나타내려면 대신 DateComponentsFormatter를 사용하십시오
let dateComponents = NSDateComponents()
dateComponents.day = 4
dateComponents.month = 5
dateComponents.year = 2017
if let gregorianCalendar = NSCalendar(calendarIdentifier: .gregorian),
let date = gregorianCalendar.date(from: dateCompoents as DateComponents) {
let weekday = gregorianCalendar.component(.weekday, from: date)
print(weekday) // 5
}
사용자에게 날짜를 표시할 때 특정 필요에 따라 date formatter의 dateStyle
, timeStyle
속성을 설정합니다. 예를 들어, 시간을 표시하지 않고, 월, 일, 및 연도를 표시하려면 dateStyle
property 값을 DateFormatter.Style.long으로 설정하면 됩니다. 그리고 timeStyle
property를 DateFormatter.Style.none으로 설정하면 됩니다. 반대로 시간만 표시하려면 dateStyle
property를 DateFormatter.Style.none으로, timeStyle
property를 DateFormatter.Style.short로 설정하면 됩니다. dateStyle, timeStyle
property 값에 따라서 DateFormatter는 지정된 날짜에 대한 표현을 제공합니다
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
let date = Date(timeIntervalSinceReferenceDate: 118800)
// US English Locale (en_US)
dateFormatter.locale = Locale(identifier: "en_US")
print(dateFormatter.string(from: date)) // Jan 2, 2001
// French Locale (fr_FR)
dateFormatter.locale = Locale(identifier: "fr_FR")
print(dateFormatter.string(from: date)) // 2 janv. 2001
// Japanese Locale (ja_JP)
dateFormatter.locale = Locale(identifier: "ja_JP")
print(dateFormatter.string(from: date)) // 2001/01/02
만약에 미리 정의된 스타일을 사용하여 달성할 수 없는 형식을 정의해야 하는 경우에는 setLocalizedDateFormatterFromTemplate(_:)
를 사용하여 템플릿에서 local 화된 날짜 형식을 지정할 수 있습니다
let dateFormatter = DateFormatter()
let date = Date(timeIntervalSinceReferenceDate: 410220000)
// US English Locale (en_US)
dateFormatter.locale = Locale(identifier: "en_US")
dateFormatter.setLocalizedDateFormatFromTemplate("MMMMd") // set template after setting locale
print(dateFormatter.string(from: date)) //December 31
// British English Locale (en_GB)
dateFormatter.locale = Locale(identifier: "en_GB")
dateFormatter.setLocalizedDateFormatFromTemplate("MMMMd")
print(dateFormatter.string(from: date)) //31 December
RFC 3339와 같은 고정 fotmat의 날짜로 작업할 때는, dateFormat
property를 string 값으로 설정해주면 됩니다. 대부분의 고정 형식의 경우 locale
property 값을 POSIX locale("en_US_POSIX")으로, timeZone
property 값을 UTC로 설정해줍니다.
iOS 7 이후로 NSDateFormatter 는 Thread Safe 하게 되었다
Date Formatter의 경우 매우 expensive한 동작을 보여준다. 그래서 최대한 효율적으로 활용하는 것이 좋다. 링크 참조
프로젝트에서의 활용 방법
이전
struct Memo: Decodable {
let title: String
let body: String
private let lastModified: Int
var lastModifiedDate: String {
let date = Date(timeIntervalSince1970: TimeInterval(lastModified))
let dateFormatter: DateFormatter = DateFormatter()
...
}
}
이후
struct Memo: Decodable {
let title: String
let body: String
let lastModified: Int
}
//...
//<중략>
//...
let dateFormatter: DateFormatter = DateFormatter()
for memo in memos {
let date = Date(timeIntervalSince1970: TimeInterval(memo.lastModified))
dateFormatter.locale = Locale(identifier: Locale.current.identifier)
dateFormatter.setLocalizedDateFormatFromTemplate("yyyy. MM. d")
let dateString = dateFormatter.string(from: date)
memoViewModels.append(MemoViewModel(title: memo.title, date: dateString, content: memo.body))
}