Итерация в течение года, чтобы каждый день получать объект NSDate в Swift

Здравствуйте, у меня есть метод, который возвращает массив раз для каждого дня.

prayTimesDate(date: NSDate, latitide : Double, longitude : Double, timeZone : Double) -> NSMutableArray

Мне нужно перебрать весь год или, может быть, диапазон дат, чтобы получить массив раз для каждого дня в течение всего года. Я нашел много ссылок на ruby ​​и python о том, как это сделать, но я не смог найти ничего для быстрого или объективного-c. Есть ли какие-либо встроенные методы в Swift, которые сделают это? Если нет, может кто-нибудь помочь мне, так как я все еще новичок в программировании. Любой вклад приветствуется.

Это код Objective-C для метода, который я связываю со своим быстрым проектом.

- (NSMutableArray *)prayerTimesDate:(NSDate *)date latitude:(double)latitude longitude:(double)longitude andTimezone:(double)timezone
{
    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:unitFlags fromDate:date];

    NSInteger year = [components year];
    NSInteger month = [components month];
    NSInteger day = [components day];

    return [self getDatePrayerTimesForYear:year month:month day:day latitude:latitude longitude:longitude andtimeZone:timezone];
}

person gnm1978    schedule 24.01.2015    source источник
comment
Какой код в настоящее время находится в вашем методе PrayTimesDate?   -  person Lyndsey Scott    schedule 24.01.2015
comment
@ Линдси Скотт, я только что обновил свой вопрос   -  person gnm1978    schedule 25.01.2015
comment
чтобы уточнить мой вопрос, мне просто нужен способ итерации от текущего дня до года каждый раз, когда пользователь открывает приложение, чтобы я мог обновлять таблицы времени молитв.   -  person gnm1978    schedule 25.01.2015
comment
И вы уже написали что-нибудь в своем методе getDatePrayerTimesForYear?   -  person Lyndsey Scott    schedule 25.01.2015
comment
Кроме того, вы хотели код на Swift или Obj-C? Я понимаю, что вы хотите это в Swift... Но для чего нужен метод Obj-C?   -  person Lyndsey Scott    schedule 25.01.2015
comment
И, самое главное, какое именно время вы хотите в каждом массиве дней? Вам просто нужен массив, содержащий, например, полночь каждого дня?   -  person Lyndsey Scott    schedule 25.01.2015
comment
да, я бы хотел, чтобы это было быстро, конечно. Приведенный выше метод уже возвращает правильное время для заданной даты. Он возвращает массив строк семи времен молитвы в зависимости от вашего местоположения и часового пояса. то, что я пытаюсь сделать, это использовать этот метод, чтобы получить массив молитв не только за один день, но и за весь год с текущего дня.   -  person gnm1978    schedule 25.01.2015
comment
скажем, например, сегодня 24.01.2015. Я хочу получить массив молитв каждого дня каждого месяца до 24.01.2016.   -  person gnm1978    schedule 25.01.2015
comment
Я бы хотел, чтобы люди комментировали, прежде чем голосовать против, чтобы мы могли учиться на своих ошибках.   -  person gnm1978    schedule 25.01.2015


Ответы (4)


Предполагая, что ваш метод prayerTimesDate: уже возвращает ожидаемый результат, вы можете перебирать каждый день года, многократно вызывая prayerTimesDate:, чтобы получить массив, содержащий время молитвы для каждого дня, например:

func yearlyPrayerDatesFromCurrentDate (latitude:Double, longitude:Double, timezone:Double) -> NSMutableArray {

    // Set "date" to equal the current day
    var date:NSDate! = NSDate()

    // Increment "date" by one year to calculate the ending
    // date for the loop
    let gregorian:NSCalendar! = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
    let dateComponents = NSDateComponents()
    dateComponents.year = 1
    let endingDate:NSDate! = gregorian.dateByAddingComponents(dateComponents, toDate: date, options: nil)

    // Create an array to hold *all* the returned 
    // results for the year
    var datesArray = NSMutableArray()

    // Loop through each date until the ending date is
    // reached
    while date.compare(endingDate) != NSComparisonResult.OrderedDescending {
        // Call your prayerTimesDate: method on the current
        // date to get that date's prayer times and add the
        // times from the returned array to the datesArray
        datesArray.addObjectsFromArray(prayerTimesDate(date, latitude: latitude, longitude: longitude, andTimezone: timezone))

        // increment the date by 1 day
        let dateComponents = NSDateComponents()
        dateComponents.day = 1
        date = gregorian.dateByAddingComponents(dateComponents, toDate: date, options: nil)
    }

    return datesArray
}
person Lyndsey Scott    schedule 24.01.2015
comment
хорошо, поэтому я только что отредактировал код на dateArray.addObject вместо addObjectsFormArray, чтобы у меня была каждая дата в отдельном массиве, затем я добавил dateArray.addObject(date), чтобы у меня была дата для идентификации каждого массива. Но первое свидание всегда на день раньше бывшего. 25.01.2015 - person gnm1978; 25.01.2015
comment
Я даже добавил дату перед циклом while, чтобы получить текущую дату, а затем снова добавил ее в цикле while после addObjects. - person gnm1978; 25.01.2015
comment
@GhassanMohammed Сейчас 25 января 2015 года по часовому поясу GMT, и это часовой пояс для любого объекта NSDate. - person Lyndsey Scott; 25.01.2015
comment
о я с. Извините за невежество, но должен ли я изменить компонент даты на часовой пояс по умолчанию, даст ли это мне правильную дату? - person gnm1978; 25.01.2015
comment
Вероятно, вам следует просто вернуть даты молитвыTimesDate по Гринвичу, но вот несколько решений, которые могут помочь: - person Lyndsey Scott; 25.01.2015

Вот еще пример для периода более 14 дней (без NSCalendar):

let ti:NSTimeInterval = 24*60*60 //one day
let dateFrom = NSDate() //Now
let dateTo = dateFrom.dateByAddingTimeInterval(24*60*60*14) //14 Days later

var nextDate = NSDate()
var endDate = dateTo.dateByAddingTimeInterval(ti)

while nextDate.compare(endDate) == NSComparisonResult.OrderedAscending
{      
    print("nextDate:", nextDate)
    nextDate = nextDate.dateByAddingTimeInterval(ti)
}
person Peter Kreinz    schedule 16.08.2015
comment
из-за перехода на летнее время дни не обязательно состоят из 24 часов. они могут длиться 23, 24 или 25 часов. поскольку последний результат используется для вычисления следующего, ошибка будет составлять не только 2 дня в году, но и до половины от него. - person vikingosegundo; 30.08.2017
comment
обязателен к просмотру каждым разработчиком iOS/macOS: WWDC11: выполнение расчетов календаря - person vikingosegundo; 30.08.2017

Создайте NSDateComponents экземпляр на 1 день и NSDate объектов на каждый раз в первый день. Теперь вы можете перебрать желаемое количество дней (или пока не нажмете дату окончания), а затем вы можете использовать dateByAddingComponents:toDate:options: календаря, чтобы получить новую дату для каждого дня.

person Wain    schedule 24.01.2015

Из документа Apple: чтобы вычислить последовательность дат, используйте метод enumerateDatesStartingAfterDate:matchingComponents:options:usingBlock: вместо вызова этого метода ( - nextDateAfterDate:matchingComponents:options: ) в цикле с результатом предыдущей итерации цикла.

Как я понял, он будет повторять все даты, совпадающие с «matchingComponents», пока вы не закончите итерацию с «stop.memory = true».

//: Playground - noun: a place where people can play

import UIKit

let calendar = NSCalendar.currentCalendar()
let startDate = calendar.startOfDayForDate(NSDate())
let finishDate = calendar.dateByAddingUnit(.Day, value: 10, toDate: startDate, options: [])
let dayComponent = NSDateComponents()
dayComponent.hour = 1

calendar.enumerateDatesStartingAfterDate(startDate, matchingComponents: dayComponent, options: [.MatchStrictly]) { (date, exactMatch, stop) in
    print(date)
    if date!.compare(finishDate!) == NSComparisonResult.OrderedDescending {
        // .memory gets at the value of an UnsafeMutablePointer
        stop.memory = true
    }
}
person Жека Yarotski    schedule 05.07.2016