it-swarm.com.de

Swift - Überprüfe, ob ein Zeitstempel vor gestern, heute, morgen oder vor X Tagen liegt

Ich versuche herauszufinden, wie man entscheiden kann, ob ein bestimmter Zeitstempel heute oder +1/-1 Tage auftritt. Im Grunde würde ich so etwas gerne machen (Pseudocode)

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'

Entscheidend ist jedoch, dass es sich in Swift befinden muss und ich kämpfe mit den NSDate/NSCalendar-Objekten. Ich begann damit, den Zeitunterschied so zu berechnen:

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

Der Vergleich auf diese Weise ist jedoch nicht einfach, da der .Day je nach Tageszeit und Zeitstempel unterschiedlich ist. In PHP würde ich einfach mktime verwenden, um ein neues Datum zu erstellen, basierend auf dem Start des Tages (d. H. mktime(0,0,0)), aber ich bin mir nicht sicher, wie dies in Swift am einfachsten ist.

Hat jemand eine gute Idee, wie er damit umgehen soll? Vielleicht wäre eine Erweiterung zu NSDate oder etwas Ähnlichem am besten?

33
Ben

Calendar hat Methoden für alle drei Fälle

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

Zur Berechnung der Tage früher als gestern verwenden

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

Übergeben Sie [.day] an components und rufen Sie die day-Eigenschaft aus dem Ergebnis ab.


Dies ist eine Funktion, die auch is in für frühere und spätere Daten berücksichtigt, indem der Zeitteil (Swift 3+) entfernt wird.

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" }
    }
}

Alternativ können Sie DateFormatter für Yesterday , Today und Tomorrow verwenden, um lokalisierte Zeichenfolgen kostenlos zu erhalten

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"
    }
}
73
vadian

Swift 3/4:

Calendar.current.isDateInToday(yourDate)
Calendar.current.isDateInYesterday(yourDate)
Calendar.current.isDateInTomorrow(yourDate)

Zusätzlich:

Calendar.current.isDateInWeekend(yourDate)

Beachten Sie, dass das Wochenende in manchen Ländern von Samstag bis Sonntag abweicht. Dies hängt vom Kalender ab.

Sie können auch autoupdatingCurrent anstelle von current calendar verwenden, um Benutzeraktualisierungen zu verfolgen. Sie verwenden es genauso:

Calendar.autoupdatingCurrent.isDateInToday(yourDate)

Calendar ist ein Typalias für die NSCalendar.

70
KlimczakM

Swift 4 Update:

    let calendar = Calendar.current
    let date = Date()

    calendar.isDateInYesterday(date)
    calendar.isDateInToday(date)
    calendar.isDateInTomorrow(date)
13
Edward

NSCalendar verfügt über neue Methoden, die Sie direkt verwenden können.

NSCalendar.currentCalendar().isDateInTomorrow(NSDate())//Replace NSDate() with your date
NSCalendar.currentCalendar().isDateInYesterday()
NSCalendar.currentCalendar().isDateInTomorrow()

Hoffe das hilft

6
nishith Singh

1) Gemäß Ihrem Beispiel möchten Sie die Labels "Gestern", "Heute" usw. erhalten. IOS kann dies standardmäßig tun:

https://developer.Apple.com/documentation/foundation/nsdateformatter/1415848-foesrelativedateformatierung?language=objc

2) Wenn Sie Ihre benutzerdefinierte Beschriftung berechnen möchten, wenn iOS diese Beschriftungen nicht selbst hinzufügt, können Sie alternativ 2 DateFormatter-Objekte mit sowohl doesRelativeDateFormatting == true als auch doesRelativeDateFormatting == false verwenden und vergleichen, ob ihre Ergebnisdatum-Zeichenfolgen gleich oder verschieden sind