dateWithTimeIntervalSince1970 не работает при создании события - PullRequest
0 голосов
/ 23 ноября 2011

В моем приложении мне нужно программно создать событие в Календаре, весь алгоритм работает вокруг дат, созданных методом + (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds. Но с помощью этого метода я не могу создать событие, кажется, что внутри него не установлен часовой пояс, потому что с другими методами (т.е. [NSDate date]) событие создается успешно.

Мое решение состояло в том, чтобы преобразовать NSDate в CFGregorianDate, установить часовой пояс и преобразовать обратно. Кажется, я думаю, это немного долго.

Фрагмент кода:

EKEvent *event = [EKEvent eventWithEventStore:eventStore];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:1322045010]; // interval is in seconds

NSLog(@"%@", date);
event.title = @"Test";
event.startDate = date;
event.endDate = date;
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
[event addAlarm:[EKAlarm alarmWithAbsoluteDate:date]];

[eventStore saveEvent:event span:EKSpanThisEvent error:nil];

Итак, мой вопрос - почему невозможно создать событие с NSDate, инициализированным с + (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds? И мог бы кто-нибудь предложить более надежный способ решения этой проблемы, я был бы очень признателен.

Артем

1 Ответ

7 голосов
/ 24 ноября 2011

Ваша ошибка обнаруживается, когда вы говорите следующее: "кажется, что у него где-то не установлен часовой пояс, потому что с другими методами (т.е. [NSDate date]) событие создается успешно."

Нет NSDate содержит информацию о часовом поясе. Все они ссылаются на GMT. Класс NSDateFormatter обычно используется для представления их в местном часовом поясе. И, судя по вашему ответу на комментарии выше, я сомневаюсь, что вы мне сейчас верите Проверьте это, в каком-нибудь методе где-нибудь запустите эту строку кода.

NSLog(@"[NSDate date] = %@",[NSDate date]);

Согласно вашему профилю пользователя вы находитесь в Эстонии. По моему быстрому поиску вы должны быть GMT + 2: 00 (извините, если я ошибаюсь в вашем часовом поясе), поэтому время, которое вы видите в консоли, должно быть на 2 часа меньше. И я уверен, что это так. Так же, как у меня, на 5 часов вперед.

Вы также можете сказать, что я прав по вашему решению: "Мое решение заключалось в преобразовании NSDate в CFGregorianDate, установке часового пояса и обратном преобразовании. Кажется, это немного долго." Так что в основном вы настроили часовой пояс, и он работает нормально, имеет смысл.

Но на ваш реальный вопрос: «Может ли кто-нибудь предложить более надежный способ решения этой проблемы?» Ответ относительно прост.

Допустим, ваш сервер возвращает интервал времени с 1970 года по эстонскому времени (Восточная Европа?). Все, что вам нужно сделать, это настроить этот интервал времени, чтобы указать время по Гринвичу. Опять же, если я ошибаюсь в особенностях вашего часового пояса, я прошу прощения.

NSTimeInterval estoniaTimeZoneDifference = 60*60*2;//60 seconds, 60 minutes, 2 hours
NSDate *adjusted = [NSDate dateWithTimeIntervalSince1970:(timeIntervalSince1970FromServer - estoniaTimeZoneDifference)];
// Here we subtract because this zone is 2 hours ahead of GMT.

Снова эта корректировка будет проиндексирована с ответом сервера.

Редактировать: В ответ на:

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

По словам известного телевизионного персонажа "Вызов принят!".

Поэтому я решил проверить, может ли событие быть успешно создано с использованием dateWithTimeIntervalSince1970:. И, как я и ожидал, я не нашел недостатка в NSDate или в структуре EventKit. Я использовал этот код:

NSTimeInterval rightNowInterval = [[NSDate date] timeIntervalSince1970];
    //NSTimeInterval is a double, thus nothing up my sleeve.
NSTimeInterval intervalSince70ToFire = rightNowInterval + 120;
    // Two minutes from whenever now is. Plus this is another layer of indirection to prove there's no 'magic' to [NSDate date]


    //Create fire date from dateWithTimeIntervalSince1970
NSDate *fireDate = [NSDate dateWithTimeIntervalSince1970:intervalSince70ToFire];

    // Insert boilerplate event code
EKEventStore *eventSotre = [[EKEventStore alloc] init];
EKEvent *event = [EKEvent eventWithEventStore:eventSotre];
event.title= @"Event Title"; 
event.startDate = fireDate;
event.endDate= [[NSDate alloc] initWithTimeInterval:600 sinceDate:event.startDate];
[event addAlarm:[EKAlarm alarmWithAbsoluteDate:fireDate]];
event.calendar = [eventSotre defaultCalendarForNewEvents];
NSError *err = nil;
if([eventSotre saveEvent:event span:EKSpanThisEvent error:&err]){
    UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:@"Event" message:@"Event added in calendar" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertview show];
}
else{
    UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:@"Event" message:[err description] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertview show];
}

Когда я запускаю этот код, я получаю сообщение «Событие добавлено в календарь». Две минуты дают мне достаточно времени, чтобы перейти к календарю и увидеть, что событие на самом деле было правильно спланировано. И выходи и жди, пока сработает мой будильник. И это делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...