LoginSignup
1
3

More than 1 year has passed since last update.

【Swift】「〇日前」の表示を作成する

Posted at

はじめに

SNSなどでよくみる「〇日前」のような表示をSwiftで作成してみようと思います。

実装

extension Date {
    static let dateFormatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .short
        dateFormatter.timeStyle = .none
        dateFormatter.locale = Locale(identifier: "ja_JP")
        return dateFormatter
    }()

    var elapsedTimeText: String {
        let components = Calendar.current.dateComponents([.year, .month, .weekOfYear, .day, .hour, .minute, .second], from: self, to: Date())

        if let year = components.year, year > 0 {
            return Date.dateFormatter.string(from: self)
        } else if let month = components.month, month > 0 {
            return "\(month)ヶ月前"
        } else if let week = components.weekOfYear, week > 0 {
            return "\(week)週間前"
        } 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 "たった今"
        }
    }
}

テストコード

    func testElapsedTimeText() {
        let now = Date()

        // 1年以上前の場合
        let oneYearAgo = Calendar.current.date(byAdding: .year, value: -1, to: now)!
        XCTAssertEqual(oneYearAgo.elapsedTimeText, Date.dateFormatter.string(from: oneYearAgo))

        // 11ヶ月前の場合
        let elevenMonthsAgo = Calendar.current.date(byAdding: .month, value: -11, to: now)!
        XCTAssertEqual(elevenMonthsAgo.elapsedTimeText, "11ヶ月前")

        // 1ヶ月前の場合
        let oneMonthAgo = Calendar.current.date(byAdding: .month, value: -1, to: now)!
        XCTAssertEqual(oneMonthAgo.elapsedTimeText, "1ヶ月前")

        // 2週間前の場合
        let twoWeeksAgo = Calendar.current.date(byAdding: .day, value: -14, to: now)!
        XCTAssertEqual(twoWeeksAgo.elapsedTimeText, "2週間前")

        // 1日前の場合
        let oneDayAgo = Calendar.current.date(byAdding: .day, value: -1, to: now)!
        XCTAssertEqual(oneDayAgo.elapsedTimeText, "1日前")

        // 2時間前の場合
        let twoHoursAgo = Calendar.current.date(byAdding: .hour, value: -2, to: now)!
        XCTAssertEqual(twoHoursAgo.elapsedTimeText, "2時間前")

        // 30分前の場合
        let thirtyMinutesAgo = Calendar.current.date(byAdding: .minute, value: -30, to: now)!
        XCTAssertEqual(thirtyMinutesAgo.elapsedTimeText, "30分前")

        // 10秒前の場合
        let tenSecondsAgo = Calendar.current.date(byAdding: .second, value: -10, to: now)!
        XCTAssertEqual(tenSecondsAgo.elapsedTimeText, "10秒前")

        // たった今の場合
        XCTAssertEqual(now.elapsedTimeText, "たった今")
    }

おわり

Dateの扱いは難しいです。
もっとこうしたほうがいいとかありましたらコメントください。。

参考記事

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3