NSDate에 한 달을 추가하는 방법은 무엇입니까?


답변:


138

NSDateComponents 를 사용해야합니다 .

NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setMonth:1];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *newDate = [calendar dateByAddingComponents:dateComponents toDate:originalDate options:0];
[dateComponents release]; // If ARC is not used, release the date components

지금과 운명 날짜를 어떻게 비교할 수 있는지 아십니까? 이 날짜를 통과했는지 확인하려면?
— 또는 azran

1
날짜 비교는 NSDate 함수 compare, earlyDate 및 laterDate를 사용하여 수행됩니다. NSDate 문서를 참조하십시오. developer.apple.com/library/mac/#documentation/Cocoa/Reference/…
— TheEye

1
@orazran을 사용하여 날짜를 비교할 수 있습니다 : [date timeIntervalSinceDate:otherDate], 초 단위의 차이를 반환합니다 (과거 날짜의 경우 0 미만, 미래 날짜의 경우 0보다 큼).
— Abhi Beckert 2011

126

iOS 8 및 OS X 10.9에서는 다음을 NSCalendarUnits사용하여 추가 할 수 있습니다 NSCalendar.

목표 -C

NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *someDate = [cal dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:[NSDate date] options:0];

스위프트 3

let date = Calendar.current.date(byAdding: .month, value: 1, to: Date())

스위프트 2

let cal = NSCalendar.currentCalendar()
let date = cal.dateByAddingUnit(.Month, value: 1, toDate: NSDate(), options: [])

위의 예는 속성에 액세스하지 않고 메서드를 호출하는 것입니다.
— Kevin

스위프트 3 : 할 일 = Calendar.current.date (byAdding : .month, 값 : 1 : 날짜 ())
— Maksym 빌란

이것은 받아 들여진 대답이어야합니다. 현재 허용되는 답변은 Objective-C 전용이며 지나치게 장황합니다.
— Colin Basnett

23

신속한 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)!
    }
}

1
1 월 31 일에 1 개월을 추가하면 3 월 2 일에 끝나거나 ...?
— Michał Ziobro

13

예를 들어 3Swift에서 현재 날짜에 월 을 추가 하려면 :

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

Swift 2.0에서 :

let date = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 3, toDate: NSDate(), options: [])
  • 새로운 OptionSetType구조NSCalendarUnit 사용하면.Month
  • 취하는 매개 변수 OptionSetType(예 : options:취하는 매개 변수 NSCalendarOptions)는 일 수 없으므로 nil빈 집합 ( [])을 전달하여 "옵션 없음"을 나타냅니다.

.MonthCalendarUnit더 이상 사용되지 않습니다..CalendarUnitMonth
— Arnold

3

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))

2

SWIFT 3.0 용

여기에 기능이 있습니다. 예를 들어 여기와 같이 일, 월, 일을 줄일 수 있습니다. 예를 들어 여기와 같이 현재 시스템 날짜의 연도를 100 년으로 줄였습니다. 일, 월에 대해 할 수 있으며 카운터를 설정 한 다음 값을 저장하십시오 배열에서 원하는 작업을 수행합니다.

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)
}

1

원하는 행동이 한 달을 추가하고 일광 절약 시간을 허용하는 경우 다른 답변이 제대로 작동합니다. 결과는 다음과 같습니다.

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

그러나 나는 DST가 잃거나 얻은 시간을 무시하고 싶었습니다.

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

따라서 DST 경계가 통과되었는지 확인하고 그에 따라 시간을 더하거나 뺍니다.

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
    }

테스트:

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)
}

완전성을 위해 사용중인 .asDate () 메서드

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()!
    }
}

1

현재까지 자동 계산을 선택한 사용자에 따라 "월"또는 정확히 30 일 또는 1 일 또는 1 년을 추가 하시겠습니까?

  NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] 
  init];
    [dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
    NSDateComponents *components = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:[NSDate date]];

        NSDateComponents *dayComponent = [[NSDateComponents alloc] 
 init];
        int changeid = [here number of days intValue];

        dayComponent.hour = changeid;

        NSCalendar *theCalendar = [NSCalendar currentCalendar];
        NSDate *nextDate = [theCalendar 
 dateByAddingComponents:dayComponent toDate:[dateFormatter 
  dateFromString:self.fromDateTF.text] options:0];

        NSLog(@"nextDate: %@ ...", nextDate);
        [self.toDateTF setText:[dateFormatter 
            stringFromDate:nextDate]];

////달


-3

"월"을 추가 하시겠습니까, 아니면 정확히 30 일을 추가 하시겠습니까? 30 일이면 다음과 같이합니다.

// 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

참고 : 이것은 일광 절약 시간 전환이나 윤초를 고려하지 않습니다. 필요한 경우 @TheEye의 답변을 사용하십시오.


2
DST 변경 또는 윤초 등에서 사용하면 실패합니다.
— James Webster

@JamesWebster는 매우 좋은 점입니다. 제 답변에 그것을 포함하는 메모를 추가했습니다. 낮은 수준의 더하기 / 빼기 초는 여전히 답 중 하나에 속합니다. DST와 같은 것을 항상 따르고 싶지는 않습니다. 날짜가 사용되는 날짜에 따라 다릅니다.
— Abhi Beckert 2011

2
매월 30 일이 없습니다
— Adil Malik 2014

이것은 30 일을 추가하지 않습니다. 30 곱하기 86,400 초를 더하는 것은 완전히 다른 것입니다. 그런 종류의 코드는 엄청나게 나쁜 조언입니다.
— gnasher729 2014

이것이 DST 전환의 경우 잘못된 결과를주는 것은 사실입니다. 윤초는 그러나 있습니다 하지 유닉스 시간을 계산하지 않기 때문에 문제.
— Martin R
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.