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.