NSDateFormatter、私は何か間違ったことをしていますか、これはバグですか?
-
02-07-2019 - |
質問
特定の形式で日付を印刷しようとしています:
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:@""];
解決
2.1ファームウェアと24時間制をオフに設定して、シミュレーターと電話の両方に投稿したコードを使用して、dateStrにAM / PMを追加したことはありませんでした:
NSLog(@"%@", dateStr);
dateStrを使用して、ここに投稿しなかったことを他に行っていますか?値をどのようにチェックしていますか?
フォロー
午前/午後の設定をオンにしてからオフにしてみてください。私はそれをするまで、問題もありませんでした。あなたと同じように印刷しています。
さて、これもやってみます。バグにならないでください。 バグレポートを提出し、その間に不要な文字をチェックして除外することをお勧めします。
他のヒント
この動作の理由はロケールです。正しいロケールを設定します。
NSDateFormatter のローカルを en_US_POSIX に設定すると、これが修正されます。 24時間形式と12時間形式の両方で機能します。
iPhone OSでは、ユーザーはデフォルトのAM / PM対24時間設定を上書きできます(設定>一般>日付&時間> 24-時間)。これにより、NSDateFormatterが書き換えられます設定したフォーマット文字列。
アップルドキュメント
これを試してください
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];
iPhone SDKのバグの説明は次のとおりです(3.1ベータSDKにもまだあります)
まず、iPhoneのユーザーインターフェイスの背景について説明します。 iPhone ユーザーは、たとえば“ United States”の間で地域の形式を変更します。そして “フランス&#8221 ;、ユーザー’ “ 24時間”設定は自動的に切り替えられます その地域で最も普及しているモードに。フランスでは、 24-Hour Timeを“ ON”に設定し、米国では、 “ OFF”。その後、ユーザーはその設定を手動で上書きできます。 問題が始まる場所。
問題は、NSDateFormatterが何らかの原因で“スタック状態になることです”の中に ユーザーが手動で選択した12時間制または24時間制。だから フランスのユーザーは手動で12時間モードを選択し、アプリケーションは NSDateFormatterに24時間形式で時刻を出力するよう要求しました “ HHmm&#8221 ;、実際には12時間形式で時刻を受け取ります。 “ 01:00 PM&#8221 ;、アプリケーションが代わりに“ hhmm aa”を要求したかのように。 米国のユーザーが手動で24時間モードを選択した場合、逆のことが起こります。 12時間形式で時間を出力する“ hhmm aa”実際に得るだろう 代わりに、24時間形式で時間を計ります。 “ 17:00″。
詳細と可能な回避策は、このブログ。
日付フォーマッタのロケールを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];
カレンダーの追加も必要かどうかわかりませんが、これはうまく機能します。
これが解決策だと思います。
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!
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];
これも機能するはずです(ただし、奇妙な結果が表示されます)。
-(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];
}
簡単な答え: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時間ずれている可能性があります。
更新: 私は最近NSLocale(https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html)を見ていましたが、autoupdatingCurrentLocaleを使用して、アプリ内から行われた変更をロケールに適用します。その結果、電話が24時間時計を使用するように設定されている場合(フランスに切り替えたときなど)でも、電話の他のアプリに影響を与えないアプリの12/24切り替えを行うことができます。または、変更を行うためにアプリを終了する必要があります。