2016-10-16 14 views
9

Sposób Zrobiłem to w Swift 2.3 brzmiała:Swift 3 - znaleźć liczbę dni kalendarzowych pomiędzy dwiema datami

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) 

Teraz to wszystko zmieniło się z Swift 3. Muszę użyć NSCalendar i NSDate stale wpisz odlewanie z as lub znajdź sposób Swift 3.

Co jest właściwym sposobem na zrobienie tego w Swift 3?

+0

użyć 'i' Calendar' dzień spełnienia wymogu. Sprawdź dokumentację referencyjną, aby zobaczyć zmiany interfejsu API. Podejmij próbę. Zaktualizuj swoje pytanie, próbując i wyjaśnij wszelkie problemy, które mogą pojawić się w tłumaczeniu. – rmaddy

+0

Dzięki, to było naprawdę pomocne. –

Odpowiedz

21

Okazuje się, że jest to o wiele prostsze do zrobienia w 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 
    } 
} 

Edytuj

Porównując ordinality dwóch terminach powinny być w tej samej era zamiast tego samego year, ponieważ naturalnie te dwie daty mogą przypaść w różnych latach.

Wykorzystanie

let yesterday = Date(timeInterval: -86400, since: Date()) 
let tomorrow = Date(timeInterval: 86400, since: Date()) 


let diff = tomorrow.interval(ofComponent: .day, fromDate: yesterday) 
// return 2 
+0

Zmienna końcowa ma argument "self", co to ma być równa? Próbowałem użyć twojej funkcji w klasie niestandardowej, aby uzyskać dni między datą a tym, co użytkownik w instalacji, ale nie działa. –

+0

Zaktualizowałem swoją odpowiedź przy użyciu próbki. Podany kod miał być użyty jako metoda instancji (można to zrobić dodając funkcję w rozszerzeniu 'Date'). –

+0

Niesamowite rozszerzenie! Idealny dla wszelkich interwałów wszelkich typów dat, dokładnie tego, czego szukałem :). Dla innych, którzy chcą dodać przyszłe daty, spróbuj tego, var components = DateComponents() components.setValue (numOfDays, dla: .day) let futureDate = Calendar.current.date (przez dodanie: komponenty do: dateChosen), dateChosen jest właśnie tym, let dateChosen: Date = Date() –

3
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 
} 
0
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! 
    } 

Innym podejściem porównać ze składnikami dzień miesiąc rok

Zastosowanie:

daty wejścia w następującym formacie

[dd, mm, yyyy] 
[9, 6, 2017] 
[6, 6, 2017] 
0

Aktualizacja dla Swift 3:

jeśli chcesz wydrukować liczbę dni, jak również listę dni między dwiema datami kalendarza, użyte poniżej prostego kodu;

// deklaracja zmiennej:

var daysListArray = [String]() 

// funkcja Defination:

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 
} 

// Wywołanie funkcji powyżej:

let count = self.printCountBtnTwoDates(mStartDate: your_start_date, mEndDate: your_end_date) 
    print("count: \(count)") // date count 

// Ciesz kodowanie ...!

2

W Swift4 możemy łatwo uzyskać brak dni między dwiema różnymi datami kalendarzowymi, korzystając z poniższych kodów.

Pierwsza z nich to różnica w dniach z aktualną datą.

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) 

Kontynuacja z powyższym kodem ... Poniżej znajduje się lista dni dla dwóch różnych dat.Zawartość poprzednim dniu pochodzi z góry dniu

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

print(differenceInDays) 
2

Swift wersji 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) 

Zadrukowane - lat 16 miesiąca: 10 dni: 19 godzin 12 minuty: 16 sekund: 42 isLeapMonth: false

19

W Swift 4 jest prosta-liner, aby uzyskać liczbę dni (lub inny DateComponent) pomiędzy dwiema datami:

let diffInDays = Calendar.current.dateComponents([.day], from: dateA, to: dateB).day 
+0

Świetny jednolinijkowy. Chciałbym, żeby mogłem +2, +1 będzie musiał zrobić –

-1

Znalazłem to na innym wątku, ale to w końcu najbardziej proste rozwiązanie dla mnie za pomocą Swift 4:

Podstawy:

let previousDate = ENTER DATE HERE 
let now = Date() 

let formatter = DateComponentsFormatter() 
formatter.unitsStyle = .brief // May delete the word brief to let Xcode show you the other options 
formatter.allowedUnits = [.month, .day, .hour] 
formatter.maximumUnitCount = 1 // Show just one unit (i.e. 1d vs. 1d 6hrs) 

let stringDate = formatter.string(from: previousDate, to: now) 

musiałem sformatować NSDate (CoreData) jako data, więc dodałem to przed powyższym kodzie:

// Format date basis 
guard let lastAccessed = disease.last_accessed as Date? else { 
    continue 
} 

Musiałem także dodać następujące do końca faktycznie korzysta datę:

guard var date = stringDate as String? else { 
    continue 
} 
Powiązane problemy