Returns 在 swift 中打印第一个和最后一个日期的错误结果

Returns wrong result For printing FIRST AND LAST DATE OF THE MONTH in swift

我需要使用当前日期的月份的第一个和最后一个日期。我为此找到了很多解决方案。但是都给了我错误的答案。

我的代码: 1. 月初

extension NSDate{

    func firstDateOfMonth ()->NSDate{

        let calendar = NSCalendar.currentCalendar()
        let components = calendar.components([.Year, .Month], fromDate: self)
        let startOfMonth = calendar.dateFromComponents(components)!
        return startOfMonth

    } 

    func lastDateOfmonth()->NSDate{

        let calendar = NSCalendar.currentCalendar()
        let comps2 = NSDateComponents()
        comps2.month = 1
        comps2.day = -1
        let endOfMonth = calendar.dateByAddingComponents(comps2, toDate: self, options: [])!
        return endOfMonth
    }

}

结果如下所示:

print(NSDate().firstDateOfMonth())
print(NSDate().lastDateOfmonth())

输出:

2016-01-31 18:30:00 +0000  // instead of 2016-02-01
// prints the previous month last date
2016-03-02 06:56:17 +0000   // instead of 2016-02-29
// next month date

如有不妥请指正

我也试过这段代码

extension NSDate{

    func firstDateOfMonths ()->NSDate{

        let calendar = NSCalendar.currentCalendar()

        let components = calendar.components([.Era, .Year,.Month], fromDate: self)
        components.day = 1
        let startOfMonth = calendar.dateFromComponents(components)!
        return startOfMonth

    }
}

谢谢

第一个问题是你不明白NSDate是如何工作的常见问题。 NSDate returns UTC,不是您所在时区的日期。有数百个问题可以解释这一点。

第二个问题是您粗心地获取了所有日期组件。您正在将当前日期加一个月减去一天。

计算天数的最可靠方法是 rangeOfUnitNSCalendar

extension NSDate {

  func firstDateOfMonth() -> NSDate {

    let calendar = NSCalendar.currentCalendar()
    // calendar.timeZone = NSTimeZone(forSecondsFromGMT: 0) use this line if you need UTC
    var startDate : NSDate?
    calendar.rangeOfUnit(.Month, startDate: &startDate, interval: nil, forDate: self)
    return startDate!
  }

  func lastDateOfMonth() -> NSDate {

    let calendar = NSCalendar.currentCalendar()
    // calendar.timeZone = NSTimeZone(forSecondsFromGMT: 0) use this line if you need UTC
    let dayRange = calendar.rangeOfUnit(.Day, inUnit: .Month, forDate: self)
    let dayLength = dayRange.length
    let components = calendar.components([.Year, .Month, .Day], fromDate: self)
    components.day = dayLength

    return calendar.dateFromComponents(components)!
  }
}

Swift 3+

Calendar 中 API 被命名为 dateInterval(of:start:interval:for:

extension Date {

    func firstDateOfMonth() -> Date {

        let calendar = Calendar.current
        var startDate = Date()
        var interval : TimeInterval = 0
        _ = calendar.dateInterval(of:.month, start: &startDate, interval: &interval, for: self)
        return startDate
    }

    func lastDateOfMonth() -> Date {

        let calendar = Calendar.current
        let dayRange = calendar.range(of:.day, in: .month, for: self)!
        let dayLength = dayRange.upperBound
        var components = calendar.dateComponents([.year, .month, .day], from: self)
        components.day = dayLength

        return calendar.date(from:components)!
    }
}