iphone - 使用 EventKit 的 NSTimezone 问题

标签 iphone objective-c cocoa-touch eventkit

我需要使用 EventKit 框架在 iPhone 日历中创建条目。

由于我的应用程序应该是国际化的,因此我需要照顾不同的时区。 我现在在做什么:

事件应在早上 6:00 开始。 因此我用这段代码创建了一个 NSDate 对象:

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

我得到的是一个带有 06:00 am 和 GMT 时区的 NSDate 对象。

当使用这个 NSDate 作为事件的开始日期时,我想使用系统时区,以确保事件在日历中真正显示为早上 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 am 到 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];

现有事件的删除未显示,但这已经过测试并且有效。

最佳答案

如果你想保留系统时区的时间,那么这样做,

+(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。如果是另一个,您可以在上面的代码片段中更改它。

编辑

为什么需要获取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 实例。

关于iphone - 使用 EventKit 的 NSTimezone 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6483008/

相关文章:

ios - 如何在使用自定义单元格的 UICollectionView 中正确设置异步图像下载?

ios - 如何通过 IBAction 从带有动画的 tableView 中删除单元格? iOS swift 3.0

ios - 自定义 iOS 状态栏颜色

iphone - 如何在没有服务器的情况下使用iPhone自动续订

ios - 如何根据内容动态调整 UICollectionViewCell 的高度?

ios - UIScrollView 如果有动画则滚动到不同的位置

ios - 在适当的部分动态添加行而不干扰其排序

iOS 数据存储问题 - 即使在 NSURLIsExcludedFromBackupKey 之后也被拒绝

objective-c - AVAudioPlayer 立即停止播放 ARC

objective-c - 如何深度复制 NSDictionaries 的 NSArray?