iPhone - NSDate,NSString和Timezones的奇怪问题

时间:2011-06-29 06:19:18

标签: iphone nsdate nsdateformatter gmt nstimezone

我已经搜索过,并没有找到像我一样的确切问题,所以这里什么都没有:

我有一个NSString,其中包含我从XML Feed中提取的密钥。密钥是24小时格式的时间(例如13:30或15:00)。我想将NSString转换为NSDate并根据设备的设置时区将其转换为适当的时区。关键是Unicode HH:mm(24:00),所以我很好奇为什么这不能正常工作。

我已经得到了一个应该有效的基本大纲,但唉没有。第二个NSLog(获得NS日期)返回null并且最终日志返回一个奇怪的数字(准确地说是1969-12--2147483629 -596:-31:-23 +0000。)我在这里做错了什么?

提前致谢,

    NSString *dateString = [dict objectForKey:@"24hrdate"];
    NSLog(@"NSString Date: %@", dateString);

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];    
    [formatter setDateFormat:@"HH:mm"];
    NSDate *sourceDate = [formatter dateFromString:dateString]; 
    NSLog(@"Got NS Date: %@", sourceDate);

    NSTimeZone *sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    NSTimeZone *destinationTimeZone = [NSTimeZone systemTimeZone];

    NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
    NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
    NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;

    NSDate* destinationDate = [[[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate] autorelease];
    NSLog(@"Final Date: %@", destinationDate);

3 个答案:

答案 0 :(得分:0)

首先要了解日期组件将为01-01-1970,因为它未提供。如果输入字符串是04:00 GMT,我假设您希望时间为@"04:00"。您可以通过设置格式化程序的时区来实现。

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];    
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
[formatter setDateFormat:@"HH:mm"];
NSDate *sourceDate = [formatter dateFromString:dateString]; 

答案 1 :(得分:0)

NSDate用于表示日期和时间。虽然你可以通过坚持午夜代表一个约会,但你不能真正代表它的一天中的时间。你可以在Mac上对它进行虚假处理(默认为合理的一天),但在iOS上你会得到非常不准确的时间。 (至少,你在某些版本上做过。这可能已经修复了。)

这里有两种方法:

  1. 您可以在一天中的某个时段构建NSDateComponents并使用dateByAddingComponents将其添加到您希望时间显示的日期的午夜。这将无法返回您在夏令时开始或结束的那一天所期望的时间。

  2. 您可以使用所需日期(NSDate)和时间(可能为NSString)来构建日期/时间字符串。

  3. - (NSDate *)timeInHours: (NSInteger)hours
                    minutes: (NSInteger)minutes
                    seconds: (NSInteger)seconds
                     onDate: (NSDate *)inDate;
    {
        id timeStr = [[NSMutableString alloc] initWithFormat: @"%02d:%02d:%02d", hours, minutes, seconds];
        id dateStr = [dateWithoutTimeFormatter stringFromDate: inDate];
        id dateTimeStr = [[NSString alloc] initWithFormat: @"%@ %@", dateStr, timeStr];
        [timeStr release];
        id dateTime = [dateWithTimeFormatter dateFromString: dateTimeStr];
        [dateTimeStr release];
        return dateTime;
    }
    

    如果你真的只想要一天中的时间,那就把它作为一个字符串保存。

答案 2 :(得分:0)

只是想回复一下,我确实设法实现了我最初的目的,没有任何问题。基本上,我必须将字符串转换为NSDate,通过NSDateFormatter运行NSDate(设置为时间的原始时区 - NSDateFormatter的setTimeZone是有帮助的),从中拉出一个NSDate,然后通过另一个NSDateFormatter运行该设备的时区。然后我将生成的NSDate转换回NSString,并将其粘贴在UILabel上。

这个解决方案似乎效果很好,因为我已将设备设置为各个时区,时区更改仍然正确。

编辑:这也很重要:

NSString *date…….
date = [date stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
相关问题