अगर एक NSDate दो अन्य NSDates के बीच होता है, तो कैसे जांचें


90

मैं यह पता लगाने की कोशिश कर रहा हूं कि एनएसडीट का उपयोग करके वर्तमान तिथि किसी तिथि सीमा के भीतर है या नहीं।

उदाहरण के लिए, आप NSDate का उपयोग करके वर्तमान तिथि / समय प्राप्त कर सकते हैं:

NSDate rightNow = [NSDate date];

फिर मैं उस तिथि का उपयोग यह जांचने के लिए करना चाहूंगा कि क्या यह 9AM - 5PM की सीमा में है ।


1
आप इस प्रश्न के उत्तर के बारे में अधिक जानकारी के लिए एक विशेष समय अवधि के लिए NSDate ऑब्जेक्ट कैसे बनाते हैं, जैसे कि शाम 5-9pm पर एक नज़र डाल सकते हैं।
मार्क चारबोनो

जवाबों:


167

मैं एक हल लेकर आया। यदि आपके पास एक बेहतर समाधान है, तो इसे छोड़ने के लिए स्वतंत्र महसूस करें और मैं इसे सही के रूप में चिह्नित करूंगा।

+ (BOOL)date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate
{
    if ([date compare:beginDate] == NSOrderedAscending)
        return NO;

    if ([date compare:endDate] == NSOrderedDescending) 
        return NO;

    return YES;
}

3
यह अच्छा लग रहा है, लेकिन आप इसे कुछ इस तरह से नाम बदलना चाह सकते हैं: + (BOOL) दिनांक: (NSDate *) दिनांक isBetweenDate: (NSDate *) startDate औरDate: (NSDate *) भ्रम से बचने के लिए इसे समाप्त करें।
जेफ केली

3
कोड गोल्फ! कंपाइलर को तुलनात्मक रूप से शॉर्ट सर्किट करना चाहिए, जो आपके पास की क्षमता के बराबर है: रिटर्न ([डेट तुलना: डेडेट! = NSOrderedDescending) && ([डेट तुलना: एंडडेट] = = NSOrderedAscending));
टिम

1
बेहतर अभी तक, मैं इसे एक उदाहरण विधि (NSDate के अतिरिक्त), क्लास विधि नहीं बनाऊँगा। मैं इसके साथ जाऊँगा: -isBetweenDate: और दिनांक:
डेव बैटन

4
अति उत्कृष्ट! मैंने इससे एक श्रेणी बनाई:- (BOOL)isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate;
मत्तेओ अलेसानी

2
अच्छा समाधान, आप इसे शॉर्ट-सर्किट (और एक मूल डी मॉर्गन एप्लिकेशन द्वारा कम क्रिया भी बना सकते हैं।return !([date compare:startDate] == NSOrderedAscending || [date compare:endDate] == NSOrderedDescending);
गेब्रियल पेट्रोनेला

13

पहले भाग के लिए, NSDate ऑब्जेक्ट्स की तुलना करने के लिए @kperryua से उत्तर का उपयोग करें। आपके अपने प्रश्न के उत्तर से, ऐसा लगता है कि आप समझ गए हैं।

वास्तव में तारीखों की तुलना करने के लिए, मैं आपके उत्तर पर @Tim की टिप्पणी से पूरी तरह सहमत हूं । यह वास्तव में आपके कोड के बराबर अधिक संक्षिप्त है, और मैं समझाऊंगा कि क्यों।

+ (BOOL) date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {
    return (([date compare:beginDate] != NSOrderedAscending) && ([date compare:endDate] != NSOrderedDescending));
}

हालाँकि ऐसा लग सकता है कि रिटर्न स्टेटमेंट में && ऑपरेटर के दोनों ऑपरेंड का मूल्यांकन करना होगा, लेकिन वास्तव में ऐसा नहीं है। कुंजी " शॉर्ट-सर्किट मूल्यांकन " है, जिसे विभिन्न प्रकार की प्रोग्रामिंग भाषाओं में लागू किया जाता है, और निश्चित रूप से सी। मूल रूप से, ऑपरेटरों &और &&"शॉर्ट सर्किट" यदि पहला तर्क 0 (या NO, nil, आदि) है , जबकि |और ||पहले तर्क 0. नहीं है, तो वही करें । यदि dateपहले आता है beginDate, तो परीक्षण NOकी तुलना किए बिना भी वापस आ जाता है endDate। मूल रूप से, यह आपके कोड के समान ही काम करता है, लेकिन एक पंक्ति में एक बयान में 5 नहीं (या व्हॉट्सएप के साथ 7)।

यह रचनात्मक इनपुट के रूप में अभिप्रेत है, क्योंकि जब प्रोग्रामर अपनी विशेष प्रोग्रामिंग भाषा को तार्किक अभिव्यक्तियों का मूल्यांकन करने के तरीके को समझते हैं, तो वे दक्षता के बारे में बिना अधिक प्रभावी ढंग से उनका निर्माण कर सकते हैं। हालांकि, एक जैसे परीक्षण कर रहे हैं होगा कम कुशल हो, सभी ऑपरेटरों नहीं शॉर्ट सर्किट के बाद से। (वास्तव में, अधिकांश शॉर्ट-सर्किट नहीं कर सकते हैं , जैसे संख्यात्मक तुलना ऑपरेटर।) जब संदेह है, तो अपने तर्क को तोड़ने में स्पष्ट होना हमेशा सुरक्षित होता है, लेकिन जब आप भाषा / संकलक को छोटी चीजों को संभालने देते हैं तो कोड अधिक पठनीय हो सकता है। तुम्हारे लिए।


1
समझा जा सकता। मुझे पता नहीं था कि ऑब्जेक्टिव-सी शॉर्ट-सर्किट मूल्यांकन होगा। मैं उस पर अपना शब्द लूँगा जो वह करता है। मेरे लिए वह सही करने के लिए धन्यवाद। मुझे लगता है कि मैं आपको सही के रूप में चिह्नित करूंगा क्योंकि आपका उत्तर मेरे खुद के मुकाबले अधिक संक्षिप्त है ... और मैंने कुछ सीखा :)
ब्रुक वुल्फ

इसके लिए अपना शब्द लेने की आवश्यकता नहीं है - मैं सिद्धांत "विश्वास, लेकिन सत्यापित करता हूं" की वकालत करता हूं (धन्यवाद, रोनाल्ड रीगन!) यदि केवल मेरी जिज्ञासा को संतुष्ट करने के लिए और कुछ काम करता है और नहीं करता है की सीमा जानने के लिए। आप इसे दो तरीकों की && के द्वारा सत्यापित कर सकते हैं कि लॉग इन करने पर वे क्या कहते हैं; आप ध्यान देंगे कि यदि पहले वाला 0 देता है, तो दूसरा कभी नहीं बुलाया जाएगा।
क्विन टेलर

7

ब्रिक वुल्फ संस्करण स्विफ्ट में:

extension NSDate
{
    func isBetweenDates(beginDate: NSDate, endDate: NSDate) -> Bool
    {
        if self.compare(beginDate) == .OrderedAscending
        {
            return false
        }

        if self.compare(endDate) == .OrderedDescending
        {
            return false
        }

        return true
    }
}

4

यदि आप जानना चाहते हैं कि वर्तमान तिथि दो दिए गए बिंदुओं के बीच में घटती है (9AM - 7/1/09 पर 5PM), तो NSCalendar और NSDateCompords का उपयोग करके इच्छित समय के लिए NSDate उदाहरण बनाएं और वर्तमान तिथि के साथ उनकी तुलना करें।

यदि आप जानना चाहते हैं कि क्या वर्तमान तारीख हर दिन इन दो घंटों के बीच आती है, तो आप शायद दूसरे रास्ते पर जा सकते हैं। NSDateCompords ऑब्जेक्ट को NSCalendar और अपने NSDate के साथ बनाएं और घंटे के घटकों की तुलना करें।


4

यदि आप iOS 10.0 + / macOS 10.12+ को लक्षित कर सकते हैं, तो DateIntervalकक्षा का उपयोग करें ।

सबसे पहले, एक शुरुआत और समाप्ति तिथि के साथ एक तिथि अंतराल बनाएं:

let start: Date = Date()
let middle: Date = Date()
let end: Date = Date()

let dateInterval: DateInterval = DateInterval(start: start, end: end)

फिर, जाँच करें कि क्या दिनांक अंतराल containsमें है DateInterval:

let dateIsInInterval: Bool = dateInterval.contains(middle) // true

3

इसे तिथियों के समय अंतराल का उपयोग करके आसानी से पूरा किया जा सकता है, जैसे:

const NSTimeInterval i = [date timeIntervalSinceReferenceDate];
return ([startDate timeIntervalSinceReferenceDate] <= i &&
        [endDate timeIntervalSinceReferenceDate] >= i);

3

क्विन और ब्रोक्स के समाधानों के साथ जारी रखते हुए, NSDate कार्यान्वयन को कम करने के लिए बहुत अच्छा है, इसलिए इसका उपयोग हर जगह किया जा सकता है:

-(BOOL) isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {
    return (([self compare:beginDate] != NSOrderedAscending) && ([self compare:endDate] != NSOrderedDescending));
}

और आपके कोड के किसी भी भाग पर आप इसका उपयोग कर सकते हैं:

[myNSDate isBetweenDate:thisNSDate andDate:thatNSDate];

(myNSDate, thisNSDate और thatNSDate बेशक NSDates हैं)


3

इस समस्या का बेहतर और अधिक समाधान है।

extention Date {
    func isBetween(from startDate: Date,to endDate: Date) -> Bool {
        let result = (min(startDate, endDate) ... max(startDate, endDate)).contains(self)
        return result
    }
}

तब आप इसे इस तरह कह सकते हैं।

todayDate.isBetween(from: startDate, to: endDate)

यहां तक ​​कि आप डेट को रैंडम पास कर सकते हैं क्योंकि यह एक्सटेंशन चेक करता है कि कौन सा न्यूनतम है और कौन सा नहीं।

आप इसे स्विफ्ट 3 और इसके बाद के संस्करण में उपयोग कर सकते हैं।


2

स्विफ्ट 5 के साथ, आप नीचे दो समाधानों में से एक का उपयोग कर सकते हैं ताकि यह जांचा जा सके कि कोई तिथि दो अन्य तिथियों के बीच है या नहीं।


# 1। का उपयोग करते हुए DateIntervalकी contains(_:)विधि

DateIntervalनामक एक विधि है contains(_:)contains(_:)निम्नलिखित घोषणा है:

func contains(_ date: Date) -> Bool

इंगित करता है कि क्या इस अंतराल में दी गई तारीख शामिल है।

निम्न खेल का मैदान कोड दिखाता है कि contains(_:)दो अन्य तिथियों के बीच एक तिथि होने की जाँच करने के लिए कैसे उपयोग किया जाए:

import Foundation

let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let myDate = calendar.date(from: DateComponents(year: 2012, month: 8, day: 15))!

let dateInterval = DateInterval(start: startDate, end: endDate)
let result = dateInterval.contains(myDate)
print(result) // prints: true

# 2। का उपयोग करते हुए ClosedRangeकी contains(_:)विधि

ClosedRangeनामक एक विधि है contains(_:)contains(_:)निम्नलिखित घोषणा है:

func contains(_ element: Bound) -> Bool

एक बूलियन मान लौटाता है जो दर्शाता है कि दिया गया तत्व सीमा के भीतर निहित है या नहीं।

निम्न खेल का मैदान कोड दिखाता है कि contains(_:)दो अन्य तिथियों के बीच एक तिथि होने की जाँच करने के लिए कैसे उपयोग किया जाए:

import Foundation

let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let myDate = calendar.date(from: DateComponents(year: 2012, month: 8, day: 15))!

let range = startDate ... endDate
let result = range.contains(myDate)
//let result = range ~= myDate // also works
print(result) // prints: true

-1

स्विफ्ट में बेहतर संस्करण:

@objc public class DateRange: NSObject {
    let startDate: Date
    let endDate: Date

    init(startDate: Date, endDate: Date) {
        self.startDate = startDate
        self.endDate = endDate
    }

    @objc(containsDate:)
    func contains(_ date: Date) -> Bool {
        let startDateOrder = date.compare(startDate)
        let endDateOrder = date.compare(endDate)
        let validStartDate = startDateOrder == .orderedAscending || startDateOrder == .orderedSame
        let validEndDate = endDateOrder == .orderedDescending || endDateOrder == .orderedSame
        return validStartDate && validEndDate
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.