SORU
7 Temmuz 2011, PERŞEMBE


NSDateFormatter yerel "özellik" ile başa çıkmak için en iyi yolu nedir?

NSDateFormatter "özelliği varsa Eğer basit bir" "çalışma biçimi olarak . sabit yaparsan" o seni ısırmadan beklenmedik bir var gibi görünüyor

NSDateFormatter* fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"yyyyMMddHHmmss"];
NSString* dateStr = [fmt stringFromDate:someDate];
[fmt release];

Daha sonra ABD'de gayet iyi çalışıyor ... ve 24 saat açık bir bölge telefon seti olan biri KADAR çoğu yerel 12 12/24 saat ayarları geçiş ayarlar. Yukarıdaki "" veya "PM" sonuç dizesi sonu üzerine. teyel başlar

(Örneğin, NSDateFormatter, am I doing something wrong or is this a bug?)

(**26)

Görünüşe göre Apple bu "Tasarlanmış, ve bunu düzeltmek için gidiyor. Bozuk Olarak" KÖTÜ olduğunu açıkladı

Tuzağa görünüşe göre tarih, yerel belirli bir bölge, genellikle BİZİM için biçimlendirici ayarlamak için, ama bu biraz dağınık

NSLocale *loc = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
[df setLocale: loc];
[loc release];

Çok kötü değil onsies. ama farklı apps on ile uğraşıyorum, ve baktığım ilk bu senaryonun 43 örnekleri vardır.

Makro/geçersiz bir sınıf için akıllı fikirler her şeyi değiştirmek için çaba en aza indirmek için ne/kadar, belirsiz kodu yapmadan? (Aklıma ilk gelen ınit yöntemi yerel oluşturacak bir sürümü ile NSDateFormatter geçersiz kılmak için. İki hat tahsis/init hattı ve ekledi alma -- değişen gerektirir.)

Eklendi

Bu tüm senaryolarda iş gibi görünüyor şimdiye kadar ile geldim nedir:

@implementation BNSDateFormatter

-(id)init {
static NSLocale* en_US_POSIX = nil;
NSDateFormatter* me = [super init];
if (en_US_POSIX == nil) {
    en_US_POSIX = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
}
[me setLocale:en_US_POSIX];
return me;
}

@end

Kelle!

Öneri/eleştiri ortasından geçen gün gördüğüm en iyi (meşru) ödül Salı ödül vereceğim. [--Aşağıdaki uzattı.

Güncelleme

Re OMZ önerisi burada buluyorum

Burada sürüm -- h dosyası kategori:

#import <Foundation/Foundation.h>


@interface NSDateFormatter (Locale)
- (id)initWithSafeLocale;
@end

Kategori m dosya:

#import "NSDateFormatter Locale.h"


@implementation NSDateFormatter (Locale)

- (id)initWithSafeLocale {
static NSLocale* en_US_POSIX = nil;
self = [super init];
if (en_US_POSIX == nil) {
    en_US_POSIX = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
}
NSLog(@"Category's locale: %@ %@", en_US_POSIX.description, [en_US_POSIX localeIdentifier]);
[self setLocale:en_US_POSIX];
return self;    
}

@end

Kod:

NSDateFormatter* fmt;
NSString* dateString;
NSDate* date1;
NSDate* date2;
NSDate* date3;
NSDate* date4;

fmt = [[NSDateFormatter alloc] initWithSafeLocale];
[fmt setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
dateString = [fmt stringFromDate:[NSDate date]];
NSLog(@"dateString = %@", dateString);
date1 = [fmt dateFromString:@"2001-05-05 12:34:56"];
NSLog(@"date1 = %@", date1.description);
date2 = [fmt dateFromString:@"2001-05-05 22:34:56"];
NSLog(@"date2 = %@", date2.description);
date3 = [fmt dateFromString:@"2001-05-05 12:34:56PM"];  
NSLog(@"date3 = %@", date3.description);
date4 = [fmt dateFromString:@"2001-05-05 12:34:56 PM"]; 
NSLog(@"date4 = %@", date4.description);
[fmt release];

fmt = [[BNSDateFormatter alloc] init];
[fmt setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
dateString = [fmt stringFromDate:[NSDate date]];
NSLog(@"dateString = %@", dateString);
date1 = [fmt dateFromString:@"2001-05-05 12:34:56"];
NSLog(@"date1 = %@", date1.description);
date2 = [fmt dateFromString:@"2001-05-05 22:34:56"];
NSLog(@"date2 = %@", date2.description);
date3 = [fmt dateFromString:@"2001-05-05 12:34:56PM"];  
NSLog(@"date3 = %@", date3.description);
date4 = [fmt dateFromString:@"2001-05-05 12:34:56 PM"]; 
NSLog(@"date4 = %@", date4.description);
[fmt release];

Sonuç:

2011-07-11 17:44:43.243 DemoApp[160:307] Category's locale: <__NSCFLocale: 0x11a820> en_US_POSIX
2011-07-11 17:44:43.257 DemoApp[160:307] dateString = 2011-07-11 05:44:43 PM
2011-07-11 17:44:43.264 DemoApp[160:307] date1 = (null)
2011-07-11 17:44:43.272 DemoApp[160:307] date2 = (null)
2011-07-11 17:44:43.280 DemoApp[160:307] date3 = (null)
2011-07-11 17:44:43.298 DemoApp[160:307] date4 = 2001-05-05 05:34:56 PM  0000
2011-07-11 17:44:43.311 DemoApp[160:307] Extended class's locale: <__NSCFLocale: 0x11a820> en_US_POSIX
2011-07-11 17:44:43.336 DemoApp[160:307] dateString = 2011-07-11 17:44:43
2011-07-11 17:44:43.352 DemoApp[160:307] date1 = 2001-05-05 05:34:56 PM  0000
2011-07-11 17:44:43.369 DemoApp[160:307] date2 = 2001-05-06 03:34:56 AM  0000
2011-07-11 17:44:43.380 DemoApp[160:307] date3 = (null)
2011-07-11 17:44:43.392 DemoApp[160:307] date4 = (null)

Telefon [Bu bir iPod Touch olun] 12/24 12 ayarlı anahtar ile İngiltere için ayarlanır. İki sonuç net bir fark var, ve kategori sürümü yanlış kanısındayım. Kategori sürümünde günlük idam oluyor (ve durur kodu yerleştirilen isabet), sadece kod değil bu yüzden unutmayın, bir şekilde kullanılan almıyor.

Kelle güncelleme:

Henüz yürürlükteki herhangi bir cevap alamadım beri bir iki gün kelle süre uzatacağım.

Ödül 21 saat eğer cevap benim durumumda çok faydalı olmasa bile yardım için en fazla çabayı kim gidin, olur-biter.

İlginç bir gözlem

Modifiye kategori uygulama biraz:

#import "NSDateFormatter Locale.h"

@implementation NSDateFormatter (Locale)

- (id)initWithSafeLocale {
static NSLocale* en_US_POSIX2 = nil;
self = [super init];
if (en_US_POSIX2 == nil) {
    en_US_POSIX2 = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
}
NSLog(@"Category's locale: %@ %@", en_US_POSIX2.description, [en_US_POSIX2 localeIdentifier]);
[self setLocale:en_US_POSIX2];
NSLog(@"Category's object: %@ and object's locale: %@ %@", self.description, self.locale.description, [self.locale localeIdentifier]);
return self;    
}

@end

Temelde sadece statik yerel değişken statik alt ilan ile bazı çatışma olduğu durumda) adını değiştirdi ve ekstra NSLog ekledi. Ama bu NSLog yazdırır bak:

2011-07-15 16:35:24.322 DemoApp[214:307] Category's locale: <__NSCFLocale: 0x160550> en_US_POSIX
2011-07-15 16:35:24.338 DemoApp[214:307] Category's object: <NSDateFormatter: 0x160d90> and object's locale: <__NSCFLocale: 0x12be70> en_GB
2011-07-15 16:35:24.345 DemoApp[214:307] dateString = 2011-07-15 04:35:24 PM
2011-07-15 16:35:24.370 DemoApp[214:307] date1 = (null)
2011-07-15 16:35:24.378 DemoApp[214:307] date2 = (null)
2011-07-15 16:35:24.390 DemoApp[214:307] date3 = (null)
2011-07-15 16:35:24.404 DemoApp[214:307] date4 = 2001-05-05 05:34:56 PM  0000

Gördüğünüz gibi, sadece setLocale yoktu. Biçimlendirici yerel hala en_GB. Bir şey "" bir kategoride. ınit yöntemi hakkında garip bir şey var gibi görünüyor

Son kararım

accepted answer aşağıya bakın.

CEVAP
18 Temmuz 2011, PAZARTESİ


Yaa!!

Bazen bir var"!! Aha" bazen bir daha"!! Duh" an Bu ikincisi. İnitWithSafeLocale için kategori olan "süper" ınit self = [super init]; olarak kodlanmış. Bu NSDateFormatter en ÜST ınıts ama NSDateFormatter nesnesi init değildir. Görünüşe göre bu başlatma atlanır setLocale", muhtemelen nesne. bazı eksik veri yapısı nedeniyle "sıçrar self = [self init]; ınit değişen NSDateFormatter başlatma oluşmasına neden olur ve setLocale tekrar mutlu.

Burada "" kaynak kategori .son m:

#import "NSDateFormatter Locale.h"

@implementation NSDateFormatter (Locale)

- (id)initWithSafeLocale {
    static NSLocale* en_US_POSIX = nil;
    self = [self init];
    if (en_US_POSIX == nil) {
        en_US_POSIX = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    }
    [self setLocale:en_US_POSIX];
    return self;    
}

@end

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • apenney888

    apenney888

    27 EKİM 2010
  • Karan Thakur

    Karan Thakur

    23 HAZİRAN 2010
  • theKGB65

    theKGB65

    24 Aralık 2007