日付を特定の形式で印刷しようとしています。
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時間形式の両方で機能します。
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];
これが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 にあります。
日付フォーマッタのロケールを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!
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];
簡単な答え: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に切り替えることができます。または、変更を加えるためにアプリを終了する必要があります。
これも機能するはずです(私はいくつかの奇妙な結果を見ていますが)。
-(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];
}