nil nsdate عند محاولة الحصول على تاريخ من سلسلة UTC في الوقت الزولو

StackOverflow https://stackoverflow.com/questions/1263455

سؤال

كتابة تطبيق iPhone في Objective-C، لدي تاريخ في نموذج السلسلة (بتنسيق UTC، مع وجود Z في النهاية للإزاحة Zero UTC، أو Zulu Time)، والتي أحتاج إلى تحليلها في NSDate هدف.

قليلا من التعليمات البرمجية:

NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSString* str = @"2009-08-11T06:00:00.000Z";
NSDate* date = [df dateFromString:str];
تشغيل هذا من خلال المصحح، تاريخ ينتهي نيلفي أنا أفترض أنه يحتوي على شيء مع سلسلة تنسيق تاريخي.

كيف يمكنني إصلاحه لتحليل سلسلة التاريخ بشكل صحيح؟

الفكر سيكون لجعل z. في تنسيق التاريخ الحرفي، A LA إعداد تنسيق التاريخ إلى yyyy-mm-dd't'hh: مم: ss.sss'z.

من شأنها أن تعمل، إلا عندما يتم تحليل Z كحرفي، فإن التاريخ يفقد معلومات الإزاحة، وكذلك غامضة، وبالتالي تفسر أن تكون بالتوقيت المحلي.

على سبيل المثال، إذا كانت السلسلة لتحليل الجهاز 2009-08-11T06: 00: 00.000z (6:00 زولو) سيتم تفسيرها على أنها الساعة 6:00 بالتوقيت المحلي، وسيتم تسجيل إزاحة غير صحيحة. ثم يتم تحليلها في 2009-08-11T06: 00: 00.000-600 (12:00 زولو) مع إزاحة اعتمادا على إزاحة المستخدم.

شكرا!

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

المحلول

لقد أتيحت لي هذه المشكلة أيضا، لست متأكدا مما إذا كان خطأ API ضمن رمز Apple، أو عدم وجود فهمي، لكنني عملت من حوله باستخدام إزاحة ساعة في سلاسل تاريخي.

إذا قمت بتغيير الرمز في مثالك إلى:

NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSString* str = @"2009-08-11T06:00:00.000-0700";   // NOTE -0700 is the only change
NSDate* date = [df dateFromString:str];

سوف تحليل الآن سلسلة التاريخ. بالطبع ساعات -0700 هي إزاحة بلدي، يجب عليك تغييره إلى لك. أتمنى أن يساعدك هذا.

نصائح أخرى

تشير معظم الإجابات إلى علاج "z" كحرف حرفي. لا تفعل هذا!

يعني Z في الواقع أن التاريخ يتم إيقافه بواسطة 0 إلى UTC (+0000).

هذا وفقا لتنسيق المنطقة الزمنية ISO8601.:

تنسيق المنطقة الزمنية ISO 8601: إزاحة ثابتة ومحددة من UTC، والتي لها دائما نفس التنسيق باستثناء UTC نفسها ("z").

"-08:00"

"z"

ما تريد القيام به هو استخدام التنسيق التالي ل NSDateFormatter:

 NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                                  // 2013-11-18T23:00:00.324Z
                                  [formatter setTimeZone:[NSTimeZone localTimeZone]];
                                  [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
                                  return formatter;

عن طريق تكرار z. خمس مرات، يمكنك معرفة الهياكل لاستخدام ISO8601 عند تحليل السلسلة.

علاوة:

  • استخدام واحد إلى ثلاثة z.S لتنسيق RFC 822 بتوقيت جرينتش.
  • استخدام أربعة z.S لتنسيق GMT المحلي.

لمزيد من المعلومات هذه وثيقة.

أعتقد أنك بحاجة إلى وضع علاقات اقتباس واحدة حول Z في سلسلة التنسيق، لأن Z تعني فعليا شيئا ما للتكيف وترغب في تمثيل حرف حرفي بدلا من ذلك.

    [df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

ليست هناك حاجة لمعالجة السلسلة. ببساطة ضبط المنطقة الزمنية على NSDateFormatter (ودوري بينما كنت في ذلك):

NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setLocale:[NSLocale systemLocale]];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

وتحليل سلاسل التاريخ حسب الحاجة:

NSDate * value = [formatter dateFromString:@"2012-03-01T23:08:25.000Z"];
NSLog(@"%@", value); // prints 2012-03-01 23:08:25 +0000

يمكنك استخدام هذه الطريقة للحصول على تاريخ من UTC.

+ (NSDate*)getDateFromUTCDateTimeString:(NSString*)dateString {

NSDateFormatter *isoDateFormatter = [[NSDateFormatter alloc] init];

[isoDateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

[isoDateFormatter setTimeZone:[NSTimeZone  timeZoneWithAbbreviation:@"UTC"]];

NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];

[userFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

[dateFormatter setTimeZone:[NSTimeZone  timeZoneWithAbbreviation:@"UTC"]];

NSDate *date = [isoDateFormatter dateFromString:dateString];

return [dateFormatter dateFromString:[userFormatter stringFromDate:date]];

}

هذا قد يساعدك .. "z" هو حرفي لرمز المنطقة الزمنية. حاول استخدام "o" (الحرف، وليس الصفر). يعني "O" الحرفي إزاحة UTC. ركضت في حين مرة أخرى، آمل أن يكون هذا ساعدك.

-(NSDate*)dateFromZulu:(NSString*)str {
    if (str == nil) {
        NSLog(@"Error getting date");
        return [NSDate date];
    }

    NSDateFormatter *f = [[NSDateFormatter alloc] init];
    [f setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss Z"];
    NSDate *ret = [f dateFromString:[str stringByReplacingOccurrencesOfString:@"Z" withString:@" +0000"]];
    [f release];

    if (ret == nil) {
        ret = [NSDate date];
        NSLog(@"Error formatting date (%@)",str);       
    }   
    return ret;     
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top