سؤال

ما خيار SetDateFormat ل NSDateFormatter يمكنني استخدامه للحصول على لاحقة ترتيبية لمدة شهر؟

مثل المقتطف أدناه ينتج حاليا:
3:11 مساء السبت 15 أغسطس

ماذا يجب أن أتغير للحصول على:
3:11 مساء السبت 15 أغسطسذ

NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"h:mm a EEEE MMMM d"];
NSString *dateString = [dateFormatter stringFromDate:date]; 
NSLog(@"%@", dateString);

في PHP، كنت أستخدم هذا الأمر أعلاه:
<?php echo date('h:m A l F jS') ?>

هل هناك nsdateformatter يعادل س الخيار في سلسلة تنسيق PHP؟

هل كانت مفيدة؟

المحلول 2

NSDate *date = [NSDate date];
NSDateFormatter *prefixDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[prefixDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[prefixDateFormatter setDateFormat:@"h:mm a EEEE MMMM d"];
NSString *prefixDateString = [prefixDateFormatter stringFromDate:date];
NSDateFormatter *monthDayFormatter = [[[NSDateFormatter alloc] init] autorelease];
[monthDayFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[monthDayFormatter setDateFormat:@"d"];     
int date_day = [[monthDayFormatter stringFromDate:date] intValue];  
NSString *suffix_string = @"|st|nd|rd|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|st|nd|rd|th|th|th|th|th|th|th|st";
NSArray *suffixes = [suffix_string componentsSeparatedByString: @"|"];
NSString *suffix = [suffixes objectAtIndex:date_day];   
NSString *dateString = [prefixDateString stringByAppendingString:suffix];   
NSLog(@"%@", dateString);

نصائح أخرى

لم تكن أي من هذه الإجابات مزحة جماليا مثل ما أستخدمه، لذلك اعتقدت أنني سأشارك:


SWIFT 3:

func daySuffix(from date: Date) -> String {
    let calendar = Calendar.current
    let dayOfMonth = calendar.component(.day, from: date)
    switch dayOfMonth {
    case 1, 21, 31: return "st"
    case 2, 22: return "nd"
    case 3, 23: return "rd"
    default: return "th"
    }
}

ج موضوعية:

- (NSString *)daySuffixForDate:(NSDate *)date {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSInteger dayOfMonth = [calendar component:NSCalendarUnitDay fromDate:date];
    switch (dayOfMonth) {
        case 1:
        case 21:
        case 31: return @"st";
        case 2:
        case 22: return @"nd";
        case 3:
        case 23: return @"rd";
        default: return @"th";
    }
}

من الواضح أن هذا يعمل فقط للغة الإنجليزية.

هذا يتم القيام به بسهولة اعتبارا من iOS9.

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterOrdinalStyle;
NSArray<NSNumber *> *numbers = @[@1, @2, @3, @4, @5];

for (NSNumber *number in numbers) {
    NSLog(@"%@", [formatter stringFromNumber:number]);
}
// "1st", "2nd", "3rd", "4th", "5th"

مأخوذ من nshipster.

SWIFT 2.2:

let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .OrdinalStyle
let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for number in numbers {
    print(numberFormatter.stringFromNumber(number)!)
}

إليك تنفيذ آخر لطريقة لتوليد لاحقة. إن اللواحق التي تنتجها صالحة فقط باللغة الإنجليزية وقد لا تكون صحيحة بلغات أخرى:

- (NSString *)suffixForDayInDate:(NSDate *)date
{
    NSInteger day = [[[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] components:NSDayCalendarUnit fromDate:date] day];
    if (day >= 11 && day <= 13) {
        return @"th";
    } else if (day % 10 == 1) {
        return @"st";
    } else if (day % 10 == 2) {
        return @"nd";
    } else if (day % 10 == 3) {
        return @"rd";
    } else {
        return @"th";
    }
}

تاريخ التوافق على Mac OS 10.5 واستخدام iPhone TR35. كمعيار محدد تنسيقها. لا يسمح هذا المواصين بمثل هذا اللاحقة في أي تاريخ؛ إذا كنت تريد واحدة، فسيتعين عليك توليدها بنفسك.

إجابة مات أندرسن هي توضيح تماما، وكذلك Sdjmchattie. لكن NSDateFormatter ثقيل للغاية على وحدة المعالجة المركزية وإذا استدعيت هذا 100x، فأنت ترى حقا التأثير، لذلك إليك حل مشترك مشتق من الإجابات أعلاه. (يرجى ملاحظة أن ما سبق لا يزال صحيحا)

nsdateformatter هو كافيلي غالي الثمن لنصنع او لنبتكر. خلق بمجرد و إعادة استخدام, ، ولكن احذر: انها ليست آمنة الخيط، لذلك واحدة لكل موضوع.

افترض self.date = [تاريخ nsdate]؛

   - (NSString *)formattedDate{

    static NSDateFormatter *_dateFormatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _dateFormatter = [[NSDateFormatter alloc] init];
        _dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
        _dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
    });

    _dateFormatter.dateFormat = [NSString stringWithFormat:@"h:mm a EEEE MMMM d'%@'", [self suffixForDayInDate:self.date]];
   NSString *date = [_dateFormatter stringFromDate:self.date];

    return date;
}

/ * رمز SDJMCHATTIE، هذا أكثر ملاءمة من استخدام صفيف * /

- (NSString *)suffixForDayInDate:(NSDate *)date{
    NSInteger day = [[[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] components:NSDayCalendarUnit fromDate:date] day];
    if (day >= 11 && day <= 13) {
        return @"th";
    } else if (day % 10 == 1) {
        return @"st";
    } else if (day % 10 == 2) {
        return @"nd";
    } else if (day % 10 == 3) {
        return @"rd";
    } else {
        return @"th";
    }
}

الإخراج: 3:11 مساء السبت 15 أغسطس

هذا سيعطي سلسلة بالتنسيق "10:10 مساء السبت، 2 أغسطس"

   -(NSString*) getTimeInString:(NSDate*)date
    {
        NSString* string=@"";
        NSDateComponents *components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay fromDate:date];

        if(components.day == 1 || components.day == 21 || components.day == 31){
             string = @"st";
        }else if (components.day == 2 || components.day == 22){
            string = @"nd";
        }else if (components.day == 3 || components.day == 23){
             string = @"rd";
        }else{
             string = @"th";
        }

        NSDateFormatter *prefixDateFormatter = [[NSDateFormatter alloc] init];    [prefixDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
        [prefixDateFormatter setDateFormat:[NSString stringWithFormat:@"h:mm a EEEE, d'%@' MMMM",string]];

        NSString *dateString = [prefixDateFormatter stringFromDate:date];

        return dateString;
    }

سيؤدي ذلك إلى القيام بالتنسيق في خطوتين: أولا، قم بإنشاء سلسلة فرعية هي اليوم مع لاحقة مناسبة، ثم قم بإنشاء سلسلة تنسيق للأجزاء المتبقية، وتوصيلها في اليوم المنسق بالفعل.

func ordinalDate(date: Date) -> String {
    let ordinalFormatter = NumberFormatter()
    ordinalFormatter.numberStyle = .ordinal
    let day = Calendar.current.component(.day, from: date)
    let dayOrdinal = ordinalFormatter.string(from: NSNumber(value: day))!

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "h:mm a EEEE MMMM '\(dayOrdinal)'"
    return dateFormatter.string(from: Date())
}

منذ يوم الترتيبي مبنية من قبل NumberFormatter, ، يجب أن تعمل بجميع اللغات، وليس الإنجليزية فقط.

يمكنك الحصول على سلسلة تنسيق أمرت للمطانية الحالية عن طريق استبدال المهمة dateFormat مع هذا:

dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "h:mm a EEEE MMMM d", options: 0, locale: dateFormatter.locale)?.replacingOccurrences(of: "d", with: "'\(dayOrdinal)'")

ملاحظة النصيحة من العديد من الآخرين الذين يقومون بإنشاء تكوينات مكلفة، لذلك يجب عليك التخزين المؤقت وإعادة استخدامها في التعليمات البرمجية التي تسمى بشكل متكرر.

تم تنفيذ هذا بالفعل في الأساس.

let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .ordinal
numberFormatter.locale = Locale.current

numberFormatter.string(for: 1) //Should produce 1st
numberFormatter.string(for: 2) //Should produce 2nd
numberFormatter.string(for: 3) //Should produce 3rd
numberFormatter.string(for: 4) //Should produce 4th

أو إذا كنت تريد لاحقة عن أي رقم:

extension Int {

    public func suffix() -> String {
        let absSelf = abs(self)

        switch (absSelf % 100) {

        case 11...13:
            return "th"
        default:
            switch (absSelf % 10) {
            case 1:
                return "st"
            case 2:
                return "nd"
            case 3:
                return "rd"
            default:
                return "th"
            }
        }
    }
}

التفكير في أن هناك 5 إمكانيات للأرقام الإيجابية. إنه رقم المرتبة الأولى هو 1 كونها "st". إنه رقم المرتبة الثانية هو 2 كونها "2nd". إنه رقم المركز الثالث هو 3 كونه "RD". أي حالة أخرى هي "TH"، أو إذا كان رقم المرتبة الثانية هو 1، فإن القواعد المذكورة أعلاه لا تنطبق وهي "عشر".

يعطينا Modulo 100 رقمين آخرين رقمين، حتى نتمكن من التحقق من 11 إلى 13. modulo 10 يعطينا الرقم الأخير من الرقم، حتى نتمكن من التحقق من 1، 2، 3 إذا لم يتم القبض عليه بنفس الشرط الأول.

جرب هذا التمديد في الملاعب:

let a = -1 

a.suffix() // "st"

let b = 1112 

b.suffix() // "th"

let c = 32 

c.suffix() // "nd"

أحب أن أرى ما إذا كانت هناك طريقة أقصر لكتابة هذا باستخدام العمليات الثنائية و / أو صفيف!

   - (void)viewDidLoad
{ 
  NSDate *date = [NSDate date];
        NSDateFormatter *prefixDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
        [prefixDateFormatter setDateFormat:@"yyy-dd-MM"];
        date = [prefixDateFormatter dateFromString:@"2014-6-03"]; //enter yourdate
        [prefixDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
        [prefixDateFormatter setDateFormat:@"EEEE MMMM d"];

        NSString *prefixDateString = [prefixDateFormatter stringFromDate:date];

        NSDateFormatter *monthDayFormatter = [[[NSDateFormatter alloc] init] autorelease];
        [monthDayFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];

        [monthDayFormatter setDateFormat:@"d"];
        int date_day = [[monthDayFormatter stringFromDate:date] intValue];
        NSString *suffix_string = @"|st|nd|rd|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|st|nd|rd|th|th|th|th|th|th|th|st";
        NSArray *suffixes = [suffix_string componentsSeparatedByString: @"|"];
        NSString *suffix = [suffixes objectAtIndex:date_day];
        NSString *dateString = [prefixDateString stringByAppendingString:suffix];
        NSLog(@"%@", dateString);

}

لا يستخدم أي من الإجابات نمط الأرقام الترتيبي الموجودة بالفعل في عدد هتكف في SWIFT.

    var dateString: String {
       let calendar = Calendar.current
       let dateComponents = calendar.component(.day, from: date)
       let numberFormatter = NumberFormatter()
       numberFormatter.numberStyle = .ordinal
       let day = numberFormatter.string(from: dateComponents as NSNumber)
       let dateFormatter = DateFormatter()
       dateFormatter.dateFormat = "MMM"
       return day! + dateFormatter.string(from: date)
    }

أضفت هاتين الطريقتين إلى NSDate مع إضافات NSDate + فئة.

\- (NSString *)monthDayYear 
{

    NSDateFormatter * dateFormatter = NSDateFormatter.new;
    [dateFormatter setDateFormat:@"MMMM d*, YYYY"];
    NSString *dateString = [dateFormatter stringFromDate:self];

    return [dateString stringByReplacingOccurrencesOfString:@"*" withString:[self ordinalSuffixForDay]];
}

\- (NSString *)ordinalSuffixForDay {

NSDateFormatter * dateFormatter = NSDateFormatter.new;
[dateFormatter setDateFormat:@"d"];
NSString *dateString = [dateFormatter stringFromDate:self];
NSString *suffix = @"th";

if ([dateString length] == 2 && [dateString characterAtIndex:0] == '1') {
    return suffix;
}

switch ([dateString characterAtIndex:[dateString length]-1]) {
    case '1':
        suffix = @"st";
        break;
    case '2':
        suffix = @"nd";
        break;
    case '3':
        suffix = @"rd";
        break;
}

return suffix;
}

يمكنك جعلها أكثر كفاءة من خلال الجمع بينها وفهرسة رقم المرء من اليوم ضمن سلسلة التنسيق الخاصة بك باعتبارها نقطة التبديل. اخترت فصل الوظيفة حتى يتم استدعاء اللاعيم الترتيبي بشكل منفصل لتنسيقات تاريخ مختلفة.

- (NSString *)dayWithSuffixForDate:(NSDate *)date {

    NSInteger day = [[[NSCalendar currentCalendar] components:NSDayCalendarUnit fromDate:date] day];

    NSString *dayOfMonthWithSuffix, *suffix  = nil ;

    if(day>0 && day <=31)
    {

        switch (day)
        {
            case 1:
            case 21:
            case 31: suffix =  @"st";
                break;
            case 2:
            case 22: suffix = @"nd";
                break;
            case 3:
            case 23: suffix = @"rd";
                break;
            default: suffix = @"th";
                break;
        }


            dayOfMonthWithSuffix = [NSString stringWithFormat:@"%ld%@", (long)day , suffix];
    }


    return dayOfMonthWithSuffix;
}

يقول وثائق NSDateFormatter أن جميع خيارات التنسيق التي يدعمها هي المدرجة في TR35..

لماذا تريد ذلك؟ إذا كنت تصنع شيئا لآلة لتحليلها، يجب عليك استخدامها ISO 8601 تنسيق, ، أو RFC 2822 تنسيق إذا كان لديك ل. لا أحد يتطلب أو يسمح لاحقة ترتيبية.

إذا كنت تظهر تواريخ للمستخدم، فيجب عليك استخدام إحدى التنسيقات من إعدادات لغة المستخدم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top