Быстрые дни между двумя НСДАП



Мне интересно, есть ли какая-то новая и потрясающая возможность получить количество дней между двумя NSDates в Swift / The "new" Cocoa?



например, как в Ruby я бы сделал:



(end_date - start_date).to_i
583   22  

22 ответов:

принятый ответ не вернет правильный номер дня между двумя датами. Вы также должны учитывать разницу во времени. Например, если вы сравниваете даты 2015-01-01 10:00 и 2015-01-02 09:00, дни между этими датами вернутся как 0 (ноль), так как разница между этими датами составляет менее 24 часов (это 23 часа).

если ваша цель-получить точное число дней между двумя датами, вы можете обойти эту проблему следующим образом:

// Assuming that firstDate and secondDate are defined
// ...

let calendar = NSCalendar.currentCalendar()

// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)

let flags = NSCalendarUnit.Day
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: [])

components.day  // This will return the number of day(s) between dates

Swift 3 Версия

let calendar = NSCalendar.current

// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: firstDate)
let date2 = calendar.startOfDay(for: secondDate)

let components = calendar.dateComponents([.day], from: date1, to: date2)

вот мой ответ для Swift 2:

func daysBetweenDates(startDate: NSDate, endDate: NSDate) -> Int
{
    let calendar = NSCalendar.currentCalendar()

    let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])

    return components.day
}

Я вижу пару ответов Swift3, поэтому я добавлю свой собственный:

public static func daysBetween(start: Date, end: Date) -> Int {
    return Calendar.current.dateComponents([.day], from: start, to: end).day!
}

именование чувствует себя более быстрым, это одна строка, и с помощью последней dateComponents() метод.

Я перевел мой цель-C ответ

let start = "2010-09-01"
let end = "2010-09-05"

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"

let startDate:NSDate = dateFormatter.dateFromString(start)
let endDate:NSDate = dateFormatter.dateFromString(end)

let cal = NSCalendar.currentCalendar()


let unit:NSCalendarUnit = .Day

let components = cal.components(unit, fromDate: startDate, toDate: endDate, options: nil)


println(components)

результат

<NSDateComponents: 0x10280a8a0>
     Day: 4

самое сложное было то, что автозаполнение настаивает на fromDate и toDate будет NSDate?, но ведь они должны быть NSDate! как показано в справочнике.

Я не вижу как хорошее решение с оператора, будет выглядеть, как вы хотите указать единицу по-разному в каждом случае. Вы могли бы вернуть временной интервал,но чем вы не получите много.

обновление для Swift 3 iOS 10 Beta 4

func daysBetweenDates(startDate: Date, endDate: Date) -> Int {
    let calendar = Calendar.current
    let components = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate)
    return components.day!
}

здесь очень хороший,

вот ответ на Swift 3 (протестирован для iOS 10 Beta)

func daysBetweenDates(startDate: Date, endDate: Date) -> Int
{
    let calendar = Calendar.current
    let components = calendar.components([.day], from: startDate, to: endDate, options: [])
    return components.day!
}

тогда вы можете назвать это так

let pickedDate: Date = sender.date
let NumOfDays: Int = daysBetweenDates(startDate: pickedDate, endDate: Date())
    print("Num of Days: \(NumOfDays)")

Swift 3. Спасибо Эмин Бугра Сарал выше startOfDay предложение.

extension Date {

    func daysBetween(date: Date) -> Int {
        return Date.daysBetween(start: self, end: date)
    }

    static func daysBetween(start: Date, end: Date) -> Int {
        let calendar = Calendar.current

        // Replace the hour (time) of both dates with 00:00
        let date1 = calendar.startOfDay(for: start)
        let date2 = calendar.startOfDay(for: end)

        let a = calendar.dateComponents([.day], from: date1, to: date2)
        return a.value(for: .day)!
    }
}

использование:

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let start = dateFormatter.date(from: "2017-01-01")!
let end = dateFormatter.date(from: "2018-01-01")!

let diff = Date.daysBetween(start: start, end: end) // 365

вещи, встроенные в swift, по-прежнему очень просты. Как и должно быть на этой ранней стадии. Но вы можете добавить свой собственный материал с риском, который приходит с перегрузкой операторов и функций глобального домена. Однако они будут локальными для вашего модуля.

let now = NSDate()
let seventies = NSDate(timeIntervalSince1970: 0)

// Standard solution still works
let days = NSCalendar.currentCalendar().components(.CalendarUnitDay, 
           fromDate: seventies, toDate: now, options: nil).day

// Flashy swift... maybe...
func -(lhs:NSDate, rhs:NSDate) -> DateRange {
    return DateRange(startDate: rhs, endDate: lhs)
}

class DateRange {
    let startDate:NSDate
    let endDate:NSDate
    var calendar = NSCalendar.currentCalendar()
    var days: Int {
        return calendar.components(.CalendarUnitDay, 
               fromDate: startDate, toDate: endDate, options: nil).day
    }
    var months: Int {
        return calendar.components(.CalendarUnitMonth, 
               fromDate: startDate, toDate: endDate, options: nil).month
    }
    init(startDate:NSDate, endDate:NSDate) {
        self.startDate = startDate
        self.endDate = endDate
    }
}

// Now you can do this...
(now - seventies).months
(now - seventies).days

вот мой ответ для Swift 3:

func daysBetweenDates(startDate: NSDate, endDate: NSDate, inTimeZone timeZone: TimeZone? = nil) -> Int {
    var calendar = Calendar.current
    if let timeZone = timeZone {
        calendar.timeZone = timeZone
    }
    let dateComponents = calendar.dateComponents([.day], from: startDate.startOfDay, to: endDate.startOfDay)
    return dateComponents.day!
}

вряд ли существует какая-либо стандартная библиотека Swift; только lean основные числовые, строковые и коллекционные типы.

вполне возможно определить такие сокращения с помощью расширений, но что касается фактических готовых API, то нет "нового" Cocoa; Swift просто сопоставляет непосредственно с теми же старыми подробными API Cocoa, как они уже существуют.

Я собираюсь добавить свою версию, даже если этот поток является год назад. Мой код выглядит так:

    var name = txtName.stringValue // Get the users name

    // Get the date components from the window controls
    var dateComponents = NSDateComponents()
    dateComponents.day = txtDOBDay.integerValue
    dateComponents.month = txtDOBMonth.integerValue
    dateComponents.year = txtDOBYear.integerValue

    // Make a Gregorian calendar
    let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)

    // Get the two dates we need
    var birthdate = calendar?.dateFromComponents(dateComponents)
    let currentDate = NSDate()

    var durationDateComponents = calendar?.components(NSCalendarUnit.CalendarUnitDay, fromDate: birthdate!, toDate: currentDate, options: nil)

    let numberOfDaysAlive = durationDateComponents?.day

    println("\(numberOfDaysAlive!)")

    txtGreeting.stringValue = "Hello \(name), You have been alive for \(numberOfDaysAlive!) days."

Я надеюсь, что это поможет кому-то.

спасибо,

метод Эрин обновлен до Swift 3, это показывает дни с сегодняшнего дня (без учета времени суток)

func daysBetweenDates( endDate: Date) -> Int 
    let calendar: Calendar = Calendar.current 
    let date1 = calendar.startOfDay(for: Date()) 
    let date2 = calendar.startOfDay(for: secondDate) 
    return calendar.dateComponents([.day], from: date1, to: date2).day! 
}

все ответы хороши. Но для локализации нам нужно вычислить количество десятичных дней между двумя датами. так мы можем обеспечить устойчивый десятичный формат.

// This method returns the fractional number of days between to dates
func getFractionalDaysBetweenDates(date1: Date, date2: Date) -> Double {

    let components = Calendar.current.dateComponents([.day, .hour], from: date1, to: date2)

    var decimalDays = Double(components.day!)
    decimalDays += Double(components.hour!) / 24.0

    return decimalDays
}

Swift 3-дней с сегодняшнего дня до даты

func daysUntilDate(endDateComponents: DateComponents) -> Int
    {
        let cal = Calendar.current
        var components = cal.dateComponents([.era, .year, .month, .day], from: NSDate() as Date)
        let today = cal.date(from: components)
        let otherDate = cal.date(from: endDateComponents)

        components = cal.dateComponents([Calendar.Component.day], from: (today! as Date), to: otherDate!)
        return components.day!
    }

вызовите такую функцию

// Days from today until date
   var examnDate = DateComponents()
   examnDate.year = 2016
   examnDate.month = 12
   examnDate.day = 15
   let daysCount = daysUntilDate(endDateComponents: examnDate)

проще вариант будет создать расширение на дату

public extension Date {

        public var currentCalendar: Calendar {
            return Calendar.autoupdatingCurrent
        }

        public func daysBetween(_ date: Date) -> Int {
            let components = currentCalendar.dateComponents([.day], from: self, to: date)
            return components.day!
        }
    }

Swift 3.2

extension DateComponentsFormatter {
    func difference(from fromDate: Date, to toDate: Date) -> String? {
        self.allowedUnits = [.year,.month,.weekOfMonth,.day]
        self.maximumUnitCount = 1
        self.unitsStyle = .full
        return self.string(from: fromDate, to: toDate)
    }
}
  func completeOffset(from date:Date) -> String? {

    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .brief

    return  formatter.string(from: Calendar.current.dateComponents([.year,.month,.day,.hour,.minute,.second], from: date, to: self))




}

Если вам нужен год месяц дни и часы в качестве строки используйте это

ВАР завтра = календарь.текущий.дата(byAdding: .день, значение: 1, to: Date())!

пусть dc = завтра.completeOffset (from: Date ())

Хороший удобный вкладыш :

extension Date {
  var daysFromNow: Int {
    return Calendar.current.dateComponents([.day], from: Date(), to: self).day!
  }
}

Это возвращает абсолютную разницу в днях между Date и сегодня:

extension Date {
  func daysFromToday() -> Int {
    return abs(Calendar.current.dateComponents([.day], from: self, to: Date()).day!)
  }
}

и затем использовать его:

if someDate.daysFromToday() >= 7 {
  // at least a week from today
}
let calendar = NSCalendar.currentCalendar();
let component1 = calendar.component(.Day, fromDate: fromDate)
let component2 = calendar.component(.Day, fromDate: toDate)
let difference  = component1 - component2

версия 2017, копирование и вставка

func simpleIndex(ofDate: Date) -> Int {

    // index here just means today 0, yesterday -1, tomorrow 1 etc.

    let c = Calendar.current
    let todayRightNow = Date()

    let d = c.date(bySetting: .hour, value: 13, of: ofDate)
    let t = c.date(bySetting: .hour, value: 13, of: todayRightNow)

    if d == nil || today == nil {

        print("weird problem simpleIndex#ofDate")
        return 0
    }

    let r = c.dateComponents([.day], from: today!, to: d!)
    // yesterday is negative one, tomorrow is one

    if let o = r.value(for: .day) {

        return o
    }
    else {

        print("another weird problem simpleIndex#ofDate")
        return 0
    }
}

Comments

    Ничего не найдено.