Проблема NSTimezone с использованием EventKit - PullRequest
3 голосов
/ 26 июня 2011

Мне нужно делать записи в календаре iPhone, используя каркас EventKit.

Поскольку мое приложение должно быть международным, мне нужно позаботиться о разных часовых поясах. Что я сейчас делаю:

Мероприятие должно начаться в 6:00 утра. Поэтому я создаю объект NSDate с этим кодом:

[NSDate dateWithString:[NSString stringWithFormat:@"%d-%d-%d %d:%d:00 +0000",year,month,day,hour,minute]];

Я получаю объект NSDate с 06:00 утра и часовым поясом по Гринвичу.

При использовании этого NSDate в качестве startDate события я хочу использовать системный часовой пояс, чтобы убедиться, что событие действительно отображается как 06:00 утра в календаре.

Поэтому я использую этот код:

+(NSDate*) convertToSystemTimezone:(NSDate*)sourceDate
{   
    NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];  
    NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
    NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
    NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;   
    NSDate* destinationDate = [[[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate] autorelease];         
    return destinationDate; 
}

Как пример, я изменяю часовой пояс моих устройств на НЬЮ-ЙОРК. Если я отлаживаю в коде, он правильно распознает часовой пояс и смещение -14400 секунд. Так что мои объекты начала и окончания NSDate кажутся правильными.

Если я загляну в календарь, приложение создало событие, которое начинается не в 06:00, а в 04:00.

Что я делаю не так ??

РЕДАКТИРОВАТЬ: Мой код для создания события:

Пример создания события с 06:00 до 08:00

int year=2011;
int month=6;
int day=26;
int hour=6;
int minute=0;

NSDate *startDate = [NSDate dateWithString:[NSString stringWithFormat:@"%d-%d-%d %d:%d:00 +0000",year,month,day,hour, minute];  
startDate=[self convertToSystemTimezone:startDate];

NSDate *endDate = [NSDate dateWithString:[NSString stringWithFormat:@"%d-%d-%d %d:%d:00 +0000",year,month,day,8, minute];   
endDate=[self convertToSystemTimezone:endDate];     

EKEventStore *eventDB = [[EKEventStore alloc] init];
EKEvent *myEvent  = [EKEvent eventWithEventStore:eventDB];      
myEvent.title  = @"Testevent";
myEvent.startDate = startDate;
myEvent.endDate   = endDate;
myEvent.allDay = NO;
[myEvent setCalendar:[eventDB defaultCalendarForNewEvents]];
NSError *err;                   
[eventDB saveEvent:myEvent span:EKSpanThisEvent error:&err];
[eventDB release];

Удаление существующих событий не отображается, но это проверено и работает.

1 Ответ

2 голосов
/ 26 июня 2011

Если вы хотите сохранить время для системного часового пояса, сделайте это,

+(NSDate*) convertToSystemTimezone:(NSDate*)sourceDate {
    NSCalendar * calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
    [calendar setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];

    NSUInteger flags = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit );
    NSDateComponents * dateComponents = [calendar components:flags fromDate:sourceDate];

    [calendar setTimeZone:[NSTimeZone systemTimeZone]];
    NSDate * myDate = [calendar dateFromComponents:dateComponents];

    return myDate;
}

Но я думаю, что вы должны смотреть на localTimeZone, а не systemTimeZone. Если это другой, вы можете просто изменить его в приведенном выше фрагменте.

EDIT

Зачем вам нужно получать дату в GMT, а затем конвертировать ее? Вы не можете сделать это напрямую?

NSCalendar * calendar = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];

NSDateComponents * dateComponents = [[[NSDateComponents alloc] init] autorelease];
[dateComponents setYear:2011];
[dateComponents setMonth:6];
[dateComponents setDay:26];
[dateComponents setHour:6];
[dateComponents setMinute:0];

NSDate * startDate = [calendar dateFromComponents:dateComponents];

[dateComponents setHour:8];
NSDate * endDate = [calendar dateFromComponents:dateComponents];

с последующим созданием и сохранением экземпляра EKEvent.

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