ios iPhone - 获取给定地点/时区的当前日期和时间并将其与同一地点的另一个日期/时间进行比较的正确方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7362199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iPhone - Correct way for getting current date and time for a given place / timezone and compare it with another date/time in the same place
提问by Oliver
I'm searching the correct way to get the actual date and time for a given place / timezone, and being able to compare it to a given date/time for that same place.
我正在寻找正确的方法来获取给定地点/时区的实际日期和时间,并能够将其与同一地点的给定日期/时间进行比较。
Let's say, for the example, Paris, that is GMT +1. As we now, Paris can also be GMT+2 because of daylight saving, but it's part of an exception as far as I know so it must be taken in account into the answer, but not taken as a general param. The important words here are "given place".
假设以巴黎为例,即格林威治标准时间 +1。正如我们现在一样,由于夏令时,巴黎也可以是 GMT+2,但据我所知,这是例外的一部分,因此必须将其考虑到答案中,但不能将其视为一般参数。这里的重要词是“给定的地方”。
So, if I want to know what date and time it is at Sidney Australia, or Paris France, and get that date into an NSDate for being able to compare it with another NSDate that would represent another date/time in the same place, how may I do ?
因此,如果我想知道它在澳大利亚悉尼或法国巴黎的日期和时间,并将该日期放入 NSDate 以便能够将其与另一个代表同一地点的另一个日期/时间的 NSDate 进行比较,如何我可以吗?
I've read pages and pages of questions and answers with comments, even on accepted answer, that says from experienced users : not a good answer -1, wrong, not the correct way of doing this, absolutely wrong, ...
我已经阅读了一页又一页的带有评论的问题和答案,即使是在接受的答案上,经验丰富的用户也说:不是一个好的答案 -1,错误,不是正确的做法,绝对错误,......
So, do you know the correct real way to do that ?
那么,您知道这样做的正确方法吗?
In a perfect world, that date/time would be absolute even if the user's phone is not at the good time and/or date and/or timezone, or anything that can be near that perfection without needing for that to connect to a date/time server.
在一个完美的世界中,即使用户的手机不在合适的时间和/或日期和/或时区,或者任何可以接近完美而无需连接到日期的任何东西,该日期/时间也是绝对的/时间服务器。
采纳答案by Oliver
After a big headache and starting to understand what NSDate is, I imagined that kind of solution. What do you think about that way of doing ?
在头疼并开始了解 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);
Some reference : http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtTimeZones.html#//apple_ref/doc/uid/20000185-SW4
一些参考:http: //developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtTimeZones.html#//apple_ref/doc/uid/20000185-SW4
But, as far as I know and tested, that day/time cannot be really absolute. It is based on the iPhone date/time/timezone, that can be wrong.
但是,据我所知和测试,那一天/时间并不是绝对的。它基于 iPhone 日期/时间/时区,这可能是错误的。
回答by albertamg
I'm searching the correct way to get the actual date and time for a given place / timezone.
我正在寻找正确的方法来获取给定地点/时区的实际日期和时间。
[NSDate date]
returns a date object representing the current date and time, no matter whereyou are. NSDate
s are not subject to places or time zones. There is just one NSDate that represents nowor any other moment for that matter, not different date objects for every time timezone. Therefore, you should not attempt to convert a date between time zones.
[NSDate date]
无论您身在何处,都返回一个表示当前日期和时间的日期对象。NSDate
s 不受地点或时区的限制。只有一个 NSDate 代表现在或任何其他时刻,而不是每个时区的不同日期对象。因此,您不应尝试在时区之间转换日期。
NSDate
objects represent an absoluteinstant in time. Consider the following example of how two date representationsin different time zones (9/9/11 3:54 PM
in Paris and 9/9/11 11:54 PM
in Sydney) are actually the samedate.
NSDate
对象代表时间上的绝对瞬间。考虑以下示例,说明不同时区(巴黎和悉尼)中的两个日期表示实际上是相同的日期。9/9/11 3:54 PM
9/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?");
}
It logs that last message because 9/9/11 3:54 PM
in Paris and 9/9/11 11:54 PM
in Sydney are actually the same instant in time. When it is 9/9/11 3:54 PM
in Paris, it is 9/9/11 11:54 PM
in Sydney.
它记录了最后一条消息,因为9/9/11 3:54 PM
在巴黎和9/9/11 11:54 PM
悉尼实际上是同一时刻。当它9/9/11 3:54 PM
在巴黎时,它9/9/11 11:54 PM
在悉尼。
both gives in the debugger and NSLog 2011-09-09 14:26:02, but it's now 16:26 so I guess it should return 16:26:02 +0200
两者都在调试器和 NSLog 2011-09-09 14:26:02 中给出,但现在是 16:26,所以我想它应该返回 16:26:02 +0200
When it comes to output a date, bear in mind that NSDate
's description
method returns time in GMT and you need to use a NSDateFormatter
to create a date string representing the local time in Paris, Sydney, etc. from a date:
在输出日期时,请记住NSDate
'sdescription
方法返回格林威治标准时间的时间,您需要使用 aNSDateFormatter
来创建表示巴黎、悉尼等本地时间的日期字符串:
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
ok, but if I want to know if that time is after 15:00, how may I test that ?
好的,但是如果我想知道那个时间是否在 15:00 之后,我该如何测试?
Create an NSDate object that represents today at 15:00 (local time) and compare it to "now":
创建一个代表今天 15:00(当地时间)的 NSDate 对象并将其与“现在”进行比较:
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");
}
It turns out @Oliver needed to check if it is after 15:00 in Parisso he needed to create a date that represents today at 15:00 Paris time (not local time). For an example on how to do that, see @Oliver's answer. Just to be clear, my third snippet of code shows how to check if it is after 15:00 local time.
事实证明,@Oliver 需要检查它是否在巴黎 15:00 之后,因此他需要创建一个代表今天巴黎时间 15:00(不是当地时间)的日期。有关如何执行此操作的示例,请参阅 @Oliver 的回答。为了清楚起见,我的第三段代码展示了如何检查它是否在当地时间 15:00 之后。
回答by zaph
Use NSCalendar, and the setTimeZone
method.
使用 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
新日期:2011-09-09 15:02:09 +0000 新
日期: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
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
newDate: 2011-09-09 08:52:03 +0000
newTimeInterval: 337251730