आज NSDate प्राप्त करें, कल, यह सप्ताह, अंतिम सप्ताह, यह महीना, अंतिम महीना… चर


86

मैं कोशिश कर रहा हूँ कि आज NSDate, कल, इस सप्ताह, अंतिम सप्ताह, इस महीने, पिछले महीने के चरों को यूआईटेबल व्यू के शीर्षकफेयरइंटरइन में जोड़े जाने के लिए तैयार किया जाए।

जो मैं चाहता हूं, वह 2009-12-11 की तारीख के लिए नीचे दिए गए कोड में मैन्युअल रूप से किया गया है

 NSDate *today = [NSDate dateWithString:@"2009-12-11 00:00:00 +0000"];
 NSDate *yesterday = [NSDate dateWithString:@"2009-12-10 00:00:00 +0000"];
 NSDate *thisWeek = [NSDate dateWithString:@"2009-12-06 00:00:00 +0000"];
 NSDate *lastWeek = [NSDate dateWithString:@"2009-11-30 00:00:00 +0000"];
 NSDate *thisMonth = [NSDate dateWithString:@"2009-12-01 00:00:00 +0000"];
 NSDate *lastMonth = [NSDate dateWithString:@"2009-11-01 00:00:00 +0000"];

जवाबों:


93

दिनांक और समय प्रोग्रामिंग गाइड से अनुकूलित :

// Right now, you can remove the seconds into the day if you want
NSDate *today = [NSDate date];

// All intervals taken from Google
NSDate *yesterday = [today dateByAddingTimeInterval: -86400.0];
NSDate *thisWeek  = [today dateByAddingTimeInterval: -604800.0];
NSDate *lastWeek  = [today dateByAddingTimeInterval: -1209600.0];

// To get the correct number of seconds in each month use NSCalendar
NSDate *thisMonth = [today dateByAddingTimeInterval: -2629743.83];
NSDate *lastMonth = [today dateByAddingTimeInterval: -5259487.66];

यदि आप महीने के आधार पर दिनों की सही सही संख्या चाहते हैं, तो आपको एक का उपयोग करना चाहिए NSCalendar


77
समय के लिए स्थिर स्थिरांक BAD BAD BAD हैं। लीप दिन या लीप सेकंड के बारे में क्या? NSDateCompords का उपयोग करें या आप कुछ बहुत बुरा और कठिन मुद्दों पर बहस करने के लिए जब आपकी तारीख टिकटों का मिलान शुरू कर देंगे।
केंडल हेल्मसटेटर गेलनर

11
यह वास्तव में बुरा नहीं है यदि आप बस पिछले सप्ताह के लायक मूल्य या जो कुछ भी चाहते हैं। मैंने निर्दिष्ट किया कि NSCalendarयदि आवश्यक हो तो ओपी का उपयोग करना चाहिए ।
बेन एस

2
निश्चित स्थिरांक वास्तव में सिर्फ गिनती के दिनों के लिए ठीक होना चाहिए: हर दिन 86400 सेकंड है। लीप सेकंड केवल दो बार लंबे समय तक ले जाते हैं - एक छलांग के साथ एक दिन अभी भी 86400 'सेकंड' है। महीने के लिए ... हाँ साफ साफ :)
क्रिस

3
@Chris को छोड़कर जब दिन 86400 सेकंड नहीं होते हैं। दिन के उजाले बचत समय के बारे में क्या? यह महत्वहीन लगता है, लेकिन यह वास्तव में आपको सुपर गार्नी बग्स तक ले जा सकता है, जहां से बाहर नहीं निकलता है जब डीएसटी हिट होता है और आपको इसे ध्यान में रखना याद नहीं था।
jpswain

1
यदि आप केवल 7 दिन लगभग वापस जाना चाहते हैं, तो आप समय को घटा सकते हैं, यदि आप इस सप्ताह के 'सोमवार' पर वापस जाना चाहते हैं, तो NSCalendar का उपयोग करें। दोनों परिदृश्यों के लिए उपयोग के मामले हैं।
जॉनी रॉकएक्स

83

यह लिखने का एक बेहतर तरीका हो सकता है, लेकिन यहां मैं बेन के NSCalendar सुझाव पर आया हूं और वहां से काम कर रहा हूँ

NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond ) fromDate:[[NSDate alloc] init]];

[components setHour:-[components hour]];
[components setMinute:-[components minute]];
[components setSecond:-[components second]];
NSDate *today = [cal dateByAddingComponents:components toDate:[[NSDate alloc] init] options:0]; //This variable should now be pointing at a date object that is the start of today (midnight);

[components setHour:-24];
[components setMinute:0];
[components setSecond:0];
NSDate *yesterday = [cal dateByAddingComponents:components toDate: today options:0];

components = [cal components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:[[NSDate alloc] init]];

[components setDay:([components day] - ([components weekday] - 1))]; 
NSDate *thisWeek  = [cal dateFromComponents:components];

[components setDay:([components day] - 7)];
NSDate *lastWeek  = [cal dateFromComponents:components];

[components setDay:([components day] - ([components day] -1))]; 
NSDate *thisMonth = [cal dateFromComponents:components];

[components setMonth:([components month] - 1)]; 
NSDate *lastMonth = [cal dateFromComponents:components];

NSLog(@"today=%@",today);
NSLog(@"yesterday=%@",yesterday);
NSLog(@"thisWeek=%@",thisWeek);
NSLog(@"lastWeek=%@",lastWeek);
NSLog(@"thisMonth=%@",thisMonth);
NSLog(@"lastMonth=%@",lastMonth);

13
आप उन fromDate:[[NSDate alloc] init]बिट्स के साथ स्मृति को लीक कर रहे हैं ।
झबरा मेंढक

21
@ शागिर्द मेंढक: मुझे लगता है कि वह मान रहा है कि एआरसी सक्षम है ...?)
ओर्ज

3
यह कोड सही ढंग से काम नहीं करता है। यह एक दूसरे के अंशों को ध्यान में नहीं रखता है जो इनपुट तिथि का हिस्सा हैं। यानी, तारीख 30.1234 सेकंड हो सकती है और NSDateCompords के पास केवल 30 सेकंड के मूल्य हैं इसलिए NSDate से 30 सेकंड घटाकर आपको आधी रात को 0.1234 सेकंड के साथ छोड़ देता है। इसके अलावा, कुछ दिनों में 24 घंटे (दिन के उजाले की बचत) से अधिक (या कम) होता है, इसलिए कल की तारीख प्राप्त करने के लिए वास्तव में [घटकों setDay: -1] का उपयोग करना चाहिए बजाय [घटकों setHour: -24]।
orj

5
@orj FYI करें, ARC ने जवाब आने के बाद उम्र बताई
Shaggy Frog

3
@orj इसके अलावा, दिन के समय की बचत के समय में परिवर्तन, घंटों को घटाकर आपको मध्यरात्रि नहीं देता है। -1। यह कोड 35 अपवोट के लायक नहीं है।
निकोलाई रुहे

40

NSDateCompords आज प्राप्त करने के लिए अच्छा है:

NSCalendar *cal = [NSCalendar currentCalendar];

NSDate *date = [NSDate date];
NSDateComponents *comps = [cal components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) 
                                                          fromDate:date];
NSDate *today = [cal dateFromComponents:comps];

यह केवल वर्ष, माह और दिनांक के साथ एक NSDate बनाता है:

(gdb) po today
2010-06-22 00:00:00 +0200

कल प्राप्त करने के लिए, आप NSDateCompords का उपयोग करके इसकी गणना कर सकते हैं:

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:-1];
NSDate *yesterday = [cal dateByAddingComponents:components toDate:today options:0];

क्या आपको युग घटक शामिल करने की आवश्यकता नहीं है?
क्रिस पेज

अच्छा लगा। अतीत में 8 साल की तारीख की गणना करने के लिए इसका इस्तेमाल किया और यह अच्छी तरह से काम करता है। बस यहाँ एक रिसाव को ठीक करने की आवश्यकता है: [[NSDateCompords आवंटित] init];
क्रेग बी

@ क्रेगब धन्यवाद। इसका पूरा उदाहरण नहीं है। स्पष्ट स्मृति प्रबंधन को पाठक के लिए एक चुनौती के रूप में छोड़ दिया;)
ईसाई बीयर

@ChrisPage युग घटक? किस लिए?
क्रिश्चियन बीयर

1
@ChristianBeer मुझे पूरा यकीन है कि वांछित रिज़ॉल्यूशन से बड़े सभी घटकों पर विचार किया जाना चाहिए। मेरा मानना ​​है कि (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)होना चाहिए (NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
क्रिस पेज

19
+ (NSDate*)dateFor:(enum DateType)dateType {

    NSCalendar *calendar = [NSCalendar currentCalendar];

    NSDateComponents *comps =
    [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
                fromDate:[NSDate date]];

    if(dateType == DateYesterday) {

        comps.day--;
    }
    else if(dateType == DateThisWeek) {

        comps.weekday = 1;
    }
    else if(dateType == DateLastWeek) {

        comps.weekday = 1;
        comps.week--;
    }
    else if(dateType == DateThisMonth) {

        comps.day = 1;
    }
    else if(dateType == DateLastMonth) {

        comps.day = 1;
        comps.month--;
    }
    else if(dateType != DateToday)
        return nil;

    return [calendar dateFromComponents:comps];
}

क्या आपको युग घटक शामिल करने की आवश्यकता नहीं है?
क्रिस पेज

मुझे NSDayCalendarUnit को निकालना पड़ा और DateLeekWeek की गणना करते समय NSWeekdayCalendarUnit को जोड़ना पड़ा।
jessecurry

Apple ने NSWeekdayCalendarUnit और NSDayCalendarUnit की परिभाषा को iOS 5.0 के आसपास बदल दिया। नया तरीका NSWeekdayCalendarUnit का उपयोग करना है। लेकिन पुराने संस्करणों पर आपको NSDayCalendarUnit का उपयोग करना चाहिए। यह एक गड़बड़ है ...
डस्टिन

@ नई इकाइयों को अपडेट करते समय भी यह काम नहीं करता है ... उदाहरण के लिए DateThisWeek, कार्यदिवस की स्थापना के लिए NSDate पर प्रभाव नहीं पड़ता है ...
AnthoPak

11

स्विफ्ट 4.2

let today = Date()
let yesterday = today.addingTimeInterval(-86400.0)
let thisWeek = today.addingTimeInterval(-604800.0)
let lastWeek = today.addingTimeInterval(-1209600.0)

let thisMonth = today.addingTimeInterval(-2629743.83)
let lastMonth = today.addingTimeInterval(-5259487.66)

// components of the date
let calendar = Calendar(identifier: Calendar.Identifier.gregorian)
let components = calendar.dateComponents([.year, .month, .day], from: today)
let (year, month, day) = (components.year, components.month, components.day)

कृपया ध्यान दें कि दिनांक घटक वैकल्पिक हैं।


1
@ फेंग कुआं, आज २ 2016 जून २०१६, दोपहर १ बजे २, जून २०१६ होगा और अगर मैं २४ घंटे घटा दूं तो तारीख २ date जून १ बजे होगी। क्या बात है कि मैं चूक गया?
गोखानकुटर्ट

1
क्षमा करें, @gokhanakkurt। मुझे लगता है कि मेरे मन की कुछ अड़चनें थीं। आपका उत्तर सही है
fengd

4

अन्य उत्तर सिर्फ मेरे लिए काम नहीं करते थे (शायद मेरे समय क्षेत्र के कारण)। यह मेरा इसे करने का तरीका है:

- (BOOL)isOnThisWeek:(NSDate *)dateToCompare
{
    NSCalendar * calendar = [NSCalendar currentCalendar];
    NSDate     * today    = [NSDate date];

    int todaysWeek        = [[calendar components: NSWeekCalendarUnit fromDate:today] week];
    int dateToCompareWeek = [[calendar components: NSWeekCalendarUnit fromDate:dateToCompare] week];

    int todaysYear         = [[calendar components:NSYearCalendarUnit fromDate:today] year];
    int dateToCompareYear  = [[calendar components:NSYearCalendarUnit fromDate:dateToCompare] year];

    if (todaysWeek == dateToCompareWeek && todaysYear == dateToCompareYear) {
        return YES;
    }

    return NO;
}

4

यदि आप iOS 10+ या MacOS 10.12+ का उपयोग कर रहे हैं, तो आप Calendarइसे ठीक से करने के लिए इन दो विधियों का उपयोग कर सकते हैं ।

  • func date(byAdding component: Calendar.Component, value: Int, to date: Date, wrappingComponents: Bool = default) -> Date?( डॉक्स )
  • func dateInterval(of component: Calendar.Component, for date: Date) -> DateInterval?( डॉक्स )

मेरे समय क्षेत्र में खेल के मैदान के उत्पादन के साथ, स्विफ्ट 3 में इन विधियों का उपयोग कैसे करें, इसका एक उदाहरण यहां दिया गया है।

let calendar = Calendar.current
let now = Date()
// => "Apr 28, 2017, 3:33 PM"

let yesterday = calendar.date(byAdding: .day, value: -1, to: now)
// => "Apr 29, 2017, 3:33 PM"
let yesterdayStartOfDay = calendar.startOfDay(for: yesterday!)
// => ""Apr 29, 2017, 12:00 AM"

let thisWeekInterval = calendar.dateInterval(of: .weekOfYear, for: now)
// => 2017-04-23 04:00:00 +0000 to 2017-04-30 04:00:00 +0000

let thisMonthInterval = calendar.dateInterval(of: .month, for: now)
// => 2017-04-01 04:00:00 +0000 to 2017-05-01 04:00:00 +0000

let aDateInLastWeek = calendar.date(byAdding: .weekOfYear, value: -1, to: now)
let lastWeekInterval = calendar.dateInterval(of: .weekOfYear, for: aDateInLastWeek!)
// => 2017-04-16 04:00:00 +0000 to 2017-04-23 04:00:00 +0000

let aDateInLastMonth = calendar.date(byAdding: .month, value: -1, to: now)
let lastMonthInterval = calendar.dateInterval(of: .weekOfYear, for: aDateInLastMonth!)
// => 2017-03-26 04:00:00 +0000 to 2017-04-02 04:00:00 +0000

बोनस: आप DateIntervalपरीक्षण के लिए उपयोग कर सकते हैं कि कोई तिथि उस सीमा में आती है या नहीं। ऊपर से जारी:

thisWeekInterval!.contains(now)
// => true
lastMonthInterval!.contains(now)
// => false

ऐसा क्यों है कि yesterdayअप्रैल 29 nowकहता है और अप्रैल 28 कहता है?
जुआन बोरो

1
NSDate *today = [NSDate date]; // Today's date
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents =[gregorian componentsNSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];
NSInteger day = [weekdayComponents day];

0

मुझे वास्तव में इस परियोजना में शामिल THCalendarInfo ऑब्जेक्ट पसंद है:

http://github.com/jaredholdcroft/kcalendar

मुझे मूल नहीं मिल रहा है। इस ऑब्जेक्ट का उपयोग करके आप पिछले दिन, एक सप्ताह की शुरुआत, एक महीने की शुरुआत, एक सप्ताह का दिन, एक महीने का दिन ... आदि प्राप्त कर सकते हैं।


0
NSDate *today = [[NSDate alloc] initWithTimeIntervalSinceNow:0];

14
क्यों नहीं [NSDate date]?
जोशापुल

चूंकि दोनों वर्तमान तिथि प्राप्त करने के लिए मान्य हैं, दोनों में समय शामिल है। तो यह सवाल का सही समाधान नहीं है!
ईसाई बीयर

0

यह जांच के लिए है कि यह तारीख इस महीने है या नहीं

func isOnThisMonth(dateToCompare: NSDate) -> Bool {
    let calendar: NSCalendar = NSCalendar.currentCalendar()
    let today: NSDate = NSDate()
    let todaysWeek: Int = calendar.components(NSCalendarUnit.Month, fromDate: today).month
    let dateToCompareWeek: Int = calendar.components(.Month, fromDate: dateToCompare).month
    let todaysYear: Int = calendar.components(NSCalendarUnit.Year, fromDate: today).year
    let dateToCompareYear: Int = calendar.components(NSCalendarUnit.Year, fromDate: dateToCompare).year
    if todaysWeek == dateToCompareWeek && todaysYear == dateToCompareYear {
        return true
    }
    return false
}

और दूसरा इस तरह से कमजोर के लिए केवल कैलेंडर प्रकार का परिवर्तन करें

func isOnThisWeek(dateToCompare: NSDate) -> Bool {
    let calendar: NSCalendar = NSCalendar.currentCalendar()
    let today: NSDate = NSDate()
    let todaysWeek: Int = calendar.components(NSCalendarUnit.Weekday, fromDate: today).weekday
    let dateToCompareWeek: Int = calendar.components(.Weekday, fromDate: dateToCompare).weekday
    let todaysYear: Int = calendar.components(NSCalendarUnit.Year, fromDate: today).year
    let dateToCompareYear: Int = calendar.components(NSCalendarUnit.Year, fromDate: dateToCompare).year
    if todaysWeek == dateToCompareWeek && todaysYear == dateToCompareYear {
        return true
    }
    return false
}

मुझे आशा है कि यह किसी के लिए उपयोगी है धन्यवाद।


0

मैंने पहले से ही इसी तरह के सवाल का जवाब दिया और यहां बताया कि मेरा जवाब बेहतर क्यों है:

  • स्विफ्ट 3 !
  • DateFormatter के "कल" ​​और "टुडे" का उपयोग करता है। यह पहले से ही Apple द्वारा अनुवादित है, जो आपको काम बचाता है!
  • डेटकॉर्पोरेटफॉरमैटर का पहले से अनुवादित "1 सप्ताह" स्ट्रिंग का उपयोग करता है। (फिर से आपके लिए कम काम, Apple के सौजन्य से।) आपको बस इतना करना है "% @ पहले" स्ट्रिंग। 🙂
  • अन्य उत्तर गलत तरीके से उस समय की गणना करते हैं जब दिन "आज" से "कल" ​​तक आदि पर स्थिर होता है। स्थिर स्थिरांक एक बड़ा NO-NO कारण हैं । साथ ही, अन्य उत्तर वर्तमान तिथि / समय का उपयोग करते हैं जब उन्हें वर्तमान दिन के अंत का उपयोग करना चाहिए तिथि / समय ।
  • कैलेंडर और स्थान के लिए autoupdatingCurrent का उपयोग करता है जो यह सुनिश्चित करता है कि आपका ऐप सेटिंग में उपयोगकर्ता के कैलेंडर और भाषा वरीयताओं के साथ तुरंत अपडेट है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.