[iOS] Date Formatter

Youngwoo Lee·2021년 6월 3일
1

iOS

목록 보기
17/46
post-thumbnail
post-custom-banner

프로젝트 요구사항 중 작성일자를 사용자의 지역 포멧에 맞게 표현해야 되서 찾아보는 Date Formatter

참고 자료: Developer Document
https://developer.apple.com/documentation/foundation/dateformatter

Date Formatter

날짜와 텍스트 표현을 변환하는 형식이다

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
}

Working With User-Visible Representations of Dates and Times

사용자에게 날짜를 표시할 때 특정 필요에 따라 date formatterdateStyle, 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

Working With Fixed Format Date Representations

RFC 3339와 같은 고정 fotmat의 날짜로 작업할 때는, dateFormat property를 string 값으로 설정해주면 됩니다. 대부분의 고정 형식의 경우 locale property 값을 POSIX locale("en_US_POSIX")으로, timeZone property 값을 UTC로 설정해줍니다.

Thread Safety

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))
}
profile
iOS Developer Student
post-custom-banner

0개의 댓글