How to add one month to an NSDate?

前端 未结 9 2136
自闭症患者
自闭症患者 2020-12-23 11:01

How To Add Month To NSDate Object?

NSDate *someDate = [NSDate Date] + 30Days.....;
相关标签:
9条回答
  • 2020-12-23 11:34

    For swift 3.0

    extension Date {
        func addMonth(n: Int) -> Date {
            let cal = NSCalendar.current
            return cal.date(byAdding: .month, value: n, to: self)!
        }
        func addDay(n: Int) -> Date {
            let cal = NSCalendar.current
            return cal.date(byAdding: .day, value: n, to: self)!
        }
        func addSec(n: Int) -> Date {
            let cal = NSCalendar.current
            return cal.date(byAdding: .second, value: n, to: self)!
        }
    }
    
    0 讨论(0)
  • 2020-12-23 11:34

    In Swift 2.0

        let startDate = NSDate()
        let dateComponent = NSDateComponents()
        dateComponent.month = 1
        let cal = NSCalendar.currentCalendar()
        let endDate = cal.dateByAddingComponents(dateComponent, toDate: startDate, options: NSCalendarOptions(rawValue: 0))
    
    0 讨论(0)
  • 2020-12-23 11:34

    Do you want to add a "month" or exactly 30 days? If it's 30 days, you do it like this:

    // get a date
    NSDate *date = [NSDate dateWithNaturalLanguageString:@"2011-01-02"];
    
    // add 30 days to it (in seconds)
    date = [date dateByAddingTimeInterval:(30 * 24 * 60 * 60)];
    
    NSLog(@"%@", date); // 2011-02-01
    

    Note: this will not take daylight savings time transitions or leap seconds into account. Use @TheEye's answer if you need that

    0 讨论(0)
  • 2020-12-23 11:36

    FOR SWIFT 3.0

    here is function , you can reduce days , month ,day by any count like for example here , i have reduced the current system date's year by 100 year , you can do it for day , month also just set the counter and then store the values in array , and do whatever you want to do with that array

    func currentTime(){
    
        let date = Date()
        let calendar = Calendar.current
        var year = calendar.component(.year, from: date)
        let month = calendar.component(.month, from: date)
        let  day = calendar.component(.day, from: date)
        let pastyear = year - 100
        var someInts = [Int]()
        printLog(msg: "\(day):\(month):\(year)" )
    
        for _ in pastyear...year        {
            year -= 1
                         print("\(year) ")
            someInts.append(year)
        }
    
        print(someInts)
    }
    
    0 讨论(0)
  • 2020-12-23 11:37

    For example, to add 3 months to the current date in Swift:

    let date = NSCalendar.currentCalendar().dateByAddingUnit(.MonthCalendarUnit, value: 3, toDate: NSDate(), options: nil)!
    

    In Swift 2.0:

    let date = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 3, toDate: NSDate(), options: [])
    
    • The new OptionSetType structure of NSCalendarUnit lets you more simply specify .Month
    • Parameters that take OptionSetType (like the options: parameter, which takes NSCalendarOptions) can't be nil, so pass in an empty set ([]) to represent "no options".
    0 讨论(0)
  • 2020-12-23 11:39

    Other answers work fine if your desired behaviour is adding a month and allowing for daylight savings time. This produces results such that:

    01/03/2017 00:00 + 1 month -> 31/03/2017 23:00
    01/10/2017 00:00 + 1 month -> 01/11/2017 01:00
    

    However I wanted to ignore the hour lost or gained by DST, such that:

    01/03/2017 00:00 + 1 month -> 01/04/2017 00:00
    01/10/2017 00:00 + 1 month -> 01/11/2017 00:00
    

    So I check if a DST boundary is passed, and if so either add or subtract an hour accordingly:

    func offsetDaylightSavingsTime() -> Date {
            // daylightSavingTimeOffset is either + 1hr or + 0hr. To offset DST for a given date, we need to add an hour or subtract an hour
            // +1hr -> +1hr
            // +0hr -> -1hr
            // offset = (daylightSavingTimeOffset * 2) - 1 hour
    
            let daylightSavingsTimeOffset = TimeZone.current.daylightSavingTimeOffset(for: self)
            let oneHour = TimeInterval(3600)
            let offset = (daylightSavingsTimeOffset * 2) - oneHour
            return self.addingTimeInterval(offset)
        }
    
        func isBetweeen(date date1: Date, andDate date2: Date) -> Bool {
            return date1.compare(self).rawValue * self.compare(date2).rawValue >= 0
        }
    
        func offsetDaylightSavingsTimeIfNecessary(nextDate: Date) -> Date {
            if let nextDST = TimeZone.current.nextDaylightSavingTimeTransition(after: self) {
                if nextDST.isBetweeen(date: self, andDate: nextDate){
                    let offsetDate = nextDate.offsetDaylightSavingsTime()
                    let difference = offsetDate.timeIntervalSince(nextDate)
                    return nextDate.addingTimeInterval(difference)
                }
            }
    
            return nextDate
        }
    
        func dateByAddingMonths(_ months: Int) -> Date? {
            if let dateWithMonthsAdded = Calendar.current.date(byAdding: .month, value: months, to: self) {
                return self.offsetDaylightSavingsTimeIfNecessary(nextDate: dateWithMonthsAdded)
            }
    
            return self
        }
    

    Test:

    func testDateByAddingMonths() {
    
        let date1 = "2017-01-01T00:00:00Z".asDate()
        let date2 = "2017-02-01T00:00:00Z".asDate()
        let date3 = "2017-03-01T00:00:00Z".asDate()
        let date4 = "2017-04-01T00:00:00Z".asDate()
        let date5 = "2017-05-01T00:00:00Z".asDate()
        let date6 = "2017-06-01T00:00:00Z".asDate()
        let date7 = "2017-07-01T00:00:00Z".asDate()
        let date8 = "2017-08-01T00:00:00Z".asDate()
        let date9 = "2017-09-01T00:00:00Z".asDate()
        let date10 = "2017-10-01T00:00:00Z".asDate()
        let date11 = "2017-11-01T00:00:00Z".asDate()
        let date12 = "2017-12-01T00:00:00Z".asDate()
        let date13 = "2018-01-01T00:00:00Z".asDate()
        let date14 = "2018-02-01T00:00:00Z".asDate()
    
        var testDate = "2017-01-01T00:00:00Z".asDate()
        XCTAssertEqual(testDate, date1)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date2)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date3)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date4)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date5)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date6)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date7)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date8)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date9)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date10)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date11)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date12)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date13)
    
        testDate = testDate.dateByAddingMonths(1)!
        XCTAssertEqual(testDate, date14)
    }
    

    For completeness, the .asDate() method I'm using

    extension String {
    
        static let dateFormatter = DateFormatter()
        func checkIsValidDate() -> Bool {
            return self.tryParseToDate() != nil
        }
    
        func tryParseToDate() -> Date? {
            String.dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
            return String.dateFormatter.date(from: self)
        }
    
        func asDate() -> Date {
            return tryParseToDate()!
        }
    }
    
    0 讨论(0)
提交回复
热议问题