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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39345101/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 10:04:18  来源:igfitidea点击:

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

iosswiftnsdatenscalendar

提问by Ben

I'm trying to work out how to decide if a given timestamp occurs today, or +1 / -1 days. Essentially, I'd like to do something like this (Pseudocode)

我正在尝试确定如何确定给定的时间戳是在今天还是 +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'

Crucially though, it needs to be in Swift and I'm struggling with the NSDate / NSCalendar objects. I started with working out the time difference like this:

但至关重要的是,它需要在 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())

However comparing in this way isn't easy, because the .Dayis different depending on the time of day and the timestamp. In PHP I'd just use mktime to create a new date, based on the start of the day (i.e. mktime(0,0,0)), but I'm not sure of the easiest way to do that in Swift.

然而,以这种方式进行比较并不容易,因为.Day根据一天中的时间和时间戳而有所不同。在 PHP 中,我只是使用 mktime 根据一天的开始(即mktime(0,0,0))创建一个新日期,但我不确定在 Swift 中最简单的方法。

Does anybody have a good idea on how to approach this? Perhaps an extension to NSDate or something similar would be best?

有没有人对如何解决这个问题有一个好主意?也许扩展到 NSDate 或类似的东西会是最好的?

回答by KlimczakM

Swift 3/4/5:

斯威夫特 3/4/5:

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

Additionally:

此外:

Calendar.current.isDateInWeekend(yourDate)

Note that for some countries weekend may be different than Saturday-Sunday, it depends on the calendar.

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

You can also use autoupdatingCurrentinstead of currentcalendar, which will track user updates. You use it the same way:

您还可以使用autoupdatingCurrent代替current日历,它将跟踪用户更新。您以相同的方式使用它:

Calendar.autoupdatingCurrent.isDateInToday(yourDate)

Calendaris a type alias for the NSCalendar.

Calendar是 的类型别名NSCalendar

回答by vadian

Calendarhas methods for all three cases

Calendar有所有三种情况的方法

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

To calculate the days earlier than yesterday use

要计算比昨天早的天数,请使用

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

pass [.day]to componentsand get the dayproperty from the result.

传递[.day]componentsday从结果中获取属性。



This is a function which considers also is infor earlier and later dates by stripping the time part (Swift 3+).

这是一个函数,它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" }
    }
}

Alternatively you could use DateFormatterfor Yesterday, Todayand Tomorrowto get localized strings for free

另外,您可以使用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"
    }
}

Update:

更新:

In macOS 10.15 / iOS 13 RelativeDateTimeFormatterwas introduced to return (localized) strings relative to a specific date.

在 macOS 10.15 / iOS 13RelativeDateTimeFormatter中引入了返回(本地化)相对于特定日期的字符串。

回答by Edward

Swift 4 update:

斯威夫特 4 更新:

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

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

回答by nishith Singh

NSCalender has new methods that you can use directly.

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

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

Hope this helps

希望这可以帮助

回答by rustylepord

On Swift 5and iOS 13use the RelativeDateTimeFormatter,

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"

回答by Vyachaslav Gerchicov

1)According to your example you want to receive labels "Yesterday", "Today" and etc. iOS can do this by default:

1)根据您的示例,您希望收到标签“昨天”、“今天”等。iOS 可以默认执行此操作:

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

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

2)If you want to compute your custom label when iOS don't add these labels by itself then alternatively you can use 2 DateFormatterobjects with both doesRelativeDateFormatting == trueand doesRelativeDateFormatting == falseand compare if their result date strings are the same or different

2)如果要计算您的自定义标签时的iOS不要自行添加这些标签,那么你也可以用2个DateFormatter对象既doesRelativeDateFormatting == truedoesRelativeDateFormatting == false和比较,如果其结果的日期字符串是相同的或不同