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)
Calendar
是 NSCalendar
.
的类型别名
Swift 4 次更新:
let calendar = Calendar.current
let date = Date()
calendar.isDateInYesterday(date)
calendar.isDateInToday(date)
calendar.isDateInTomorrow(date)
1)根据您的示例,您希望接收标签 "Yesterday"、"Today" 等。iOS 可以默认执行此操作:
2) 如果您想在 iOS 不自行添加这些标签时计算您的自定义标签,那么您也可以使用 2 个 DateFormatter
对象同时使用 doesRelativeDateFormatting == true
和 doesRelativeDateFormatting == false
并比较它们的结果日期字符串是否相同
在 Swift 5 和 iOS 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"
我正在尝试弄清楚如何确定给定时间戳是在今天还是 +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)
Calendar
是 NSCalendar
.
Swift 4 次更新:
let calendar = Calendar.current
let date = Date()
calendar.isDateInYesterday(date)
calendar.isDateInToday(date)
calendar.isDateInTomorrow(date)
1)根据您的示例,您希望接收标签 "Yesterday"、"Today" 等。iOS 可以默认执行此操作:
2) 如果您想在 iOS 不自行添加这些标签时计算您的自定义标签,那么您也可以使用 2 个 DateFormatter
对象同时使用 doesRelativeDateFormatting == true
和 doesRelativeDateFormatting == false
并比较它们的结果日期字符串是否相同
在 Swift 5 和 iOS 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"