Подтвердить что ты не робот

IPhone - правильный способ получения текущей даты и времени для данного места/часового пояса и сравнить его с другой датой/временем в одном и том же месте

Я ищу правильный способ получить фактическую дату и время для данного места/часовой пояс и возможность сравнить его с определенной датой/временем для того же места.

Скажем, например, Париж, то есть GMT +1. Поскольку мы сейчас, Париж также может быть GMT + 2 из-за летнего времени, но он является частью исключения, насколько я знаю, поэтому он должен учитываться в ответе, но не приниматься за общий параметр. Важные слова здесь "заданные места".

Итак, если я хочу знать, какая дата и время в Sidney Australia или Paris France, и получить эту дату в NSDate, чтобы сравнить ее с другим NSDate, который будет представлять другую дату/время в том же место, как я могу сделать?

Я читал страницы и страницы вопросов и ответов с комментариями, даже на принятом ответе, который говорит от опытных пользователей: не хороший ответ -1, неправильный, а не правильный способ сделать это, абсолютно неправильно,...

Итак, знаете ли вы правильный реальный способ сделать это?

В идеальном мире эта дата/время будет абсолютной, даже если пользовательский телефон не находится в удобное время и/или дата и/или часовой пояс, или все, что может быть рядом с этим совершенством, без необходимости подключения к нему сервер даты/времени.

4b9b3361

Ответ 1

После большой головной боли и начала понимать, что такое 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, который может быть неправильным.

Ответ 2

Я ищу правильный способ получить фактическую дату и время для определенного места/часового пояса.

[NSDate date] возвращает объект даты, представляющий текущую дату и время, независимо от того, где вы находитесь. NSDate не подлежат местам или часовым поясам. Существует только один NSDate, который представляет сейчас или любой другой момент в этом отношении, а не разные объекты даты для каждого временного часового пояса. Поэтому вам не следует пытаться преобразовать дату между часовыми поясами.

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

Он регистрирует это последнее сообщение, потому что 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

ok, но если я хочу знать, будет ли это время после 15:00, как я могу проверить это?

Создайте объект NSDate, который представляет сегодня в 15:00 (по местному времени) и сравните его с "сейчас":

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 по местному времени.

Ответ 3

Используйте 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