iPhone的 – 正确的方式获取当前的date和时间给定的地点/时区,并与另一个date/时间在同一地点比较

我正在寻找正确的方法来获得给定地点/时区的实际date和时间,并且能够将它与同一地点的给定date/时间进行比较。

比方说,例如巴黎,那就是GMT +1。 就像我们现在的情况一样,由于夏令时间的原因,巴黎也可以是GMT + 2,但是据我所知,它是一个例外的一部分,因此必须考虑到答案,而不是一般的参数。 这里的重要词汇是“给定的地方”。

那么,如果我想知道在悉尼澳大利亚或法国巴黎的date和时间,并将该date与NSDate进行比较,以便能够将该date与代表另一date/时间的另一个NSDate在同一地点进行比较,我可以吗?

我已经阅读了一些问题和答案的评论页面,甚至在接受的答案,从有经验的用户说:不是一个好的答案-1,错了,而不是这样做的正确方法,绝对错误,…

那么,你知道正确的方法吗?

在一个完美的世界中,即使用户的电话不在适当的时间和/或date和/或时区,或者任何可以接近完美的东西,那个date/时间将是绝对的,而不需要连接到date/时间服务器。

我正在寻找正确的方法来获得给定地点/时区的实际date和时间。

[NSDate date]返回一个代表当前date和时间的date对象,不pipe你在哪里NSDate不受地点或时区的限制。 只有一个NSDate代表现在或任何其他时刻,而不是每个时区的不同date对象。 因此,您不应该尝试在时区之间转换date。

NSDate对象表示绝对即时。 考虑下面的例子,说明不同时区的两个date表示 (巴黎9/9/11 3:54 PM和悉尼9/9/11 11:54 PM )实际上是同一date。

 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateStyle:NSDateFormatterShortStyle]; [formatter setTimeStyle:NSDateFormatterShortStyle]; [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Paris"]]; NSDate *aDate = [formatter dateFromString:@"9/9/11 3:54 PM"]; [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"Australia/Sydney"]]; NSDate *anotherDate = [formatter dateFromString:@"9/9/11 11:54 PM"]; NSLog(@"%@",anotherDate); if ([aDate isEqualToDate:anotherDate]) { NSLog(@"How about that?"); } 

它logging了最后的信息,因为9/9/11 3:54 PM在巴黎,9/9 / 9/9/11 11:54 PM在悉尼实际上是同一时间。 现在是9/9/11 3:54 PM在巴黎,现在是9/9/11 11:54 PM在悉尼。

都在debugging器和NSLog 2011-09-09 14:26:02,但现在是16:26所以我想它应该返回16:26:02 +0200

在输出date时,请记住, NSDatedescription方法会以GMT格式返回时间,您需要使用NSDateFormatter从date创build一个datestring来表示在巴黎,悉尼等地的当地时间:

 NSDate *now = [NSDate date]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateStyle:NSDateFormatterShortStyle]; [formatter setTimeStyle:NSDateFormatterShortStyle]; [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"Australia/Sydney"]]; NSLog(@"%@",[formatter stringFromDate:now]); //--> 9/9/11 11:54 PM [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Paris"]]; NSLog(@"%@",[formatter stringFromDate:now]); //--> 9/9/11 3:54 PM 

好的,但是如果我想知道那个时间是在15:00以后,我该怎么testing呢?

创build一个NSDate对象,在今天15:00(当地时间)表示一个NSDate对象并将其与“now”比较:

 NSDate *now = [NSDate date]; NSCalendar* myCalendar = [NSCalendar currentCalendar]; NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]]; [components setHour: 15]; [components setMinute: 0]; [components setSecond: 0]; NSDate *todayAt15 = [myCalendar dateFromComponents:components]; if ([now compare:todayAt15] == NSOrderedDescending) { NSLog(@"After 15:00 local time"); } 

事实certificate@Oliver需要检查是否在巴黎15:00之后,所以他需要在巴黎时间15:00(不是当地时间)创build一个代表今天的date。 有关如何实现的示例,请参阅@ Oliver的答案。 为了清楚起见,我的第三部分代码显示了如何检查是否在当地时间15:00之后。

在头痛头痛之后,开始了解NSDate是什么,我想到了这样的解决scheme。 你怎么看待这种做法?

 // Now, an absolute date and time that represent now all around the world, that is made to play with NSDate *now = [NSDate date]; // A specific calendar for a specific place in the world NSCalendar* parisCalendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; [parisCalendar setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Paris"]]; // Now components seen from Paris NSDateComponents* componentsNowInParis = [parisCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit|NSTimeZoneCalendarUnit fromDate:now]; // Tricking a copy of "Now components seen from Paris" to force 15:00:00, in Paris NSDateComponents* componentsInParisAt15 = [[componentsNowInParis copy] autorelease]; [componentsInParisAt15 setHour:15]; [componentsInParisAt15 setMinute:0]; [componentsInParisAt15 setSecond:0]; // Getting an universal date reference that represent what could be 15:00:00 seen from paris, Or 19:00:00 from GMT+4 NSDate* dateAt15 = [parisCalendar dateFromComponents:componentsInParisAt15]; // We now have two universal dates that can be compared each other // If "now" is 16:00:00, those date will show a 60 minutes difference all around the world NSLog(@"%@", now); NSLog(@"%@", dateAt15); 

一些参考: http : //developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtTimeZones.html#//apple_ref/doc/uid/20000185-SW4

但是,据我所知和testing,那一天/时间不可能是绝对的。 它基于iPhonedate/时间/时区,可能是错误的。

使用NSCalendar和setTimeZone方法。

 NSDate *newDate; NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:~ NSTimeZoneCalendarUnit fromDate:[NSDate date]]; newDate = [[NSCalendar currentCalendar] dateFromComponents:dateComponents]; NSLog(@"newDate: %@", newDate); NSLog(@"newDate: %.0f", [newDate timeIntervalSinceReferenceDate]); 

newdate:2011-09-09 15:02:09 +0000
newDate:337273330

 [dateComponents setTimeZone:[NSTimeZone timeZoneWithName:@"Australia/Sydney"]]; newDate = [[NSCalendar currentCalendar] dateFromComponents:dateComponents]; NSLog(@"newDate: %@", newDate); NSLog(@"newDate: %.0f", [newDate timeIntervalSinceReferenceDate]); 

newdate:2011-09-09 00:52:03 +0000
newTimeInterval:337222930

 [dateComponents setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Paris"]]; newDate = [[NSCalendar currentCalendar] dateFromComponents:dateComponents]; NSLog(@"newDate: %@", newDate); NSLog(@"newDate: %.0f", [newDate timeIntervalSinceReferenceDate]); 

newdate:2011-09-09 08:52:03 +0000
newTimeInterval:337251730