NSDateFormatter,我做错了什么或这是一个错误?

时间:2008-09-27 05:41:52

标签: iphone ios objective-c nsdate nsdateformatter

我正在尝试以某种格式打印出日期:

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

如果将iPhone设置为24小时,这样可以正常工作,如果另一方面用户已将其设置为24小时时间,然后返回到上午/下午(它可以正常工作,直到您切换此设置)然后它即使我没有要求它,也会在最后添加AM / PM:

20080927030337 PM

我做错了什么或这是固件2.1的错误?

编辑1:使描述更清晰

编辑2解决方法:事实证明这是一个错误,修复它我将AM和PM字符设置为“”:

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

8 个答案:

答案 0 :(得分:29)

此行为的原因是Locale,它设置了正确的Locale。

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.来自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];

答案 1 :(得分:14)

以下是iPhone SDK错误的解释(3.1 beta SDK中仍然存在)

  

首先,介绍iPhone用户界面的一些背景知识。当iPhone   用户在“美国”和“美国”之间更改他们的地区格式   “法国”,用户的“24小时时间”设置会自动切换   到该地区最普遍的模式。在法国,那   将24小时时间设置为“开启”,而在美国则将其设置为“开启”   “OFF”。然后,用户可以手动覆盖该设置   麻烦开始的地方。

     

问题来自NSDateFormatter以某种方式“陷入困境”   用户手动选择的12或24小时时间模式。所以,如果一个   法国用户手动选择12小时模式和应用程序   请求NSDateFormatter以24小时格式输出时间   “HHmm”,它实际上会以12小时的格式接收时间,例如:   “01:00 PM”,好像申请人要求“hhmm aa”。   如果美国用户手动选择24小时模式,则会发生相反的情况:   用12小时格式输出时间“hhmm aa”实际上会得到   您可以使用24小时格式,例如“17:00“。

可在此blog上找到更多详细信息和可能的解决方法。

答案 2 :(得分:12)

使用您在模拟器和2.1固件和24小时时间设置为关闭的手机上发布的代码,当我这样做时,我从未在dateStr上附加AM / PM:

NSLog(@"%@", dateStr);

您是否正在使用dateStr执行其他任何未在此处发布的内容?你是如何检查价值的?

跟进

  

尝试打开am / pm设置然后关闭。在我这样做之前,我也没有问题。我打印出的方式和你一样。

好的,我也是这样看的。这必须是一个bug。我建议您file a bug report,同时检查并过滤掉不需要的字符。

答案 3 :(得分:9)

将日期格式化程序上的语言环境设置为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];

我不确定是否还需要添加日历,但这很有效。

答案 4 :(得分:4)

我认为这是解决方案。

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!

答案 5 :(得分:1)

对于那些想要使用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];

答案 6 :(得分:0)

这也应该有用(虽然我看到了一些古怪的结果)。

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

答案 7 :(得分:0)

简短回答:尝试[dateFormatter setDateFormat:@"yyyyMMddhhmmss"]; 12小时格式(请注意小写hh)。

这是一个令人沮丧的话题,因为很多网站表示使用HH几个小时(包括正式的Apple文档),但是它将其设置为24小时格式,而hh使用12小时格式。有关详细信息,请参阅http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns

作为奖励,请注意您还可以使用KKkk作为一天中的小时格式,这可能会被一个人关闭。

更新: 我最近在看NSLocale(https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html),看起来你可以使用autoupdatingCurrentLocale来将应用程序内的更改应用于区域设置。这样做的结果是,即使手机设置为使用24小时制(如切换到法国时),您也可以为应用程序进行12/24切换,这不会影响手机上的任何其他应用程序,或要求您离开应用程序进行更改。