2008-09-27 17 views
37

Próbuję wydrukować datę w określonym formacie:NSDateFormatter, czy robię coś nie tak, czy jest to błąd?

NSDate *today = [[NSDate alloc] init]; 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"]; 
NSString *dateStr = [dateFormatter stringFromDate:today]; 

Jeśli iPhone jest ustawiony na 24 godziny czasu, to działa dobrze, jeśli z drugiej strony użytkownik ustawił go na 24 godziny czas, a następnie z powrotem do AM/PM (to działa dobrze, dopóki nie włączyć to ustawienie), to dołącza AM/PM na koniec, chociaż nie pytałem o to:

20080927030337 PM 

robię coś źle czy jest to błąd z oprogramowaniem układowym 2.1?

Edit 1: Wykonane opis jaśniejsze

Edycja 2 obejście: Okazuje się, że jest to błąd, aby naprawić to ustawić znaki AM i PM do "":

[dateFormatter setAMSymbol:@""]; 
[dateFormatter setPMSymbol:@""]; 
+1

Pierwsze dokładnie ten sam problem - przyjemność zobaczyć, że nie wariuję! –

+0

Tylko uwaga, jeśli używasz metod setAM/PM, wciąż będzie dodatkowe miejsce w ciągu znaków. – conor

Odpowiedz

12

Używając kodu Ci pisał zarówno na symulatorze i telefon z czasem 2.1 firmware i 24-godzinnym ustawiony na oFF, nigdy nie miałem AM/PM dołączane do dateStr kiedy zrobić:

NSLog(@"%@", dateStr); 

Czy robisz cokolwiek innego z d ateStr, że nie pisałeś tutaj? Jak sprawdzasz wartość?

Kontynuacja

Spróbuj włączyć ustawienie/PM AM na następnie wyłączyć. Ja też nie miałem problemu, dopóki tego nie zrobiłem. Drukuję go w ten sam sposób, w jaki jesteś.

Okej, widzę to, kiedy to robię. To musi być błąd. Polecam ci file a bug report i po prostu odszukuj i odfiltrowuj niechciane znaki w międzyczasie.

+0

spróbuj włączyć ustawienie AM/PM, a następnie wyłącz. Ja też nie miałem problemu, dopóki tego nie zrobiłem. Drukuję go w ten sam sposób, w jaki jesteś. – rustyshelf

+0

Ta odpowiedź nie jest rozwiązaniem - odpowiedź huyz poprawnie to potwierdza - jest to błąd z NSDateFormatter – earnshavian

14

Oto wyjaśnienie błędu iPhone SDK (również nadal istnieje w 3.1 beta SDK)

Najpierw trochę tła na interfejsie użytkownika iPhone. Gdy użytkownicy iPhone'a zmieniają swój region regionalny między, powiedzmy "Stany Zjednoczone" i "Francja", ustawienie "24-godzinny czas" użytkowników zostaje automatycznie przełączone na na tryb najbardziej rozpowszechniony w tym regionie. We Francji ten ustawiłby czas 24-godzinny na "WŁ.", A w USA ustawiłoby go na "WYŁ.". Użytkownicy mogą następnie ręcznie zastąpić to ustawienie i to jest , gdzie zaczyna się problem.

Problem pochodzi z NSDateFormatter "utknięcie" w trybie 12 lub 24-godzinnym, który użytkownik wybrał ręcznie. Jeśli więc francuski użytkownik ręcznie wybierze 12-godzinny tryb, a aplikacja zażąda od NSDateFormatter czasu wyjściowego w formacie 24-godzinnym "HHmm", faktycznie otrzyma czas w formacie 12-godzinnym, np. "01:00 PM", tak jakby aplikacja zamiast tego zażądała "hhmm aa". Odwrotna sytuacja miałaby miejsce, gdyby użytkownik z USA ręcznie wybrał tryb 24-godzinny: czas wyprowadzania z 12-godzinnym formatem "hhmm aa" faktycznie otrzymywałby czas w formacie 24-godzinnym zamiast, np. "17:00".

Więcej informacji i możliwe obejście można znaleźć na tej stronie blog.

+0

Zgłoszony błąd: http://openradar.appspot.com/radar?id=1110403 –

+3

Potwierdziłem to na urządzeniu testowym. Zmień międzynarodowe ustawienie na Zjednoczone Królestwo.Ustaw datę i godzinę na 24 godziny, aby je odtworzyć w swoich aplikacjach. Rozwiązaniem dla mnie była odpowiedź @DenNukem poniżej ustawienia locale na en_US dla formera daty. – earnshavian

+0

@earnshavian u uratowałeś moje życie !! Mój klient ostatnio natknął się na ten problem, którego nie mogę odtworzyć, ponieważ korzystałem z regionu USA! Próbowałem ustawić w innych regionach, wszystkie działały poprawnie, dopóki nie zobaczyłem Twojego komentarza, to region Wielkiej Brytanii spowodował problem. Wielkie dzięki! – user3162662

1

Dla tych, znalezienie na to pytanie, którzy chcą korzystać NSDateFormatter do analizowania czasu 24-godzinnego i napotyka ten błąd, używając NSDateComponents do analizowania daty i godziny, które mają znanym formacie pomija ten problem:

NSString *dateStr = @"2010-07-05"; 
NSString *timeStr = @"13:30"; 

NSDateComponents *components = [[NSDateComponents alloc] init]; 
components.year = [[dateStr substringToIndex:4] intValue]; 
components.month = [[dateStr substringWithRange:NSMakeRange(5, 2)] intValue]; 
components.day = [[dateStr substringFromIndex:8] intValue]; 
components.hour = [[timeStr substringToIndex:2] intValue]; 
components.minute = [[timeStr substringFromIndex:3] intValue]; 

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 

NSDate *date = [calendar dateFromComponents:components]; 

[components release]; 
[calendar release]; 
4

I myśl, że to jest rozwiązanie.

NSDateFormatter *df =[[NSDateFormatter alloc] init]; 
     [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
     NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; 

[df setLocale: usLocale]; 

[usLocale release]; 

NSDate *documento_en_Linea =[[[NSDate alloc] init]autorelease]; 

documento_en_Linea=[df dateFromString:@"2010-07-16 21:40:33"]; 

[df release]; 

     NSLog(@"fdocumentoenLineaUTC:%@!",documento_en_Linea); 


//ouput 
    fdocumentoenLineaUTC:2010-07-16 09:40:33 p.m. -0500! 
0

To powinno również zadziałać (mimo to widzę pewne dziwne wyniki).

-(NSString*)lowLevTime:(NSString*)stringFormat { 
    char buffer[50]; 
    const char *format = [stringFormat UTF8String]; 
    time_t rawtime; 
    struct tm * timeinfo; 
    time(&rawtime); 
    timeinfo = localtime(&rawtime); 
    strftime(buffer, sizeof(buffer), format, timeinfo); 
    return [NSString stringWithCString:buffer encoding:NSASCIIStringEncoding]; 
} 
9

ustawień regionalnych w dniu wydania formater na En_US rozwiązuje problem dla mnie:

NSDateFormatter * f = [[NSDateFormatter alloc] init]; 
    [f setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; 
    f.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; 
    f.calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 
    f.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease]; 

Nie jestem pewien, czy dodanie kalendarza jest również potrzebne, ale to działa dobrze.

+0

Nie zmieniłem kalendarza i po wykonaniu operacji chciałem zmienić formatowanie daty z powrotem na ustawienia regionalne użytkownika, więc zrobiłem f.locale = [NSLocale currentLocale]. To działało dla mnie. – arlomedia

+0

dziękuję, to zadziałało dla mnie –

0

Krótka odpowiedź: spróbuj [dateFormatter setDateFormat:@"yyyyMMddhhmmss"]; dla formatu 12-godzinnego (zwróć uwagę na małe litery hh).

To był frustrujący temat, ponieważ wiele stron internetowych wskazuje, że przez wiele godzin używa się HH (w tym oficjalnej dokumentacji Apple), ale to ustawia ją na format 24-godzinny, podczas gdy hh używa formatu 12-godzinnego. Aby uzyskać więcej informacji, patrz http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns.

Jako bonus należy pamiętać, że można również użyć formatu KK lub kk dla formatu godziny dnia, który prawdopodobnie zostanie wyłączony o jeden.

Aktualizacja: byłem niedawno patrząc na NSLocale (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html) i że będzie wydaje się, że możesz użyć autoupdatingCurrentLocale, aby zastosować zmiany wprowadzone w aplikacji do ustawień regionalnych. Skutek tego jest taki, że nawet jeśli telefon jest ustawiony na 24-godzinny zegar (np. Kiedy przełączyłeś się na Francję), możesz włączyć przełącznik 12/24 dla aplikacji, która nie wpłynie na inne aplikacje w telefonie, lub musisz opuścić aplikację, aby wprowadzić zmianę.

25

Powodem takiego zachowania jest Locale, ustawić właściwą Locale ustawić lokalny Twojego NSDateFormatter do en_US_POSIX będzie to naprawić. Działa zarówno w formacie 24-godzinnym, jak i 12-godzinnym.

On iPhone OS, the user can override the default AM/PM versus 24-hour time setting (via Settings > General > Date & Time > 24-Hour Time), which causes NSDateFormatter to rewrite the format string you set. Od apple doc

Spróbuj tego,

NSDate *today = [[NSDate alloc] init]; 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; 
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"]; 
NSString *dateStr = [dateFormatter stringFromDate:today]; 
+1

Dziękuję. Spędziłem 5 godzin, aby to zetknąć, i ponieważ zawsze daje mi to ciąg w formacie czasu z "a.m/p.m", co powoduje, że moje żądanie API zawodzi, ponieważ wartość łańcucha & timeRequest z przestrzenią! – felixwcf

Powiązane problemy