1. ホーム
  2. ios

[解決済み] Swift - タイムスタンプが昨日、今日、明日、X日前であるかどうかをチェックする

2023-03-31 11:03:19

質問

与えられたタイムスタンプが今日発生したか、それとも +1 / -1 日発生したかを決定する方法を見つけ出そうとしています。基本的に、私は次のようなことをしたいと思います(疑似コード)。

IF days_from_today(timestamp) == -1 RETURN 'Yesterday'
ELSE IF days_from_today(timestamp) == 0 RETURN 'Today'
ELSE IF days_from_today(timestamp) == 1 RETURN 'Tomorrow'
ELSE IF days_from_today(timestamp) < 1 RETURN days_from_today(timestamp) + ' days ago'
ELSE RETURN 'In ' + days_from_today(timestamp) + ' ago'

しかし、重要なのは、それがSwiftである必要があり、私はNSDate / NSCalendarオブジェクトと格闘していることです。まずはこんな感じで時差を計算するところから始めました。

let calendar = NSCalendar.currentCalendar()
let date = NSDate(timeIntervalSince1970: Double(timestamp))
let timeDifference = calendar.components([.Second,.Minute,.Day,.Hour],
    fromDate: date, toDate: NSDate(), options: NSCalendarOptions())

しかし、この方法で比較するのは簡単ではありません。 .Day は時間帯とタイムスタンプによって異なるからです。PHP では、mktime を使って、一日の始まりに基づいた新しい日付を作成するだけです (つまり mktime(0,0,0) ) ですが、Swiftでそれを行う最も簡単な方法はわかりません。

誰か、これにアプローチする方法について良いアイデアを持っていますか?おそらく、NSDate または同様の何かの拡張が最善でしょうか?

どのように解決するのですか?

Calendar には、3つのケースに対応するメソッドがあります。

func isDateInYesterday(_ date: Date) -> Bool
func isDateInToday(_ date: Date) -> Bool
func isDateInTomorrow(_ date: Date) -> Bool

昨日より前の日数を計算する場合は

func dateComponents(_ components: Set<Calendar.Component>, 
                      from start: Date, 
                          to end: Date) -> DateComponents

パス [.day]components を取得し day プロパティを取得します。


も考慮した関数です。 is in を考慮する機能です(Swift 3以上)。

func dayDifference(from interval : TimeInterval) -> String
{
    let calendar = Calendar.current
    let date = Date(timeIntervalSince1970: interval)
    if calendar.isDateInYesterday(date) { return "Yesterday" }
    else if calendar.isDateInToday(date) { return "Today" }
    else if calendar.isDateInTomorrow(date) { return "Tomorrow" }
    else {
        let startOfNow = calendar.startOfDay(for: Date())
        let startOfTimeStamp = calendar.startOfDay(for: date)
        let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp)
        let day = components.day!
        if day < 1 { return "\(-day) days ago" }
        else { return "In \(day) days" }
    }
}

別の方法として DateFormatter を使うこともできます。 昨日 , 今日 明日 をクリックすると、ローカライズされた文字列を無料で取得できます。

func dayDifference(from interval : TimeInterval) -> String
{
    let calendar = Calendar.current
    let date = Date(timeIntervalSince1970: interval)
    let startOfNow = calendar.startOfDay(for: Date())
    let startOfTimeStamp = calendar.startOfDay(for: date)
    let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp)
    let day = components.day!
    if abs(day) < 2 {
        let formatter = DateFormatter()
        formatter.dateStyle = .short
        formatter.timeStyle = .none
        formatter.doesRelativeDateFormatting = true
        return formatter.string(from: date)
    } else if day > 1 {
        return "In \(day) days"
    } else {
        return "\(-day) days ago"
    }
}

更新します。

macOS 10.15 / iOS 13 では RelativeDateTimeFormatter は、特定の日付からの相対的な(ローカライズされた)文字列を返すために導入されました。