NSDate में एक महीना कैसे जोड़ें?


81

NSDate ऑब्जेक्ट में महीना कैसे जोड़ें?

NSDate *someDate = [NSDate Date] + 30Days.....;

1
यदि परिणाम की शुरुआत की तारीख 31 जनवरी है तो आप क्या परिणाम चाहते हैं?
gnasher729

जवाबों:


139

आपको NSDateCompords का उपयोग करने की आवश्यकता है :

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

क्या आप जानते हैं कि मैं अब नियति तिथि के बीच तुलना कैसे कर सकता हूं? यह जाँचने के लिए कि क्या मैं इस तारीख को पास करता हूँ?
या अज़रान

1
तिथियों की तुलना से किया जाता है NSDate कार्यों के साथ तुलना, earlierDate और laterDate - उस के लिए NSDate दस्तावेज़ देखें: developer.apple.com/library/mac/#documentation/Cocoa/Reference/...
Theeye

1
@orazran के साथ आप तारीखों की तुलना कर सकते हैं: [date timeIntervalSinceDate:otherDate]जो सेकंड में उनके बीच के अंतर को वापस कर देगा (पिछली तारीखों के लिए 0 से कम, भविष्य की तारीखों के लिए 0 से अधिक)।
Abhi Beckert

127

IOS 8 और OS X 10.9 के साथ आप इसका NSCalendarUnitsउपयोग कर सकते हैं NSCalendar:

उद्देश्य सी

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: [])

उपरोक्त उदाहरण एक विधि को कॉल कर रहे हैं, एक संपत्ति तक नहीं पहुंच रहे हैं।
केविन

स्विफ्ट 3: तारीख दें = Calendar.current.date (byAdding: .month, value: 1, to: Date ())
मेक्सिकम बिलन

यह स्वीकृत उत्तर होना चाहिए। वर्तमान में स्वीकृत उत्तर केवल ऑब्जेक्टिव-सी है और अत्यधिक क्रिया है।
कॉलिन बेसनेट

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 जनवरी तक जोड़ देता हूं तो यह 2 मार्च को समाप्त हो जाएगा या ...?
मिशाल ज़िओब्रो

13

उदाहरण के लिए, 3स्विफ्ट में वर्तमान तिथि में महीनों को जोड़ने के लिए:

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

स्विफ्ट 2.0 में:

let date = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 3, toDate: NSDate(), options: [])
  • आपको अधिक सरलता से बताने की नई OptionSetTypeसंरचना हैNSCalendarUnit.Month
  • पैरामीटर्स जो पैरामीटर लेते हैं OptionSetType(जैसे options:पैरामीटर, जो लेता है NSCalendarOptions) नहीं हो सकता है nil, इसलिए []"कोई विकल्प नहीं" का प्रतिनिधित्व करने के लिए एक खाली सेट ( ) में पास करें।

.MonthCalendarUnitहटाई गई है, उपयोग.CalendarUnitMonth
अर्नोल्ड

3

स्विफ्ट 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

स्विफ्ट 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

इसलिए मैं जांचता हूं कि क्या डीएसटी सीमा पार हो गई है, और यदि ऐसा है तो उसके अनुसार एक घंटा जोड़ें या घटाएं:

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 दिन या एक दिन या एक वर्ष जोड़ना चाहते हैं।

  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 परिवर्तन या लीप सेकंड आदि में उपयोग किया जाता है
जेम्स वेबस्टर

@JamesWebster यह एक बहुत अच्छी बात है, मैंने अपने जवाब में इसे नोट किया है। निम्न स्तर जोड़ / घटाना सेकंड अभी भी उत्तरों में से एक के रूप में है। आप हमेशा डीएसटी जैसी चीजों का पालन नहीं करना चाहते हैं, यह इस बात पर निर्भर करता है कि किस दिनांक के लिए उपयोग किया जा रहा है।
अबी बेकेर्ट

2
हर महीने में 30 दिन नहीं होते हैं
आदिल मलिक

यह 30 दिन नहीं जोड़ता है। यह 30 गुना 86,400 सेकंड जोड़ता है, जो कुछ पूरी तरह से अलग है। इस तरह का कोड अविश्वसनीय रूप से बुरा सलाह है।
gnasher729

यह सच है कि यह डीएसटी संक्रमण के मामले में गलत परिणाम देता है। लीप सेकंड एक समस्या नहीं हैं , क्योंकि यूनिक्स समय उन्हें नहीं गिनता है।
मार्टिन आर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.