Ich frage mich, ob es eine neue und großartige Möglichkeit gibt, die Anzahl der Tage zwischen zwei NSDates in Swift/dem "neuen" Kakao zu berechnen?
Z.B. wie in Ruby würde ich tun:
(end_date - start_date).to_i
Die akzeptierte Antwort gibt nicht die korrekte Tagesnummer zwischen zwei Datumsangaben zurück. Sie müssen auch den Zeitunterschied berücksichtigen. Wenn Sie beispielsweise die Datumsangaben 2015-01-01 10:00
und 2015-01-02 09:00
vergleichen, werden die Tage zwischen diesen Datumsangaben als 0 (Null) zurückgegeben, da die Differenz zwischen diesen Datumsangaben weniger als 24 Stunden (also 23 Stunden) beträgt.
Wenn Sie die genaue Tageszahl zwischen zwei Datumsangaben ermitteln möchten, können Sie dieses Problem folgendermaßen umgehen:
// 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
let calendar = Calendar.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)
Hier ist meine Antwort für 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
}
Ich sehe ein paar Swift3-Antworten, also füge ich meine hinzu:
public static func daysBetween(start: Date, end: Date) -> Int {
return Calendar.current.dateComponents([.day], from: start, to: end).day!
}
Die Benennung fühlt sich schneller an, sie ist einzeilig und verwendet die neueste dateComponents()
-Methode.
Ich habe meine Objective-C-Antwort übersetzt
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)
ergebnis
<NSDateComponents: 0x10280a8a0>
Day: 4
Das Schwierigste war, dass die Autovervollständigung ausDate und ToDate besteht und zwar NSDate?
, aber tatsächlich müssen sie NSDate!
sein, wie in der Referenz angegeben.
Ich sehe nicht, wie eine gute Lösung mit einem Operator aussehen würde, da Sie die Einheit jeweils anders angeben möchten. Sie könnten das Zeitintervall zurückgeben, aber dann gewinnen Sie nicht viel.
Hier ist sehr schön, Date
Erweiterung, um den Unterschied zwischen Datumsangaben in Jahren, Monaten, Tagen, Stunden, Minuten, Sekunden zu erhalten
extension Date {
func years(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.year], from: sinceDate, to: self).year
}
func months(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.month], from: sinceDate, to: self).month
}
func days(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.day], from: sinceDate, to: self).day
}
func hours(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.hour], from: sinceDate, to: self).hour
}
func minutes(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.minute], from: sinceDate, to: self).minute
}
func seconds(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.second], from: sinceDate, to: self).second
}
}
Update für 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!
}
Hier ist die Antwort für Swift 3 (getestet für 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!
}
Dann kannst du es so nennen
let pickedDate: Date = sender.date
let NumOfDays: Int = daysBetweenDates(startDate: pickedDate, endDate: Date())
print("Num of Days: \(NumOfDays)")
Swift 3. Danke an Emin Buğra Saral oben für den startOfDay
-Vorschlag.
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)!
}
}
Verwendungszweck:
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
Die in Swift integrierten Dinge sind immer noch sehr einfach. Wie sollte es in diesem frühen Stadium sein. Sie können jedoch Ihr eigenes Material hinzufügen, mit dem Risiko, dass Operatoren und Funktionen für globale Domänen überladen werden. Sie sind jedoch lokal für Ihr Modul.
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
Hier ist meine Antwort für 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!
}
Erins Methode auf Swift 3 aktualisiert. Dies zeigt Tage vom heutigen Tag (ohne Berücksichtigung der Tageszeit)
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!
}
Ich werde meine Version hinzufügen, obwohl dieser Thread ein Jahr alt ist. Mein Code sieht so aus:
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."
Ich hoffe es hilft jemandem.
Prost,
extension Date {
func daysFromToday() -> Int {
return Calendar.current.dateComponents([.day], from: self, to: Date()).day!
}
}
Dann benutze es wie
func dayCount(dateString: String) -> String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd,yyyy hh:mm a"
let fetchedDate = dateFormatter.date(from: dateString)
let day = fetchedDate?.daysFromToday()
if day! > -1{
return "\(day!) days passed."
}else{
return "\(day! * -1) days left."
}
}
Es gibt kaum eine Swift-spezifische Standardbibliothek. nur die schlanken numerischen, String- und Collection-Typen.
Es ist durchaus möglich, solche Abkürzungen mithilfe von Erweiterungen zu definieren, aber soweit es sich um die Standard-APIs handelt, gibt es keinen "neuen" Cocoa-Code. Schnelle Zuordnung direkt zu den gleichen alten verbose Cocoa-APIs, wie sie bereits vorhanden sind.
Alle Antworten sind gut. Für Lokalisierungen müssen wir jedoch eine Anzahl Dezimaltage zwischen zwei Daten berechnen. So können wir das nachhaltige Dezimalformat bereitstellen.
// 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
}
eine einfachere Option wäre das Erstellen einer Erweiterung am Datum
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!
}
}
Schnell 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)
}
}
Schön handlicher Liner:
extension Date {
var daysFromNow: Int {
return Calendar.current.dateComponents([.day], from: Date(), to: self).day!
}
}
Swift 3 - Tage von heute bis zum Datum
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!
}
Funktion so aufrufen
// Days from today until date
var examnDate = DateComponents()
examnDate.year = 2016
examnDate.month = 12
examnDate.day = 15
let daysCount = daysUntilDate(endDateComponents: examnDate)
Sie können die folgende Erweiterung verwenden:
public extension Date {
func daysTo(_ date: Date) -> Int? {
let calendar = Calendar.current
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: self)
let date2 = calendar.startOfDay(for: date)
let components = calendar.dateComponents([.day], from: date1, to: date2)
return components.day // This will return the number of day(s) between dates
}
}
Dann können Sie es so nennen:
startDate.daysTo(endDate)
Dies gibt eine absolute Differenz in Tagen zwischen einigen Date
und heute zurück:
extension Date {
func daysFromToday() -> Int {
return abs(Calendar.current.dateComponents([.day], from: self, to: Date()).day!)
}
}
und dann verwenden Sie es:
if someDate.daysFromToday() >= 7 {
// at least a week from today
}
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))
}
wenn Sie Jahr, Monat, Tage und Stunden als Zeichenfolge benötigen, verwenden Sie diese Option
var tomorrow = Calendar.current.date (byAdding: .day, Wert: 1, bis: Date ())!
let dc = tomorrow.completeOffset (von: Date ())
Schnell 4
func getDateHeader(indexPath: Int) -> String {
let formatter2 = DateFormatter()
formatter2.dateFormat = "MM-dd-yyyy"
var dateDeadline : Date?
dateDeadline = formatter2.date(from: arrCompletedDate[indexPath] as! String)
let currentTime = dateDeadline?.unixTimestamp
let calendar = NSCalendar.current
let date = NSDate(timeIntervalSince1970: Double(currentTime!))
if calendar.isDateInYesterday(date as Date) { return "Yesterday" }
else if calendar.isDateInToday(date as Date) { return "Today" }
else if calendar.isDateInTomorrow(date as Date) { return "Tomorrow" }
else {
let startOfNow = calendar.startOfDay(for: NSDate() as Date)
let startOfTimeStamp = calendar.startOfDay(for: date as Date)
let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp)
let day = components.day!
if day < 1 { return "\(abs(day)) days ago" }
else { return "In \(day) days" }
}
}