3

在 iOS 设置应用程序中,有一个名为“时区支持”的设置(设置 > 邮件、通讯录、日历 > 时区支持)。如果此设置为OFF,则没有问题。此外,如果此设置为ON,但时区支持 (TZS) 时区设置为 的当前值systemTimeZone,也没有问题。 唯一出现问题的情况是设置为ON并且 TZS 时区设置为systemTimeZone.

在最后一种情况下,eventsMatchingPredicate:方法返回的数组(在EKEventStore类的实例上)可以预见地被截断。给定一个日期范围内的所有事件的查询,EKEventStore失败的实例返回查询范围的开始和 TZS 时区的第一个午夜之间的任何事件。

举个例子,要检索 2013 年 3 月 18 日的所有事件,可以在systemTimeZone. 假设systemTimeZone是 PDT,这将导致查询 2013 年 3 月 18 日 7AM GMT 到 3/19/2013 7AM GMT 之间的所有事件(因为 PDT 是 GMT - 7 小时)。此查询在 TZS OFF 以及 TZS ON 并设置为 PDT 时工作正常。但是,如果 TZS 为 ON 并设置为 EDT,则查询范围开始到 EDT 第一个午夜之间的所有事件都将从结果数组中丢失。由于 EDT 是 GMT - 4 小时,因此查询范围内 EDT 的第一个午夜是 3/19/2013 4AM GMT。格林威治标准时间 2013 年 3 月 18 日上午 7 点和格林威治标准时间 2013 年 3 月 19 日凌晨 4 点之间的所有事件都将丢失,结果数组将仅包含格林尼治标准时间 2013 年 3 月 19 日凌晨 4 点和格林威治标准时间 2013 年 3 月 19 日上午 7 点之间的事件。

这个结果是 100% 可预测的,无论是在模拟器上还是在物理 iOS 设备上(我尝试过的任何 TZS 时区)。我在 iOS 6 和 iOS 6.1 上进行了测试,在行为上没有明显差异。有什么理由让我错过了为什么这可能是预期的 API 行为?此外,尽管进行了很多搜索,但似乎没有一个公共(甚至私有)API 允许开发人员确定 TZS 是打开还是关闭,更不用说用户设置的任何时区 - 很难想到一个很好的解决方法...(显然,您可以通过增加每个查询的范围来确保不会错过任何事件,以便它始终包含任何可能的 TZS 时区中的午夜。然后,您可以过滤掉无关事件在代码中。然而,出于显而易见的原因,

4

1 回答 1

1

我有一个类似的问题,在结果中没有返回给定 NSDate 范围的第一天的某些事件。我发现这[EKEventStore eventsMatchingPredicate]似乎受到默认时区的影响。这种解决方法最终帮助了我:

NSTimeZone *savedTimeZone = [NSTimeZone defaultTimeZone];
[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendars];
[NSTimeZone setDefaultTimeZone:savedTimeZone];
NSArray *events = [eventStore eventsMatchingPredicate:predicate];

我希望这对您的特定情况也有帮助(在我的情况下,用户的日期/时区与应用程序中的默认时区不同,在您的情况下,日历时间支持已启用,但可能相同'predicateForEventsWithStartDate' 的场景)

在我看来,这是一个错误或设计缺陷,[EKEventStore eventsMatchingPredicate]因为给定的 NSDates 已经“无时区”,因为它们表示一个时间点,与时区无关。

于 2013-03-28T22:20:59.270 回答