๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐ŸŽ iOS & Swift

[iOS] DateFormat, ์—ด๊ฑฐํ˜•์œผ๋กœ ์ข€ ๋” ์‰ฝ๊ฒŒ ๋‹ค๋ฃจ๊ธฐ

๋“ค์–ด๊ฐ€๋ฉฐ

์•ˆ๋…•ํ•˜์„ธ์š”, ํƒœ๋ผ์ž…๋‹ˆ๋‹ค :) ์ •๋ง ์˜ค๋žœ๋งŒ์— ๊ธ€์„ ์”๋‹ˆ๋‹ค..๐Ÿ˜‚ ์š”์ƒˆ ๋ฒˆ์•„์›ƒ์ด ์˜ฌ ๊ฒƒ๋งŒ ๊ฐ™์•„์„œ ์•„์Šฌ์•„์Šฌ ํ•˜๋ฃจ๋ฅผ ๋ณด๋‚ด๊ณ  ์žˆ์ง€๋งŒ ๋‹ค์‹œ๊ธˆ ๋งˆ์Œ์„ ๋‹ค์žก๊ณ  ์—ด์‹ฌํžˆ ํ•ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ๊ธ€ ์“ฐ๋Š” ๊ฒƒ์„ ์ƒ๊ฐ๋ณด๋‹ค ๋„ˆ๋ฌด ๋ฏธ๋ค„๋‘๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, ์™„๋ฒฝ์„ ์ถ”๊ตฌํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ์ผ๋‹จ ์‹ค์ฒœ์„ ํ•˜๋Š” ๊ฒƒ์— ์Šต๊ด€์„ ๋“ค์ด๋„๋ก ๋…ธ๋ ฅํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜ ๊ฐ„๋‹จํ•˜๊ฒŒ ์†Œ๊ฐœํ•  ๋‚ด์šฉ์€์š”. ์ œ๊ฐ€ ๋‚ ์งœ ํ˜•์‹์— ๊ด€๋ จํ•ด์„œ ์‚ฌ์šฉํ–ˆ๋˜ ์ฝ”๋“œ ์กฐ๊ฐ์ด๋ผ๊ณ  ํ•˜๋ฉด ๋ ๊นŒ์š”. ๋“ฃ๊ณ  ์žˆ๋Š” ์ˆ˜์—…์—์„œ๋„ ๋‚ ์งœ๋ฅผ ๋‹ค๋ค„๋ณผ ์ผ์ด ์žˆ์—ˆ๊ณ , ์ง„ํ–‰ ์ค‘์ธ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ๋„ ์ œ๊ฐ€ ์บ˜๋ฆฐ๋”๋ฅผ ๋งก๊ณ  ์žˆ์–ด์„œ ๋‚ ์งœ๋ฅผ ๋‹ค๋ฃฐ ์ผ์ด ๋งŽ์€๋ฐ์š”. ์ƒ๊ฐ๋ณด๋‹ค ๋‚ ์งœ ํ˜•์‹์„ ๊ด€๋ฆฌํ•˜๊ธฐ ๋„ˆ๋ฌด ๊ท€์ฐฎ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์—ด๊ฑฐํ˜•์„ ์ด์šฉํ•ด์„œ ์ข€ ๋” ๊น”๋”ํ•˜๊ฒŒ DateFormat์„ ๊ด€๋ฆฌํ•ด๋ณด๋„๋ก ํ•ด์š”.


์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋™์•ˆ ๋‚ ์งœ๋ฅผ ๋‹ค๋ฃจ๋ฉด์„œ ํ–ˆ๋˜ ํ–‰๋™์„ ๋Œ์ด์ผœ๋ณผ๊ฒŒ์š”. Date ํƒ€์ž…์„ String ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜, String ํƒ€์ž…์„ Date ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋”ฑ 2๊ฐ€์ง€์˜ ๋ชจ์Šต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งค๋ฒˆ ์šฐ๋ฆฌ๋Š” ์ฝ”๋“œ๋ฅผ ์–ด๋–ค ์‹์œผ๋กœ ์ž‘์„ฑํ–ˆ์„๊นŒ์š”?


๊ธฐ์กด ๋‚ ์งœ ๋ณ€ํ™˜ ๋ฐฉ์‹

1. Date์„ String์œผ๋กœ ๋ฐ”๊พธ๊ธฐ

์›ํ•˜๋Š” ํ˜•ํƒœ์˜ ํฌ๋งท ์–ด๋–ค ๊ฒƒ์œผ๋กœ๋“  ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "ko_KR")
dateFormatter.dateFormat = "yyyy-MM-dd"

let newDate = Date()
return dateFormatter.string(from: newDate)

2. String์„ Date๋กœ ๋ฐ”๊พธ๊ธฐ

String์˜ ํฌ๋งท๊ณผ dateFormatter์˜ dateFormat ํƒ€์ž…์˜ ํฌ๋งท์„ ๋งž์ถฐ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "ko_KR")
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"

let dateString = "2022-08-08 22:30"
return dateFormatter.date(from: dateString)


์œ„์˜ 1๋ฒˆ, 2๋ฒˆ์„ ์ ์ ˆํžˆ ์ž˜ ์„ž์œผ๋ฉด String ํ˜•ํƒœ์˜ Date๋ฅผ ์›ํ•˜๋Š” ํฌ๋งท์˜ String์œผ๋กœ ๋‹ค์‹œ ๋ฐ”๊ฟ”์ค„ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.



๊ทธ๋Ÿฐ๋ฐ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์œ„์˜ ์ž‘์—…์ด ์ƒ๋‹นํžˆ ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค. ๋‚ ์งœ ํ˜•์‹์„ ๋ฐ”๊พธ๋ ค๋ฉด ๋งค ์ˆœ๊ฐ„๋งˆ๋‹ค DateFormatter ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ (๋ฌผ๋ก  Class๋‚˜ Struct ๋‚ด์—์„œ ํ•œ ๋ฒˆ๋งŒ ๋งŒ๋“ค์–ด๋†“๊ณ  ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.) dateFormat์„ ์ง€์ •ํ•ด์ฃผ๊ณ  ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์ฃผ๊ณ  ์—ฌ๊ฐ„ ๋ฒˆ๊ฑฐ๋กœ์šด ์ผ์ด ์•„๋‹ ์ˆ˜ ์—†์ฃ . ์œ„์˜ ๋‹จ์  ์™ธ์—๋„ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ํ˜•ํƒœ์˜ ๋‚ ์งœ ํ˜•์‹์ด ์“ฐ์ด๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ๊ณณ๊ณณ์— ํฉ์–ด์ง„ ๋‚ ์งœ ํ˜•์‹์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ๋งˆ์น˜ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์ด ๊ณณ๊ณณ์— ํผ์ ธ์žˆ๋Š” ๋Š๋‚Œ๊ณผ๋„ ๋น„์Šทํ•˜์ฃ . ๊ทธ๋ž˜์„œ ์—ด๊ฑฐํ˜•์„ ์ด์šฉํ•ด์„œ ์ข€ ๋” ์‰ฝ๊ฒŒ ๋‚ ์งœ ํ˜•์‹์„ ๊ด€๋ฆฌํ•˜๊ณ , Date์™€ String์˜ Extension ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์‰ฝ๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.


์—ด๊ฑฐํ˜•๊ณผ Extension์„ ์ด์šฉํ•œ ์ฝ”๋“œ ๊ฐœ์„ 

1. DateFormatType ์—ด๊ฑฐํ˜• ์ƒ์„ฑ

enum DateFormatType {
    case full
    case year
    case utc
    case utcWithSlash
    
    var description: String {
        switch self {
        case .full:
            return "yyyy-MM-dd'T'HH:mm:ss.SSS'Z"
        case .year:
            return "yyyy-MM-dd"
        case .utc:
            return "MM-dd-yyyy"
        case .utcWithSlash:
            return "MM/dd/yyyy"
        }
    }
}

์ด description ํ”„๋กœํผํ‹ฐ์— ๋“ค์–ด์žˆ๋Š” String ๊ฐ’์ด ๊ฒฐ๊ตญ dateFormatter์˜ dateFormat ํ˜•์‹์œผ๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ ๋  ๊ฒƒ์ธ๋ฐ์š”. ์ด๋ ‡๊ฒŒ ์—ด๊ฑฐํ˜•์œผ๋กœ ํ•œ ๋ฒˆ์— ๊ด€๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ ์“ฐ์ด๋Š” dateFormat์— ์ข€ ๋” ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ?


2. Date+Extension

import UIKit

extension Date {
    
    func toString(of type: DateFormatType) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "ko_KR")
        dateFormatter.dateFormat = type.description
        return dateFormatter.string(from: self)
    }
}


3. String+Extension

import UIKit

extension String {
    
    func toDate(to type: DateFormatType) -> Date? {
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "ko_KR")
        dateFormatter.dateFormat = type.description
        return dateFormatter.date(from: self)
    }
}


์‹ค์ œ ์ฝ”๋“œ ์ ์šฉ

์™ผ์ชฝ์— ์žˆ๋Š” ๋‚ ์งœ ํ˜•์‹(yyyy-MM-dd)๋ฅผ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ฏธ๊ตญ์‹ ํ‘œ๊ธฐ(MM/dd/yyyy)๋กœ ๋ฐ”๊พธ๊ณ  ์‹ถ์€ ๊ฒƒ์ธ๋ฐ์š”. ๊ธฐ์กด ๋ฐฉ์‹์„ ์ด์šฉํ•ด์„œ๋„ ์ž˜ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ ์œ„์—์„œ ์†Œ๊ฐœํ•œ ์—ด๊ฑฐํ˜•๊ณผ Extension์„ ์ด์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// media.releaseDate๋Š” "2022-08-22" ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์„ ๋ฐ
dateLabel.text = media.releaseDate
// 08/22/2022์™€ ๊ฐ™์ด ๋‚ ์งœ ํ˜•์‹์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Œ
dateLabel.text = media.releaseDate.toDate(to: .year)?.toString(of: .utcWithSlash)


๊ธฐ์กด ๋‚ ์งœ ๋ณ€ํ™˜ ๋ฐฉ์‹์„ ์ด์šฉํ–ˆ๋‹ค๋ฉด ์ค‘๋ณต๋œ ์ฝ”๋“œ๋„ ๋งŽ์ด ์“ฐ๊ณ , ๋„ˆ๋ฌด ๋จธ๋ฆฌ ์•„ํŒ ์„ ๊ฒƒ ๊ฐ™์€๋ฐ ์ฝ”๋“œ๊ฐ€ ์ž˜ ๊ฐœ์„ ๋œ ๊ฒƒ ๊ฐ™๋‚˜์š”? ์šฐ๋ฆฌ๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” ๊ธฐ๋ณธ ๊ฐœ๋…๋“ค์„ ์ด์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ๊ฐœ์„ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ข‹์€ ์‹œ๊ฐ„์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.


๋งˆ์น˜๋ฉฐ

์ถ”๊ฐ€๋กœ ์ด๋ ‡๊ฒŒ ๋‚ ์งœ ํ˜•์‹์„ ๋‹ค์–‘ํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ฆฌ๋ฉฐ ๋งˆ์นฉ๋‹ˆ๋‹ค. (์กฐ๊ธˆ๋งŒ.. ์ค„์—ฌ์„œ.. ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉํ•˜์ž...)

enum FormatType {
    case full
    case year
    case day
    case month
    case second
    case time
    case calendar
    case calendarTime
    case calendarWithMonth
    case noticeDay
    
    var description: String {
        switch self {
        case .full:
            return "yyyy-MM-dd'T'HH:mm:ss.SSS'Z"
        case .year:
            return "yyyy-MM-dd"
        case .day:
            return "M์›” d์ผ EEEE"
        case .month:
            return "M์›”"
        case .second:
            return "HH:mm:ss"
        case .time:
            return "a h:mm"
        case .calendar:
            return "yyyy๋…„ MM์›” dd์ผ"
        case .calendarTime:
            return "a HH:mm"
        case .calendarWithMonth:
            return "yyyy๋…„ M์›”"
        case .noticeDay:
            return "yyyy.MM.dd"
        }
    }
}