我在 Swift 2.3 中这样做的方式是:
let currentDate = NSDate()
let currentCalendar = NSCalendar.currentCalendar()
var startDate : NSDate?
var endDate : NSDate?
// The following two lines set the `startDate` and `endDate` to the start of the day
currentCalendar.rangeOfUnit(.Day, startDate: &startDate, interval: nil, forDate: currentDate)
currentCalendar.rangeOfUnit(.Day, startDate: &endDate, interval: nil, forDate: self)
let intervalComps = currentCalendar.components([.Day], fromDate: startDate!, toDate: endDate!, options: [])
print(intervalComps.day)
现在这一切都随着 Swift 3 的改变而改变了。我必须通过不断地使用
NSCalendar
进行类型转换来使用 NSDate
和 as
,或者找到 Swift 3 的方法来做到这一点。
在 Swift 3 中正确的做法是什么?
在 Swift 5 中,有一个简单的单行代码可以获取两个日期之间的天数(或任何其他 DateComponent):
let diffInDays = Calendar.current.dateComponents([.day], from: dateA, to: dateB).day
注意:正如评论中所指出的,该解决方案测量 24 小时周期,因此需要在
dateA
和 dateB
之间至少有 24 小时。
事实证明,在 Swift 3 中这要简单得多:
extension Date {
func interval(ofComponent comp: Calendar.Component, fromDate date: Date) -> Int {
let currentCalendar = Calendar.current
guard let start = currentCalendar.ordinality(of: comp, in: .era, for: date) else { return 0 }
guard let end = currentCalendar.ordinality(of: comp, in: .era, for: self) else { return 0 }
return end - start
}
}
编辑
比较两个日期的序数应该在相同的
era
内,而不是相同的year
,因为两个日期自然可能属于不同的年份。
用法
let yesterday = Date(timeInterval: -86400, since: Date())
let tomorrow = Date(timeInterval: 86400, since: Date())
let diff = tomorrow.interval(ofComponent: .day, fromDate: yesterday)
// return 2
Swift 4 版本
let startDate = "2000-11-22"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let formatedStartDate = dateFormatter.date(from: startDate)
let currentDate = Date()
let components = Set<Calendar.Component>([.second, .minute, .hour, .day, .month, .year])
let differenceOfDate = Calendar.current.dateComponents(components, from: formatedStartDate!, to: currentDate)
print (differenceOfDate)
印刷- 年:16 月:10 天:19 小时:12 分钟:16 秒:42 isLeapMonth:false
private func calculateDaysBetweenTwoDates(start: Date, end: Date) -> Int {
let currentCalendar = Calendar.current
guard let start = currentCalendar.ordinality(of: .day, in: .era, for: start) else {
return 0
}
guard let end = currentCalendar.ordinality(of: .day, in: .era, for: end) else {
return 0
}
return end - start
}
在 Swift4 中,我们可以使用以下代码轻松获取两个不同日历日期之间的天数。
第一个是与当前日期的天数差异。
let previousDate = "2017-03-01"
let currentDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let previousDateFormated : Date? = dateFormatter.date(from: previousDate)
let difference = currentDate.timeIntervalSince(previousDateFormated!)
var differenceInDays = Int(difference/(60 * 60 * 24 ))
print(differenceInDays)
继续上面的代码...下面是查找两个不同日期的天数。前一个日期的内容取自上面的日期
let futureDate = "2017-12-30"
let futureDateFormatted : Date? = dateFormatter.date(from: futureDate)
differenceInDays = (futureDateFormatted?.timeIntervalSince(previousDateFormated!))! / (60 * 60 * 24)
print(differenceInDays)
如果有人需要显示所有时间单位,例如“小时分钟秒”而不仅仅是“小时”。假设两个日期之间的时差为 1 小时 59 分 20 秒。此功能将显示“1h 59m 20s”。
这是我的代码:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'hh:mm:ss"
let start = dateFormatter.date(from: "2019-01-31T07:45:00")!
let end = dateFormatter.date(from: "2019-03-01T06:30:00")!
print("Date Difference : ", end.offsetFrom(date: start))
函数定义:
extension Date {
func offsetFrom(date : Date) -> String {
let dayHourMinuteSecond: Set = [.day, .hour, .minute, .second]
let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self);
let seconds = "\(difference.second ?? 0)s"
let minutes = "\(difference.minute ?? 0)m" + " " + seconds
let hours = "\(difference.hour ?? 0)h" + " " + minutes
let days = "\(difference.day ?? 0)d" + " " + hours
if let day = difference.day, day > 0 { return days }
if let hour = difference.hour, hour > 0 { return hours }
if let minute = difference.minute, minute > 0 { return minutes }
if let second = difference.second, second > 0 { return seconds }
return ""
}
}
在不同的线程上找到了这个,但它最终是我使用 Swift 4 最简单的解决方案:
let previousDate = ENTER DATE HERE
let now = Date()
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .brief // or other options
formatter.allowedUnits = [.month, .day, .hour]
formatter.maximumUnitCount = 1 // Show one unit, eg 1d vs. 1d 6hrs)
let stringDate = formatter.string(from: previousDate, to: now)
这将为您提供一个结果,例如
2m
(两个月前)或 7h
()七小时前)。请注意,您可以简单地改为
formatter.allowedUnits = [.day]
这将给它几天的时间,例如
71d
或0d
。
import Foundation
extension DateComponents {
func dateComponentsToTimeString() -> String {
var hour = "\(self.hour!)"
var minute = "\(self.minute!)"
var second = "\(self.second!)"
if self.hour! < 10 { hour = "0" + hour }
if self.minute! < 10 { minute = "0" + minute }
if self.second! < 10 { second = "0" + second }
let str = "\(hour):\(minute):\(second)"
return str
}
}
extension Date {
func offset(from date: Date)-> DateComponents {
let components = Set<Calendar.Component>([.second, .minute, .hour, .day, .month, .year])
let differenceOfDate = Calendar.current.dateComponents(components, from: date, to: self)
return differenceOfDate
}
}
用途:
var durationString: String {
return self.endTime.offset(from: self.startTime).dateComponentsToTimeString()
}
更新为 Swift 3:
如果要打印两个日历日期之间的天数以及天数列表,请使用下面的简单代码;
//变量声明:
var daysListArray = [String]()
//函数定义:
func printCountBtnTwoDates(mStartDate: Date, mEndDate: Date) -> Int {
let calendar = Calendar.current
let formatter = DateFormatter()
var newDate = mStartDate
daysListArray.removeAll()
while newDate <= mEndDate {
formatter.dateFormat = "yyyy-MM-dd"
daysListArray.append(formatter.string(from: newDate))
newDate = calendar.date(byAdding: .day, value: 1, to: newDate)!
}
// print("daysListArray: \(daysListArray)") // if you want to print list between start date and end date
return daysListArray.count
}
// 调用上面的函数:
let count = self.printCountBtnTwoDates(mStartDate: your_start_date, mEndDate: your_end_date)
print("count: \(count)") // date count
// 享受编码的乐趣...!
private func days(actual day1:[Int],expect day2:[Int]) -> Int {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let first = "\(day1[2])-\(day1[1])-\(day1[0])"
let firstDate = dateFormatter.date(from:first)!
let last = "\(day2[2])-\(day2[1])-\(day2[0])"
let lastDate = dateFormatter.date(from:last)!
let currentCalendar = NSCalendar.current
let components = currentCalendar.dateComponents([.day], from: firstDate, to: lastDate)
return components.day!
}
与日月年的组成部分进行比较的另一种方法
用途:
按照以下格式输入日期
[dd, mm, yyyy]
[9, 6, 2017]
[6, 6, 2017]