SetDoesRelativeDateFormatting का उपयोग करना: हाँ और setDateFormat: NSDateFormatter के साथ

"आज", "कल", "कल" ​​जैसे सापेक्ष तिथियों के उत्पादन के लिए NSDateFormatter का एक प्यारा समर्थन है जब इन्हें वर्तमान भाषा द्वारा समर्थित किया जाता है। एक बड़ा फायदा यह है कि ये सभी आपके लिए पहले से ही स्थानीयकृत हैं - आपको तारों का अनुवाद करने की आवश्यकता नहीं है।

आप इस कार्यक्षमता को इसके साथ चालू कर सकते हैं:

[dateFormatter setDoesRelativeDateFormatting: YES];

नीचे की तरफ यह है कि यह केवल एक उदाहरण के लिए काम करता प्रतीत होता है जो पूर्वनिर्धारित प्रारूपों में से एक का उपयोग कर रहा है, जैसे कि:

[dateFormatter setDateStyle: NSDateFormatterShortStyle];

यदि आप एक कस्टम प्रारूप का उपयोग करने के लिए डेट फॉर्मेटर सेट अप करते हैं, तो इस तरह:

[dateFormatter setDateStyle: @"EEEE"];

फिर जब आप कॉल करते हैं:

[dateFormatter stringFromDate: date];

... आप बस एक खाली स्ट्रिंग वापस मिल जाएगा।

जब भी संभव हो, मैं रिश्तेदार तार प्राप्त करने में सक्षम होना चाहता हूं, और जब यह नहीं है तो अपने स्वयं के कस्टम प्रारूप का उपयोग करें।

0

2 उत्तर

मैंने NSDateFormatter पर एक श्रेणी स्थापित करने के लिए एक वर्कअराउंड प्रदान किया। एक स्पष्टीकरण कोड का पालन करता है।

NSDateFormatter + RelativeDateFormat.h में:

@interface NSDateFormatter (RelativeDateFormat)
-(NSString*) relativeStringFromDateIfPossible:(NSDate *)date;
@end

NSDateFormatter + RelativeDateFormat.m में:

@implementation NSDateFormatter (RelativeDateFormat)
-(NSString*) relativeStringFromDateIfPossible:(NSDate *)date
{
  static NSDateFormatter *relativeFormatter;
  static NSDateFormatter *absoluteFormatter;

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    const NSDateFormatterStyle arbitraryStyle = NSDateFormatterShortStyle;

    relativeFormatter = [[NSDateFormatter alloc] init];
    [relativeFormatter setDateStyle: arbitraryStyle];
    [relativeFormatter setTimeStyle: NSDateFormatterNoStyle];
    [relativeFormatter setDoesRelativeDateFormatting: YES];

    absoluteFormatter = [[NSDateFormatter alloc] init];
    [absoluteFormatter setDateStyle: arbitraryStyle];
    [absoluteFormatter setTimeStyle: NSDateFormatterNoStyle];
    [absoluteFormatter setDoesRelativeDateFormatting: NO];
  });

  NSLocale *const locale = [self locale];
  if([relativeFormatter locale] != locale)
  {
    [relativeFormatter setLocale: locale];
    [absoluteFormatter setLocale: locale];
  }

  NSCalendar *const calendar = [self calendar];
  if([relativeFormatter calendar] != calendar)
  {
    [relativeFormatter setCalendar: calendar];
    [absoluteFormatter setCalendar: calendar];
  }

  NSString *const maybeRelativeDateString = [relativeFormatter stringFromDate: date];
  const BOOL isRelativeDateString = ![maybeRelativeDateString isEqualToString: [absoluteFormatter stringFromDate: date]];

  if(isRelativeDateString)
  {
    return maybeRelativeDateString;
  }
  else
  {
    return [self stringFromDate: date];
  }
}
@end

यह कैसे काम करता है?

यह एक (मनमाना) मानक प्रारूप का उपयोग कर दो दिनांक स्वरूपण बनाए रखता है। वे समान रूप से प्रारूपित करते हैं सिवाय इसके कि कोई सापेक्ष दिनांक तार प्रदान करेगा और दूसरा नहीं होगा।

दोनों स्वरूपकों के साथ दी गई तारीख को स्वरूपित करके, यह देखना संभव है कि रिश्तेदार दिनांक फ़ॉर्मेटर एक विशेष सापेक्ष दिनांक दे रहा है या नहीं। एक विशेष सापेक्ष तारीख होती है जब दो स्वरूपक अलग परिणाम देते हैं।

  • यदि कोई विशेष सापेक्ष दिनांक स्ट्रिंग है , तो उस विशेष सापेक्ष दिनांक स्ट्रिंग को वापस कर दिया जाता है।
  • यदि कोई विशेष सापेक्ष दिनांक स्ट्रिंग नहीं है मूल स्वरूपक को फ़ॉलबैक के रूप में उपयोग किया जाता है और आपके द्वारा परिभाषित प्रारूप सेटिंग्स का उपयोग किया जाता है।

आप यहां dispatch_once के बारे में अधिक जानकारी प्राप्त कर सकते हैं

एक सीमा ...

कार्यान्वयन उन समय घटकों को संभाल नहीं करता है जिन्हें आपने अपनी प्रारूप स्ट्रिंग में रखा हो। जब कोई सापेक्ष दिनांक स्ट्रिंग उपलब्ध होती है, तो आपके प्रारूप स्टिंग को अनदेखा किया जाता है और आपको सापेक्ष दिनांक स्ट्रिंग मिलती है।

0
जोड़ा
Dispatch_once का उपयोग करने के लिए बदल दिया। धन्यवाद @GreatWiz।
जोड़ा लेखक Benjohn, स्रोत
अच्छा काम। एक फिक्स मैं सुझाव देता हूं कि स्थैतिक स्वरूप बनाने के लिए dispatch_once का उपयोग कर रहा है
जोड़ा लेखक GreatWiz, स्रोत

मैंने सोचा कि @ बेनोज़न कोड का एक तेज संस्करण दूसरों के लिए उपयोगी होगा

extension NSDateFormatter {    
   @nonobjc static let relativeFormatter : NSDateFormatter = {
        let formatter = NSDateFormatter()
        formatter.dateStyle = .MediumStyle
        formatter.timeStyle = .NoStyle
        formatter.doesRelativeDateFormatting = true
        return formatter
    }()

    @nonobjc static let absoluteFormatter : NSDateFormatter = {
        let formatter = NSDateFormatter()
        formatter.dateStyle = .MediumStyle
        formatter.timeStyle = .NoStyle
        formatter.doesRelativeDateFormatting = false
        return formatter
    }()

    func relativeStringFromDateIfPossible(date:NSDate) -> String
    {    
        if NSDateFormatter.relativeFormatter.locale != locale {
            NSDateFormatter.relativeFormatter.locale = locale
            NSDateFormatter.absoluteFormatter.locale = locale
        }

        if NSDateFormatter.absoluteFormatter.calendar != calendar {
            NSDateFormatter.relativeFormatter.calendar = calendar
            NSDateFormatter.absoluteFormatter.calendar = calendar
        }

        let maybeRelativeString = NSDateFormatter.relativeFormatter.stringFromDate(date)
        let absoluteString = NSDateFormatter.absoluteFormatter.stringFromDate(date)

        return (maybeRelativeString != absoluteString ) ? maybeRelativeString : stringFromDate(date)
    }
}
0
जोड़ा
साझा करने के लिए धन्यवाद।
जोड़ा लेखक Benjohn, स्रोत
एक बग फिक्स के साथ संपादित
जोड़ा लेखक GreatWiz, स्रोत