使用Swift 2中的NSDateComponents计算下个月开始的奇怪日期结果

时间:2016-02-17 19:50:34

标签: ios swift nsdate nscalendar nsdatecomponents

我有一个功能:

internal func startOfNextMonth() -> NSDate? {
    guard
        let cal: NSCalendar = NSCalendar.currentCalendar(),
        let comp: NSDateComponents = NSDateComponents() else { return nil }
    comp.month = 1
    comp.day = 0
    comp.to12pm()
    let date = cal.dateByAddingComponents(comp, toDate: self.startOfMonth()!, options: [])!
    return date
}

这应该计算下个月的第一天,但​​它会返回2016-03-02 08:00:00 UTC

这是否与闰年有关(2月29日弄乱它?)

这是我的startOfMonth功能供参考,to12pm()扩展程序:

internal func startOfMonth() -> NSDate? {
    guard
        let cal: NSCalendar = NSCalendar.autoupdatingCurrentCalendar(),
        let comp: NSDateComponents = cal.components([.Year, .Month], fromDate: self.at12pm()!) else { return nil }
    comp.to12pm()
    return cal.dateFromComponents(comp)!
}

internal extension NSDateComponents {
    func to12pm() {
        self.hour = 12
        self.minute = 0
        self.second = 0
    }
}

internal func at12pm() -> NSDate? {
    let cal = NSCalendar.currentCalendar()
    return cal.dateBySettingHour(12, minute: 0, second: 0, ofDate: self, options: [])
}

2 个答案:

答案 0 :(得分:2)

startOfMonth()会在下个月的下午12点(12:00)返回,然后在startOfNextMonth()中再添加12小时,结果提前一天。

NSCalendar有一种智能方法可以计算下个月的开始,无论夏令时变化或其他不规则性

let calendar = NSCalendar.currentCalendar()
let components = NSDateComponents()
components.day = 1
let startOfNextMonth = calendar.nextDateAfterDate(NSDate(), matchingComponents: components, options: .MatchNextTime)

答案 1 :(得分:0)

如果你只是想计算下个月的第一天,你所要做的就是:

let calendar = NSCalendar.autoupdatingCurrentCalendar()
let todayComponents = calendar.components([.Year, .Month], fromDate: NSDate())
todayComponents.month += 1
let firstDayOfMonth = calendar.dateFromComponents(todayComponents)

测试:

print(firstDayOfMonth)

在控制台中打印:

Optional(2016-03-01 08:00:00 +0000)

此外,如果是12月,则日期将溢出到明年1月。