[Swift] DateComponentsFormatter 또는 RelativeDateTimeFormatter를 사용하여 날짜 차이를 표시합니다.

14353 단어 iOS13dateSwiftSwiftUI

소개



요 전날 [Swift] 날짜를 얻고 차이를 내는 방법 라고 하는 기사를 썼지만, 아니아니 좀더 표준 라이브러리를 사용해 간단하게 취득할 수 있어! 라는 것을 알았으므로 시험해 보았습니다.

환경



· iOS 13 이상

DateComponentsFormatter



A formatter that creates string representations of quantities of time.
→ 시간의 양의 캐릭터 라인 표현을 작성하는 Formatter입니다. (공식에서 번역)
시간의 표현을 작성한다면 평상시 사용하는 Formatter와 같은 것은? 라고 하는 느낌이 듭니다만, 어쨌든 사용해 본다.
 let time: TimeInterval = 300
            let formatter = DateComponentsFormatter()
            formatter.unitsStyle = .full
            formatter.includesApproximationPhrase = true
            formatter.includesTimeRemainingPhrase = true
            formatter.allowedUnits = [.minute]
            let outputString = formatter.string(from: time)!
            print(outputString)



오! 약이라고 하는 것이 신경이 쓰이지만 아무래도 time에 있는 초수로부터 나머지를 산출해 주는 모습.
이어서 time=330으로 하여 다음의 재작성해 본다.
formatter.allowedUnits = [.minute]


분과 초가 단단히 잡혀 있는지 확인할 수 있습니다.
또한 includesApproximationPhrase는 결과 단어가 부정확 한 시간 값을 반영하는지 여부를 나타내는 Bool 값이므로
formatter.includesApproximationPhrase를 false로 설정하면

됩니다. (선택 사항)
includesTimeRemainingPhrase는 출력 문자열이 남은 시간을 반영하는지 여부를 나타내는 Bool 값이므로 false로하면 "남은"이라는 문자가 사라집니다.
 let time: TimeInterval = 30000000
            let formatter = DateComponentsFormatter()
            formatter.unitsStyle = .full
            formatter.includesApproximationPhrase = false
            formatter.includesTimeRemainingPhrase = false
            formatter.allowedUnits = [.day, .hour, .minute, .second]
            let outputString = formatter.string(from: time)!
            print(outputString)



allowedUnits에 추가해 나가는 것으로 각각의 일시를 취득할 수가 있습니다. 또한 0이면 표시되지 않습니다. (이번에는 초가 0초로 표시되지 않음)

RelativeDateTimeFormatter



A formatter that creates locale-aware string representations of a relative date or time.
→ 상대 일자 또는 시각의 로케일 대응 캐릭터 라인 표현을 작성하는 Formatter입니다. (공식에서 번역)
또한 iOS13에서 사용할 수 있습니다.

localizedString(for: Date, relativeTo: Date) -> String
를 사용하는 것으로 포맷터의 캘린더를 사용해, 참조일로부터 지정된 일자까지의 일자 간격을 포맷 해 줍니다.
struct RelativeDateTimeFormatterTraining: View {
    @State var timeText = ""
    var body: some View {
        VStack{
            Button(action: {
                let targetDate = Date(timeIntervalSinceNow: 300)
                let nowDate = Date(timeIntervalSinceNow: 0)
                let formatter = RelativeDateTimeFormatter()
                formatter.unitsStyle = .abbreviated
                formatter.locale = Locale(identifier: "ja-JP")
                timeText = formatter.localizedString(for: targetDate, relativeTo: nowDate)
            }, label: {
                Text("Button")
            })
            Text(timeText)
        }
    }
}



formatter.localizedString(for: targetDate, relativeTo: nowDate)
for의 부분에서는 포맷 하는 ​​간격의 종료일을, relativeTo에는 포맷 하는 ​​간격의 개시일을 넣는 것으로 300초분의 차분을 계산해 자동으로 5분 후로 산출해 String형으로 돌려줍니다 .
그 외에도
func localizedString(from: DateComponents) -> String
지정된 일자 컴퍼넌트로 나타내지는 상대 시간을 포맷 합니다.
func localizedString(fromTimeInterval: TimeInterval) -> String
포맷터 캘린더를 사용하여 지정된 시간 간격을 포맷합니다.
func string(for: Any?) -> String?
현재 날짜와 시간에 상대적인 날짜의 형식화된 문자열을 만듭니다.
있습니다.

timeIntervalSince와 localizedString(fromTimeInterval: TimeInterval) -> String을 사용하는 것으로 Twitter와 같은”~분전”과 같은 구현을 용이하게 실시할 수 있습니다. ※ RelativeDateTimeFormatter는 문법적으로 올바르지 않을 수 있습니다. 와 공식으로 한 문장이 있듯이, 가장 큰 단위 이하의 단위는 기본 자르기 때문에 꽤 정보 떨어지는 경우도 나옵니다.
예를 들면
 VStack{
            Button(action: {
                let dateFormat = DateFormatter()
                // 日時をString型で定義
                let textLogDate = "2021-01-01 12:00:00"
                let textNowDate = "2021-01-01 12:05:40"
                // dateFormatを初期設定した"2021-01-01 12:00:00"と同じ形式になるように定義
                dateFormat.dateFormat = "yyyy-MM-dd HH:mm:ss"
                // timeZoneを日本に
                dateFormat.timeZone = TimeZone(identifier: "Asia/Tokyo")
                // String型の日時をDate型に変換
                let logDate = dateFormat.date(from: textLogDate) ?? Date()
                let nowDate = dateFormat.date(from: textNowDate) ?? Date()
                // timeIntervalSinceを使用すると差分を取得できる->nowDate-logDate
                let dateSubtraction: TimeInterval = logDate.timeIntervalSince(nowDate)
                let formatter = RelativeDateTimeFormatter()
                formatter.unitsStyle = .abbreviated
                formatter.locale = Locale(identifier: "ja-JP")
                timeText = formatter.localizedString(fromTimeInterval: dateSubtraction)
                print(timeText)
            }, label: {
                Text("Button")
            })
            Text(timeText)
        }


그렇다면 결과는

됩니다. 정확하게는 5분 40초 전입니다만, 이번 경우는 제일 큰 단위는 분이 되기 때문에 초는 잘립니다.

요약



어쨌든 Twitter에있는 것 같은 "~ 분 전"같은 구현을 할 때 RelativeDateTimeFormatter는 정말 편리하지만 정확하게 취득하고 싶은 경우는 DateComponentsFormatter를 사용하는 것이 좋을 것 같았습니다. 그러나 표준 라이브러리로 여기까지 간단하게 차분을 취해, String형으로 돌려주는 것은 정말 편리하므로 앞으로는 활용해 가고 싶습니다!

좋은 웹페이지 즐겨찾기