[Swift] Youtube API 활용하여 앱 만들기 (4) : NumberFormatter, DateComponents

Oni·2023년 9월 7일
0

TIL

목록 보기
42/47
post-thumbnail

어제 로드한 영상에 조회수랑 업로드 일자를 불러오는데 그대로 넣으니까 좀 없어보인다..

그리고 api에서 넘겨주는 date는 심지어 ISO 8601 형식이라서 그대로 쓸 수도 없다.

그래서 유튜브처럼 조회수는 천회, 만회 기준으로 그 이상일 때는 소수점 1자리로 표현하고, 업로드일자는 오늘 날짜 기준으로 몇분전, 몇시간전, 몇일전, 몇년전.. 등 으로 표기하기 위해 foamat 형식을 바꿔주는 코드를 정리해보려고 한다.


NumberFormatter

NumberFormatter는 Foundation 프레임워크에서 제공하는 클래스로, 숫자를 원하는 형식으로 서식화하고 역으로 파싱하는 데 사용한다. 주로 숫자를 문자열로 변환하거나, 문자열을 숫자로 변환할 때 유용하게 활용된다.

주요 기능 및 속성

  • numberStyle: NumberFormatter의 numberStyle 속성을 설정하여 숫자를 표시하는 스타일을 지정할 수 있음. 예를 들어, NumberFormatter.Style.decimal을 사용하면 천 단위 구분 기호를 포함한 일반적인 숫자 형식으로 표시됨
  • locale: NumberFormatter는 숫자를 지역화에 맞게 표시하므로 locale 속성을 사용하여 지역화 설정을 지정할 수 있음
  • string(from:): 숫자를 문자열로 변환할 때 사용하는 메서드
  • number(from:): 문자열을 숫자로 변환할 때 사용하는 메서드
  • positiveFormat 및 negativeFormat: 양수 및 음수 숫자에 대한 서식 지정
  • maximumFractionDigits 및 minimumFractionDigits: 소수 자릿수 제어
  • currencySymbol: 통화 기호 지정
  • roundingMode: 소수점 아래 자릿수 반올림
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
numberFormatter.locale = Locale.current

let formattedString = numberFormatter.string(from: NSNumber(value: 1234567.89))
print(formattedString) // 출력: "1,234,567.89"

if let parsedNumber = numberFormatter.number(from: "3,456.78") {
    print(parsedNumber) // 출력: 3456.78
}

커스텀 조건

api에서 전달받은 조회수는 String 형태이므로 정수형으로 먼저 변환이 필요하다. 그리고 1,000, 10,000 단위로 조회수를 표기하려고 한다.

// MARK: - ViewCount Format
private func customFormattedViewsCount(_ viewsCount: String) -> String {
	if let viewsCount = Int(viewsCount) {
		let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.maximumFractionDigits = 1

        if viewsCount >= 10000 {
        	let viewsInTenThousand = Double(viewsCount) / 10000.0
            return numberFormatter.string(from: NSNumber(value: viewsInTenThousand))! + "만회"
        } else if viewsCount >= 1000 {
        	let viewsInThousand = Double(viewsCount) / 1000.0
            return numberFormatter.string(from: NSNumber(value: viewsInThousand))! + "천회"
        } else {
        	return "\(viewsCount)회"
        }
	} else {
    	return "조회수 로드 오류"
	}
}
  • customFormattedViewsCount 클래스: 조회수를 문자열로 입력으로 받음
  • 입력된 조회수를 정수로 변환하며, 실패 시 "조회수 로드 오류" 문자열을 반환
  • NumberFormatter를 사용하여 숫자를 표시하는 서식을 지정
  • 숫자 서식은 .decimal로 설정하여 천 단위 구분 기호(쉼표)를 포함하는 서식
  • maximumFractionDigits를 1로 설정하여 소수점 이하 첫 번째 자릿수까지만 표시하도록 지정
  • 조회수가 10,000 이상인 경우, 조회수를 만 단위로 표시(예를 들어, 12,345 조회수는 "1.2만회"로 변환됨)
  • viewsCount를 10,000으로 나눈 값을 새로운 변수 viewsInTenThousand에 저장하고, NumberFormatter를 사용하여 문자열로 변환한 후 "만회" 문자열을 붙여 반환
  • 조회수가 1,000 이상인 경우, 조회수를 천 단위로 표시(예를 들어, 2,500 조회수는 "2.5천회"로 변환됨)
  • viewsCount를 1,000으로 나눈 값을 새로운 변수 viewsInThousand에 저장하고, 이를 NumberFormatter를 사용하여 문자열로 변환한 후 "천회" 문자열을 붙여 반환
  • 조회수가 1,000 미만인 경우, 조회수를 그대로 "회"로 표시
  • 모든 변환 작업을 마치고 변환된 문자열을 반환

DateComponents

DateComponents는 날짜와 시간을 구성하는 여러 구성 요소를 나타내는 객체이다. 주로 날짜 및 시간 작업을 수행할 때 사용되며, 연, 월, 일, 시, 분, 초 및 기타 시간 관련 정보를 쉽게 조작하고 검색할 수 있다.

주요 기능 및 속성

  • year, month, day, hour, minute, second: 각각 연도, 월, 일, 시, 분, 초를 나타냄(dateComponents.year: 연도)
  • calendar: DateComponents에서 사용할 달력을 지정하는 속성. 기본값은 Calendar.current이며, 이 달력은 로컬 시스템의 설정과 국가 관행에 따라 달라짐
  • timeZone: DateComponents에서 사용할 시간대를 지정하는 속성. 기본값은 TimeZone.current이며, 이 시간대는 로컬 시스템 설정에 따라 달라짐
  • era: 날짜의 연대를 나타냄. 예를 들어, 그레고리력과 율리우스력은 서로 다른 연대를 가짐
  • quarter: 분기를 나타냄(1부터 4까지의 값)
  • weekOfYear, weekday, weekOfMonth: 주 및 요일과 같은 시간 단위를 나타냄
  • isLeapMonth: 월이 윤월(윤년의 월)인지 여부를 나타냄
  • nanosecond: 나노초를 나타냄

DateComponents는 주로 Calendar와 함께 사용되며, 날짜 및 시간 연산 및 계산을 수행할 때 유용하다. 예를 들어, 특정 날짜에서 연, 월, 일을 추출하거나, 주어진 날짜에서 특정 기간을 더하거나 뺄 때 DateComponents를 사용할 수 있다. 나는 DateComponents를 사용하여 업로드 일자와 오늘 날짜의 차이를 계산하여 표시하려고 한다.

// MARK: - Date Format
private func timeAgoSinceDate(_ isoDateString: String) -> String {
	let dateFormatter = ISO8601DateFormatter()
        
	guard let date = dateFormatter.date(from: isoDateString) else {
		return "Invalid Date"
	}
        
	let currentDate = Date()
	let calendar = Calendar.current
	let components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date, to: currentDate)
        
	if let year = components.year, year > 0 {
		return "\(year)년 전"
	} else if let month = components.month, month > 0 {
		return "\(month)개월 전"
	} else if let day = components.day, day > 0 {
		return "\(day)일 전"
	} else if let hour = components.hour, hour > 0 {
		return "\(hour)시간 전"
	} else if let minute = components.minute, minute > 0 {
		return "\(minute)분 전"
	} else if let second = components.second, second > 0 {
		return "\(second)초 전"
	} else {
		return "방금 전"
	}
}
  • ISO8601DateFormatter: 이 클래스는 ISO 8601 형식의 날짜 문자열을 날짜로 파싱하는 데 사용됨. date(from:) 메서드를 호출하여 문자열을 날짜로 변환
  • Date: 현재 날짜를 가져옴
  • Calendar.current: 현재 달력을 사용하여 두 날짜 간의 차이를 계산
  • dateComponents: Calendar.current.dateComponents 메서드를 사용하여 두 날짜 사이의 연도, 월, 일, 시간, 분, 초 차이를 계산
  • 상대적인 시간 문자열 생성: 계산된 차이를 기반으로 상대적인 시간 문자열을 생성함. 먼저 연, 월, 일, 시간, 분, 초 순서로 차이를 확인하고 해당하는 문자열을 반환하며, 만약 모든 차이가 0이면 "방금 전"을 반환

🤳🏻적용화면

profile
하지만 나는 끝까지 살아남을 거야!

0개의 댓글