Oli*_*ver 17 iphone timezone datetime cocoa-touch ios
我正在寻找正确的方法来获得给定地点/时区的实际日期和时间,并能够将其与同一地点的给定日期/时间进行比较.
让我们说,例如,巴黎,即GMT +1.就像我们现在一样,由于夏令时,巴黎也可以是GMT + 2,但据我所知,这是一个例外的一部分因此必须考虑到答案,但不能作为一般参数.这里重要的词是"给定的地方".
所以,如果我想知道它在Sidney Australia或Paris France的日期和时间,并将该日期纳入NSDate,以便能够将其与另一个代表同一地点的另一个日期/时间的NSDate进行比较,如何我可以吗?
我已经阅读了一些问题和答案的页面和页面,其中包括评论,甚至是已接受的答案,这些都来自有经验的用户:不是一个好的答案-1,错误的,不是正确的做法,绝对错误,......
那么,你知道正确的方法吗?
在一个完美的世界中,即使用户的手机没有处于良好的时间和/或日期和/或时区,或者任何可以接近完美的任何东西而不需要连接到日期/时,该日期/时间将是绝对的时间服务器.
alb*_*amg 34
我正在寻找正确的方法来获得给定地点/时区的实际日期和时间.
[NSDate date]无论您身在何处,都会返回表示当前日期和时间的日期对象.NSDates不受地点或时区限制.只有一个的NSDate表示现在或任何其他时刻为此事,而不是每次时区不同日期的对象.因此,您不应尝试在时区之间转换日期.
NSDate对象代表一个绝对的瞬间.请考虑以下示例,说明不同时区(巴黎和悉尼)的两个日期表示实际上是同一个日期.9/9/11 3:54 PM9/9/11 11:54 PM
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?");
}
Run Code Online (Sandbox Code Playgroud)
它记录了最后一条消息,因为9/9/11 3:54 PM在巴黎和9/9/11 11:54 PM悉尼实际上是同一时刻.当它9/9/11 3:54 PM在巴黎时,它9/9/11 11:54 PM在悉尼.
两者都给出了调试器和NSLog 2011-09-09 14:26:02,但它现在是16:26所以我猜它应该返回16:26:02 +0200
当涉及到输出的日期,谨记NSDate的description方法返回时间GMT,你需要使用一个NSDateFormatter创建表示从日期在巴黎,悉尼等本地时间日期字符串:
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
Run Code Online (Sandbox Code Playgroud)
好的,但如果我想知道这个时间是否在15:00之后,我该如何测试呢?
创建一个今天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");
}
Run Code Online (Sandbox Code Playgroud)
事实证明@Oliver需要检查它是否在巴黎15:00之后,所以他需要创建一个代表今天巴黎时间15:00(不是当地时间)的日期.有关如何执行此操作的示例,请参阅@ Oliver的答案.为了清楚起见,我的第三段代码显示了如何检查它是否在当地时间15:00之后.
Oli*_*ver 12
经过一番头痛并开始了解NSDate是什么之后,我想到了那种解决方案.您如何看待这种做法?
// 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);
Run Code Online (Sandbox Code Playgroud)
一些参考:http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtTimeZones.html#//apple_ref/doc/uid/20000185-SW4
但是,据我所知和测试,那天/时间不可能是绝对的.它基于iPhone日期/时间/时区,这可能是错误的.
使用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]);
Run Code Online (Sandbox Code Playgroud)
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]);
Run Code Online (Sandbox Code Playgroud)
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]);
Run Code Online (Sandbox Code Playgroud)
newDate:2011-09-09 08:52:03 +0000
newTimeInterval:337251730