NSDate在从字符串转换时返回不同的值 - 与GMT无关

时间:2013-07-17 20:40:49

标签: ios nsdate

我希望这不是GMT相关的,否则我会觉得相当愚蠢。

2个快速相关的问题。为什么这个转换到另一个日期?正在失去一天。我查看了其他答案中所述的时区,但它总是GMT时区 0000 这是我的预期。我认为错误在我的 setDateFormat 中,但我看不出如何解决它。

NSString *stringFromDate = self.dateLabel.currentTitle;
NSLog(@"StringFromDateWeight! %@", stringFromDate);

NSDateFormatter *df = [[NSDateFormatter alloc] init];
//Convert Back to NSDate
[df setDateFormat:@"ddMMyyyy"];

NSDate *inputedDate = [df dateFromString: stringFromDate];
NSLog(@"StringFromDateWeight2! %@", inputedDate);

NSLog(@"StringFromDateWeight! %@", stringFromDate);
17072013

NSLog(@"StringFromDateWeight2! %@", inputedDate); is  

2013-07-16 23:00:00 +0000

我也使用下面的代码来比较2个日期,我是否正确,它会在几秒钟后返回?如何将其更改为在几天内返回?

int intervall = (int) [theDate timeIntervalSinceDate: now];

1 个答案:

答案 0 :(得分:4)

如果您未明确设置时区NSDateFormatter,则会使用您当地的时区。您没有设置一个,因此格式化程序将在您的时区创建一个位于“7月17日午夜”的NSDate。 NSDate的description方法将返回以UTC时区格式化的日期。由于你得到“7月16日23:00:00”,我猜你的时区是UTC + 1。

您有两种选择。通过显式设置时区以UTC计算。

df.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];

或者,通常更有用,不要查看NSDate的description并使用[inputedDate descriptionWithLocale:[NSLocale currentLocale]]进行调试,这将打印为您的时区格式化的日期。
如果要向用户显示日期,请使用另一个NSDateFormatter(最好使用dateStyle和timeStyle而不是dateFormat,因为hardcoded dateFormats are evil

只是显示不同,底层的NSDate对象仍然是相同的。


关于你的第二个问题:

在许多时区,每年有2天没有24小时,因此您无法使用timeIntervalSinceDate:获得的秒数计算任何内容。

您必须使用NSDateComponentsNSCalendar。幸运的是,已经有一种方法可以完全满足您的需求。 components:fromDate:toDate:options:

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:inputedDate toDate:[NSDate date] options:0];
NSLog(@"Date was %d days (and %d hours, %d minutes and %d seconds) ago", components.day, components.hour, components.minute, components.second);

如果您只需要删除除NSDayCalendarUnit

以外的所有组件的天数