Swift - 检查时间戳是昨天、今天、明天还是 X 天前

Swift - check if a timestamp is yesterday, today, tomorrow, or X days ago

我正在尝试弄清楚如何确定给定时间戳是在今天还是 +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 的扩展或类似的东西是最好的?

NSCalender 有可以直接使用的新方法。

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

希望对您有所帮助

Calendar 有针对所有三种情况的方法

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 属性。


这是一个函数,它通过去除时间部分 (Swift 3+) 来考虑 is in 更早和更晚的日期。

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 中引入了相对于特定日期的 return(本地化)字符串。

Swift 3/4/5:

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

此外:

Calendar.current.isDateInWeekend(yourDate)

请注意,对于某些国家/地区,周末可能不同于周六至周日,这取决于日历。

您也可以使用 autoupdatingCurrent 而不是 current 日历,它将跟踪用户更新。你用同样的方法:

Calendar.autoupdatingCurrent.isDateInToday(yourDate)

CalendarNSCalendar.

的类型别名

Swift 4 次更新:

let calendar = Calendar.current
let date = Date()
        
calendar.isDateInYesterday(date)
calendar.isDateInToday(date)
calendar.isDateInTomorrow(date)

1)根据您的示例,您希望接收标签 "Yesterday"、"Today" 等。iOS 可以默认执行此操作:

https://developer.apple.com/documentation/foundation/nsdateformatter/1415848-doesrelativedateformatting?language=objc

2) 如果您想在 iOS 不自行添加这些标签时计算您的自定义标签,那么您也可以使用 2 个 DateFormatter 对象同时使用 doesRelativeDateFormatting == truedoesRelativeDateFormatting == false 并比较它们的结果日期字符串是否相同

Swift 5iOS 13 使用 RelativeDateTimeFormatter,

let formatter = RelativeDateTimeFormatter()
formatter.dateTimeStyle = .named 

formatter.localizedString(from: DateComponents(day: -1)) // "yesterday"
formatter.localizedString(from: DateComponents(day: 1)) // "Tomorrow"
formatter.localizedString(from: DateComponents(hour: 2)) // "in 2 hours"
formatter.localizedString(from: DateComponents(minute: 45)) // "in 45 minutes"