【问题标题】:Iterating over a year to get each days NSDate object in Swift迭代一年以获取 Swift 中的每一天 NSDate 对象
【发布时间】:2015-01-24 20:54:34
【问题描述】:

您好,我有一个方法可以返回每天的时间数组。

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

我需要遍历一整年或一个日期范围,以获得一整年中每一天的时间数组。我在 ruby​​ 和 python 中找到了很多关于如何做到这一点的参考资料,但我找不到 swift 或 Objective-c 的任何东西。 swift中有没有内置的方法可以实现这一点?如果没有,有人可以帮助我,因为我还是编程新手。非常感谢任何输入。

这是我链接到我的 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];
}

【问题讨论】:

  • 目前在您的 grayTimesDate 方法中有什么代码?
  • @Lyndsey Scott 我刚刚更新了我的问题
  • 为了澄清我的问题,我只需要一种方法从用户打开应用程序的每一天一直迭代到一年,这样我就可以更新祈祷时间表。
  • 你有没有在你的 getDatePrayerTimesForYear 方法中写过任何东西?
  • 另外,您想要 Swift 还是 Obj-C 中的代码?我猜你想在 Swift 中使用它……但是 Obj-C 方法有什么用?

标签: ios swift nsdate nsdatecomponents


【解决方案1】:

假设您的 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
}

【讨论】:

  • 好的,所以我只是将代码编辑为 datesArray.addObject 而不是 addObjectsFormArray 所以我可以将每个日期放在自己的单独数组中,然后添加 datesArray.addObject(date) 这样我就可以有一个日期来识别每个数组。但第一次约会总是提前一天。 2015 年 1 月 25 日
  • 我什至在 while 循环之前添加了日期以获取当前日期,然后在 addObjects 之后的 while 循环中再次添加它
  • @GhassanMohammed GMT 时区目前是 2015 年 1 月 25 日,这是任何 NSDate 对象的时区。
  • 哦,我c。请原谅我的无知,但我是否应该将日期组件更改为默认时区才能给我正确的日期?
  • 您可能应该只返回格林威治标准时间的祷告时间日期,但这里有一些可能会有所帮助的解决方案:stackoverflow.com/q/18107782/2274694
【解决方案2】:

这是超过 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)
}

【讨论】:

  • 由于夏令时,天不一定有 24 小时。它们可能长达 23、24 或 25 小时。由于最后一个结果用于计算下一个结果,因此误差不仅会在一年中的 2 天内出现,而且会达到一半。
  • iOS/macOS 开发者必看:WWDC11: Performing Calendar Calculations
【解决方案3】:

为 1 天创建一个 NSDateComponents 实例,在第一天的每个时间创建一个 NSDate 对象。现在您可以遍历您想要的天数(或直到您点击结束日期),然后您可以使用日历的dateByAddingComponents:toDate:options: 来获取每一天的新日期。

【讨论】:

    【解决方案4】:

    来自 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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-04-27
      • 2016-01-22
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多