Swift 3 - 查找两个日期之间的日历天数

Vin*_*ath 44 nsdate nscalendar swift3

我在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)
Run Code Online (Sandbox Code Playgroud)

现在这已经全部改变了Swift 3.我必须使用NSCalendarNSDate不断地输入as,或者找到Swift 3的方式.

在Swift 3中使用它的正确方法是什么?

flo*_*_23 81

Swift 4中有一个简单的单行程序来获取两个日期之间的天数(或任何其他DateComponent):

let diffInDays = Calendar.current.dateComponents([.day], from: dateA, to: dateB).day
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说不起作用,因为它需要24小时. (10认同)
  • @Kqtr 将“dateA”和“dateB”替换为 `calendar.startOfDay(for: dateA)` 和 `calendar.startOfDay(for: dateB)` (6认同)
  • 警告:这给出两个日期之间的24小时周期数,四舍五入。最初的问题是询问日历天的差异,解决方案在Vinod的回答中。 (2认同)

Vin*_*ath 46

事实证明,这在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
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

比较两个日期的标准应该在相同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
Run Code Online (Sandbox Code Playgroud)

  • 小心:这似乎不适用于某些时区,例如 UTC+05:30。我怀疑这会告诉您这两个日期是否在自时代开始以来的同一 24 小时内,并且时代的开始是特定时区(UTC?)的午夜。所以它基本上不考虑日历的时区。我最终创建了一个愚蠢的自定义实用程序方法,该方法比较两个日期的“yyyy-MM-dd”并添加/删除一天,直到找到相同的字符串。 (2认同)
  • 我发现要解决时区问题(在计算出的时区中,时区中的两个日期时间“今天”在“不同的天”中),当我使用calendar.startOfDay将两个输入日期都转换为午夜时,我会得到更好的结果。我在上面加上了以下内容://当天的午夜...让midnight1 = DateTimeHelper.midnight(date:date1)让midnight2 = DateTimeHelper.midnight(date:date2) (2认同)

Ste*_*e B 19

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)
Run Code Online (Sandbox Code Playgroud)

印刷年份:16个月:10天:19小时:12分钟:16秒:42是LeapMonth:false


小智 13

如果有人想要更具体地按照以下步骤操作

1.添加此日期延期

extension Date {
    /// Returns the amount of years from another date
func years(from date: Date) -> Int {
    return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
/// Returns the amount of months from another date
func months(from date: Date) -> Int {
    return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(from date: Date) -> Int {
    return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
}
/// Returns the amount of days from another date
func days(from date: Date) -> Int {
    return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
/// Returns the amount of hours from another date
func hours(from date: Date) -> Int {
    return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(from date: Date) -> Int {
    return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(from date: Date) -> Int {
    return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
/// Returns the amount of nanoseconds from another date
func nanoseconds(from date: Date) -> Int {
    return Calendar.current.dateComponents([.nanosecond], from: date, to: self).nanosecond ?? 0
}
/// Returns the a custom time interval description from another date
func offset(from date: Date) -> String {
    var result: String = ""
            if years(from: date)   > 0 { return "\(years(from: date))y"   }
            if months(from: date)  > 0 { return "\(months(from: date))M"  }
            if weeks(from: date)   > 0 { return "\(weeks(from: date))w"   }
    if seconds(from: date) > 0 { return "\(seconds(from: date))" }
            if days(from: date)    > 0 { result = result + " " + "\(days(from: date)) D" }
            if hours(from: date)   > 0 { result = result + " " + "\(hours(from: date)) H" }
            if minutes(from: date) > 0 { result = result + " " + "\(minutes(from: date)) M" }
           if seconds(from: date) > 0 { return "\(seconds(from: date))" }
    return ""
 }
}
Run Code Online (Sandbox Code Playgroud)

2.在全球范围内定义它

 fileprivate var timer: Timer?
Run Code Online (Sandbox Code Playgroud)

3.在viewDidLoad或任何你想要的地方打电话给这个方法

override func viewDidLoad() {
    super.viewDidLoad()
    self.getRemainingTime()
} 
Run Code Online (Sandbox Code Playgroud)

4.Usage

fileprivate func getRemainingTime() {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

    let startDate = "2018-06-02 10:11:12"
    let currentDate = dateFormatter.string(from: Date())

    if currentDate != startDate {
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(calculateTime)), userInfo: nil, repeats: true)
        RunLoop.current.add(timer!, forMode: RunLoopMode.commonModes)
        timer?.fire()
    }
    else {
        self.timer?.invalidate()
        self.timer = nil
    }
}

func calculateTime() {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

    let stdate : String = "2018-06-02 10:11:12"
    let startDate = dateFormatter.date(from: stdate)!

    let currentDate = Date()

    let strTimer : String = startDate.offset(from: currentDate)
    if !strTimer.isEmpty {
        let stDay: String = "\((Int(strTimer)! % 31536000) / 86400)"
        let stHour: String = "\((Int(strTimer)! % 86400) / 3600)"
        let stMin: String = "\((Int(strTimer)! % 3600) / 60)"
        let stSec: String = "\(Int(strTimer)! % 60)"
        yourLabelOutlet.text = "Start In :\(stDay) Days \(stHour) Hours \(stMin) Minutes \(stSec) Seconds"
    }

}
Run Code Online (Sandbox Code Playgroud)

像Charm一样工作你可以使用每个单独的字符串到你的UI侧,享受


Kev*_*vin 8

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
}
Run Code Online (Sandbox Code Playgroud)


Ash*_*hal 7

在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)
Run Code Online (Sandbox Code Playgroud)

继续上面的代码......下面是两个不同日期的天数.上一日期的内容取自上述日期

let futureDate = "2017-12-30"
let futureDateFormatted : Date? = dateFormatter.date(from: futureDate)
differenceInDays = (futureDateFormatted?.timeIntervalSince(previousDateFormated!))! / (60 * 60 * 24)

print(differenceInDays)
Run Code Online (Sandbox Code Playgroud)