Qual é a melhor maneira de lidar com o locale do NSDateFormatter "feechur"?

Parece queNSDateFormatter possui um "recurso" que o morde inesperadamente: se você fizer uma operação simples de formato "fixo", como:

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

Em seguida, ele funciona bem nos EUA e na maioria das localidades, ATÉ QUE ... alguém com o telefone definido para uma região de 24 horas define o interruptor de 12/24 horas nas configurações para 12. Em seguida, o item acima começa a "AM" ou "PM" no final da sequência resultante.

(Veja, por exemplo,NSDateFormatter, estou fazendo algo errado ou isso é um bug?)

(E vejahttps: //developer.apple.com/library/content/qa/qa1480/_index.htm)

Aparentemente, a Apple declarou que isso é "MAU" - Quebrado como projetado, e eles não vão corrigi-l

A evasão é aparentemente definir o local do formatador de datas para uma região específica, geralmente os EUA, mas isso é um pouco confuso:

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

Não é muito ruim em dois pares de usuários, mas estou lidando com cerca de dez aplicativos diferentes, e o primeiro que eu olho tem 43 instâncias desse cenári

Alguma idéia inteligente para uma classe macro / substituída / o que quer que seja para minimizar o esforço de mudar tudo, sem tornar o código obscuro? (Meu primeiro instinto é substituir o NSDateFormatter por uma versão que defina o código do idioma no método init. Requer a alteração de duas linhas - a linha de alocação / inicialização e a importação adicionada.)

Adicionado

Este é o que eu criei até agora - parece funcionar em todos os cenários:

@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
Recompensa

Atribuirei a recompensa à melhor sugestão / crítica (legítima) que eu vir até o meio-dia de terça-feira. [Veja abaixo - prazo estendido.]

Atualiza

Re proposta da OMZ, aqui está o que eu estou encontrando -

Aqui está a versão da categoria - arquivo h:

#import <Foundation/Foundation.h>


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

Arquivo da categoria m:

#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

O código

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];

O resultado

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)

O telefone [faz com que o iPod Touch] esteja definido para a Grã-Bretanha, com o interruptor 12/24 definido como 12. Há uma clara diferença nos dois resultados, e considero a versão da categoria incorreta. Observe que o log na versão da categoria está sendo executado (e as paradas colocadas no código são atingidas); portanto, não é apenas um caso do código que de alguma forma não está sendo usad

tualização de recompensa:

Desde que ainda não recebi nenhuma resposta aplicável, estenderei o prazo da recompensa por mais um ou dois dia

@Bounty termina em 21 horas - será direcionado a quem fizer mais esforço para ajudar, mesmo que a resposta não seja realmente útil no meu cas

Uma observação curiosa

Modificou ligeiramente a implementação da categoria:

#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

Basicamente, apenas alterei o nome da variável de localidade estática (caso houvesse algum conflito com a estática declarada na subclasse) e adicionei o NSLog extra. Mas veja o que o NSLog imprime:

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

Como você pode ver, o setLocale simplesmente não. A localidade do formatador ainda é en_GB. Parece que há algo "estranho" em um método init em uma categori

Resposta fina

Veja o resposta aceita abaixo

questionAnswers(5)

yourAnswerToTheQuestion