web-dev-qa-db-ja.com

NSDateFormatter、私は何か間違ったことをしていますか、それともこれはバグですか?

日付を特定の形式で印刷しようとしています。

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

IPhoneが24時間制に設定されている場合、これは正常に機能します。一方、ユーザーが24時間制に設定している場合は、AM/PMに戻り(この設定を切り替えるまでは正常に機能します)、AMを追加します。私がそれを求めなかったとしても、最後に/ PM:

20080927030337 PM

私は何か間違ったことをしていますか、それともこれはファームウェア2.1のバグですか?

編集1:説明をより明確にしました

編集2の回避策:これはバグであることが判明しました。これを修正するには、AMとPM文字を ""に設定します。

[dateFormatter setAMSymbol:@""];
[dateFormatter setPMSymbol:@""];
39
rustyshelf

シミュレーターと2.1ファームウェアおよび24時間制がオフに設定された電話の両方に投稿したコードを使用して、次の場合に、dateStrにAM/PMを追加したことはありません。

NSLog(@"%@", dateStr);

ここに投稿していないdateStrで何か他のことをしていますか?値をどのようにチェックしていますか?

フォローアップ

午前/午後の設定をオンにしてからオフにしてみてください。それができるまで、私も問題はありませんでした。私はあなたと同じようにそれを印刷しています。

さて、これを行うとわかります。それはバグでなければなりません。 バグレポートを提出する それまでの間、不要な文字をチェックして除外することをお勧めします。

12
Mike McMaster

この動作の理由はロケールです。正しいロケールを設定します。

NSDateFormatterのローカルをen_US_POSIXに設定すると、これが修正されます。 24時間形式と12時間形式の両方で機能します。

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. From Apple doc

これを試して、

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];
31
Toseef Khilji

これがiPhoneSDKのバグの説明です(3.1ベータSDKにもまだあります)

まず、iPhoneのユーザーインターフェイスの背景について説明します。 iPhoneユーザーが地域の形式を「米国」と「フランス」などの間で変更すると、ユーザーの「24時間制」設定は、その地域で最も普及しているモードに自動的に切り替わります。フランスでは、24時間制が「オン」に設定され、米国では、「オフ」に設定されます。その後、ユーザーはその設定を手動で上書きでき、そこから問題が発生します。

この問題は、ユーザーが手動で選択した12時間または24時間モードでNSDateFormatterが何らかの形で「スタック」することに起因します。したがって、フランスのユーザーが手動で12時間モードを選択し、アプリケーションがNSDateFormatterに24時間形式の「HHmm」で時間を出力するように要求した場合、実際には12時間形式で時間を受信します。 「01:00 PM」、アプリケーションが代わりに「hhmmaa」を要求したかのように。米国のユーザーが手動で24時間モードを選択した場合は、逆のことが起こります。12時間形式の「hhmmaa」で時間を出力すると、実際には代わりに24時間形式で時間が取得されます。 「17:00」。

詳細と考えられる回避策は、この blog にあります。

14
huyz

日付フォーマッタのロケールをen_USに設定すると、問題が修正されます。

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

カレンダーの追加も必要かどうかはわかりませんが、これは問題なく機能します。

9
DenNukem

これが解決策だと思います。

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!
4
Ethel

NSDateFormatterを使用して24時間制を解析したいと考えており、このバグに遭遇しているこの質問を見つけた場合は、NSDateComponentsを使用して、既知の形式の日付と時刻を解析すると、この問題が回避されます。

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

簡単な答え:12時間形式で[dateFormatter setDateFormat:@"yyyyMMddhhmmss"];を試してください(小文字のhhに注意してください)。

非常に多くのWebサイトがHHを何時間も使用することを示しているため(公式のAppleドキュメントを含む)、それは24時間形式に設定されますが、hhは12時間形式を使用します。詳細については、 http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns を参照してください。

ボーナスとして、KKまたはkkを1日の時間形式に使用することもできますが、これは1つずれている可能性があります。

更新:最近NSLocale(https://developer.Apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html)を見ていましたが、使用できるようです。 autoupdatingCurrentLocaleを使用して、アプリ内から行われた変更をロケールに適用します。その結果、電話が24時間制を使用するように設定されている場合でも(フランスに切り替えた場合など)、電話の他のアプリに影響を与えないように、アプリを12/24に切り替えることができます。または、変更を加えるためにアプリを終了する必要があります。

0
Arthulia

これも機能するはずです(私はいくつかの奇妙な結果を見ていますが)。

-(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];
}
0
valexa