3

I need to make entries in the iPhone calendar, using EventKit framework.

Since my app should be international, I need to take care of differnt timezones. What I am doing right now:

An event should start at 6:00 am. Therefore I am creating a NSDate object with this code:

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

What I get is a NSDate object with 06:00 am and timezone GMT.

When using this NSDate as startDate of the event, I want to use the systems timezone, to make sure that the event is really shown as 06:00 am in the calendar.

Therefore I use this code:

+(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; 
}

As example, I change my devices timezone to NEW YORK. If I debug into the code, It correctly recognizes the timezone and an offset of -14400 seconds. So my start and end NSDate objects seems to be correct.

If I look into the calendar, the app created an event, that does not start at 06:00 am, but at 04:00 am.

What am I doing wrong ??

EDIT: My code to create the event:

Example for creating an event from 06:00 am to 08:00 am

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];

The deletion of the existing events is not shown, but this is tested and works.

Drunk
  • 31
  • 3

1 Answers1

2

If you want to retain the time for the system time zone then do this,

+(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;
}

But I think you should be looking at localTimeZone and not systemTimeZone. If it is the other, you can just change it in the snippet above.

EDIT

Why do you need to get the date in GMT and then convert it? Can't you directly do this?

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];

followed by creating and saving the EKEvent instance.

Deepak Danduprolu
  • 44,595
  • 12
  • 101
  • 105
  • Unfortunately it doesn't work. I am getting 12:00PM in calendar (for NEW YORK timezone) what should be 06:00 AM. This is the same when using systemTimeZone an localTimeZone – Drunk Jun 26 '11 at 09:13
  • @Drunk What are you getting. Can you add `NSLog(@"%@ %@", sourceDate, myDate);` before the return statement and tell me what it prints? – Deepak Danduprolu Jun 26 '11 at 09:15
  • I am gettingSource: 2011-06-26 06:00:00 AM GMT Converted: 2011-06-26 10:00:00 AM GMT on my device where I set New York as timezone – Drunk Jun 26 '11 at 09:28
  • 10:00:00 AM GMT is what you want if NY is -0400 GMT. It is the intended result. – Deepak Danduprolu Jun 26 '11 at 09:38
  • But I want the iPhone calendar to display 06:00 AM. What do I have to do ? – Drunk Jun 26 '11 at 09:42
  • I doesn't display it within my app. I simply want to export events to the systems calendar. When I open up the systems calendar I see 10:00 AM but want to see 06:00 AM – Drunk Jun 26 '11 at 09:47
  • How and when are you updating it? – Deepak Danduprolu Jun 26 '11 at 09:48
  • I'm saving the eventidentifier. When the next export is done, all existing events with the saved identifiers are deleted first. Afterwards the (possibly) updated events are entered again. – Drunk Jun 26 '11 at 09:50
  • It would great if you can show some code (add an edit to the problem). Otherwise this is too vague to see if there is something that needs to be fixed in the process. – Deepak Danduprolu Jun 26 '11 at 09:55
  • @Drunk Updated my answer. I suggest you do it directly. – Deepak Danduprolu Jun 26 '11 at 10:28
  • @Deepak: Thanks for your answer, but unfortunately it doesn't work again. I tried your solution with the dateComponents. In the calendar, now I see an event from 12 pm to 2 pm. If i call the convertToSystemTime before setting the dates on the event, I get 4 pm to 6 pm in the calendar. It's really frustrating – Drunk Jun 26 '11 at 10:37
  • Can you tell me how you are validating this? When are you changing the time zone and when are you setting the event? – Deepak Danduprolu Jun 26 '11 at 10:48
  • I got a 3GS test device where I go to preferences. I set the language to ENGLISH. Then I set the time zone in the preferences to "New York" (set automatically OFF). No I start my app and do the export. Afterwards I start the device calender and look what my app did – Drunk Jun 26 '11 at 11:14
  • 1
    Ok. Figured out your problem. I think. Go to the `Settings` app and select `Mail, Contacts, Calendars` from the menu. Scroll to the bottom where you will see the `Calendars` section. Tap on `Time Zone Support`. Now this seems to be enabled by default and thus shows your calendar in a particular Time Zone. Set it to `NO` so that calendar shows you as per your `Date Time` settings. – Deepak Danduprolu Jun 26 '11 at 11:40
  • That was the problem ! Thank you soo much for solving this issue ! – Drunk Jun 26 '11 at 12:04