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 datesSwift 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