iPhone - 获取给定地点/时区的当前日期和时间并将其与同一地点的另一个日期/时间进行比较的正确方法

发布于 2024-12-04 07:08:34 字数 467 浏览 3 评论 0原文

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

以巴黎为例,时间为 GMT+1。现在,由于夏令时,巴黎也可以是 GMT+2,但据我所知,这是例外的一部分,因此必须将其考虑到答案中,但不能将其视为一般参数。这里重要的词是“给定位置”。

因此,如果我想知道澳大利亚悉尼或法国巴黎的日期和时间,并将该日期放入 NSDate 中,以便能够将其与代表同一地点的另一个日期/时间的另一个 NSDate 进行比较,如何我可以做吗?

我已经阅读了一页又一页带有评论的问题和答案,即使是已接受的答案,也来自有经验的用户:不是一个好的答案-1,错误,不是正确的做法,绝对错误,...

所以,你知道正确的真正方法吗?

在完美的世界中,即使用户的手机不处于最佳时间和/或日期和/或时区,或者任何可以接近完美的东西,该日期/时间也将是绝对的,而不需要连接到日期/时间服务器。

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".

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 ?

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, ...

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

山有枢 2024-12-11 07:08:34

我正在寻找获取给定地点/时区的实际日期和时间的正确方法。

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

NSDate 对象表示一个绝对时间点。考虑以下示例,了解不同时区的两个日期表示方式(巴黎的 9/9/11 3:54 PM9/9/11 11:悉尼下午 54 点)实际上是同一日期。

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?");
}

它会记录最后一条消息,因为巴黎的 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

当输出日期时,请记住 < code>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

好的,但是如果我想知道那个时间是否在 15:00 之后,我该如何测试呢?

创建一个表示今天 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");
}

事实证明 @Oliver 需要检查它是否是巴黎 15:00 之后,因此他需要创建代表巴黎时间今天 15:00(非当地时间)的日期。有关如何执行此操作的示例,请参阅@Oliver 的答案。需要明确的是,我的第三段代码展示了如何检查它是否在当地时间 15:00 之后。

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 where you are. NSDates are not subject to places or time zones. There is just one NSDate that represents now or 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 objects represent an absolute instant in time. Consider the following example of how two date representations in different time zones (9/9/11 3:54 PM in Paris and 9/9/11 11:54 PM in Sydney) are actually the same 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?");
}

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.

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

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 *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 ?

Create an NSDate object that represents today at 15:00 (local time) and compare it to "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");
}

It turns out @Oliver needed to check if it is after 15:00 in Paris so 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.

独行侠 2024-12-11 07:08:34

经过一番头痛并开始了解 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);

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

但是,据我所知和测试,那一天/时间并不是绝对的。它基于 iPhone 日期/时间/时区,这可能是错误的。

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 ?

// 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

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.

岁月苍老的讽刺 2024-12-11 07:08:34

使用 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]);

新日期: 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]);

新日期: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

新时间间隔:337251730

Use NSCalendar, and the setTimeZone method.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文