김경록의 앱 개발 여정

[Swift] 유튜브처럼 타임라인 포맷팅하기 본문

TIL

[Swift] 유튜브처럼 타임라인 포맷팅하기

Kim Roks 2025. 3. 10. 19:12

 

출처: 침착맨 유튜브

 

유튜브나 인스타 등에서 유저의 시간 기록을 위와 같이 포맷팅 하는 방법에 대해 짤막하게 써보겠습니다.

코드 

import Foundation

extension String {
    func timeAgo() -> String? {
        // ISO8601DateFormatter를 사용하여 입력된 날짜 문자열을 Date로 변환
        let formatter = ISO8601DateFormatter()
        guard let inputDate = formatter.date(from: self) else { return nil }
        
        // UTC 시간대 기준으로 현재 시간을 가져옵니다.
        let calendar = Calendar.current
        guard let now = calendar.date(
            byAdding: .second,
            value: TimeZone.current.secondsFromGMT(),
            to: Date()
        ) else { return nil }
        
        // UTC 시간대 기준으로 현재 시간과 inputDate 사이의 차이를 구합니다.
        let components = calendar.dateComponents([.year, .month, .weekOfYear, .day, .hour, .minute], from: inputDate, to: now)
        
        if let years = components.year, years > 0 {
            return "\(years)년 전"
        } else if let months = components.month, months > 0 {
            return "\(months)개월 전"
        } else if let weeks = components.weekOfYear, weeks > 0 {
            return "\(weeks)주 전"
        } else if let days = components.day, days > 0 {
            return "\(days)일 전"
        } else if let hours = components.hour, hours > 0 {
            return "\(hours)시간 전"
        } else if let minutes = components.minute, minutes > 0 {
            return "\(minutes)분 전"
        } else {
            return "방금 전"
        }
    }
}

 

저는 백엔드에서 ISO8601 형식을 사용하고 있기때문에 해당 방식의 포맷터를 사용합니다.

여러 방식이 있겠지만 개인적으로 가장 편하다고 생각하여 String의 확장 메서드로 정의했습니다.

초 단위는 유튜브처럼 방금 전 으로 표시할 수 있게 했습니다.

고려 사항

1) 시간대(TimeZone)의 처리

Swift에서 날짜와 시간을 다룰 때,  Date 객체는 기본적으로 UTC(협정 세계시)를 기준으로 처리됩니다.
하지만, 시스템의 로컬 시간대는 각 사용자의 위치에 따라 다르기 때문에, 시간대 차이를 고려하지 않으면 잘못된 계산이 이루어질 수 있습니다.

예를 들어, 한국 시간(KST)에서 2025-03-10T18:20:56Z라는 시간을 처리할 때, Date()는 기본적으로 로컬 시간(KST)을 기준으로 작동하기 때문에, TimeZone을 고려하여 UTC와 시스템 시간대의 차이를 조정해야 합니다.

따라서 Date를 생성할 때 UTC 시간을 처리하도록 하는 것이 중요합니다. 위 코드에서는 TimeZone.current.secondsFromGMT()를 사용하여 현재 시스템의 시간대 차이를 초 단위로 계산한 후, 이를 UTC 기준으로 변환하고 있습니다.

let now = calendar.date(byAdding: .second, value: TimeZone.current.secondsFromGMT(), to: Date())!

 

2) DateFormatter 사용 시 주의사항

DateFormatter는 날짜 문자열을 Date로 변환할 때 매우 유용하지만, 날짜 형식에 맞는 정확한 포맷팅이 필요합니다. 예를 들어, ISO 8601 형식의 날짜 문자열을 처리하려면, ISO8601DateFormatter를 사용해야 합니다. DateFormatter와 달리 ISO8601DateFormatter는 기본적으로 UTC를 기준으로 날짜를 처리합니다.