计算上一个星期日DST在前一个星期日更改的时间

今天是2018年3月13日星期二。上一个星期天是2018年3月11日。我计算上周日的代码是:

// NOTE that this particular code block may return the correct result for you IF your timezone // is something other than "America/Chicago". Eg "America/Belize". Use the longer code // block that begins with "var calendar = ..." if you are trying to replicate the issue Calendar.current.nextDate(after: Date(), matching: DateComponents(weekday: 1), matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .backward)! 

这将返回3月4日的日期,而不是3月11日的预期值。 这是由于DST的变化 。 我已经尝试了matchingPolicyrepeatedTimePolicy每个组合,但它总是返回3月4日。 有关如何让日历在3月11日返回的任何想法?

 var calendar = Calendar(identifier: .gregorian) calendar.locale = Locale(identifier: "en_US") calendar.timeZone = TimeZone(identifier: "America/Chicago")! // Tuesday March 13th @ 3:10 PM (America/Chicago) let today = Date(timeIntervalSince1970: 1520971846) let d1 = calendar.nextDate(after: today, matching: DateComponents(weekday: 1), matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .backward)! let d2 = calendar.nextDate(after: today, matching: DateComponents(weekday: 1), matchingPolicy: .nextTimePreservingSmallerComponents, repeatedTimePolicy: .first, direction: .backward)! let d3 = calendar.nextDate(after: today, matching: DateComponents(weekday: 1), matchingPolicy: .previousTimePreservingSmallerComponents, repeatedTimePolicy: .first, direction: .backward)! let d4 = calendar.nextDate(after: today, matching: DateComponents(weekday: 1), matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .backward)! let d5 = calendar.nextDate(after: today, matching: DateComponents(weekday: 1), matchingPolicy: .nextTime, repeatedTimePolicy: .last, direction: .backward)! let d6 = calendar.nextDate(after: today, matching: DateComponents(weekday: 1), matchingPolicy: .nextTimePreservingSmallerComponents, repeatedTimePolicy: .last, direction: .backward)! let d7 = calendar.nextDate(after: today, matching: DateComponents(weekday: 1), matchingPolicy: .previousTimePreservingSmallerComponents, repeatedTimePolicy: .last, direction: .backward)! let d8 = calendar.nextDate(after: today, matching: DateComponents(weekday: 1), matchingPolicy: .strict, repeatedTimePolicy: .last, direction: .backward)! 

根据建议提交了错误报告 。

正如上面的评论所说,这可能是一个Apple漏洞。

通过首先找到“下一个”星期日,然后使用该日期查找上一个星期日,有一个非常难看的解决方法。 我确信有一些边缘情况不会起作用,但也许它可能对你有所帮助。

 // Not recommended for production code var nextSunday = Calendar.current.nextDate(after: Date(), matching: DateComponents(weekday: 1), matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .forward)! var lastSunday = Calendar.current.nextDate(after: nextSunday, matching: DateComponents(weekday: 1), matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .backward)! 

在此处输入图像描述

另一个选择是从“今天”减去七天,然后只搜索.forward 。 就个人而言,由于这个DST问题并且由于这个其他post ,我不会搜索。

 var calendar = Calendar(identifier: .gregorian) calendar.locale = Locale(identifier: "en_US") calendar.timeZone = TimeZone(identifier: "America/Chicago")! // Tuesday March 13th @ 3:10 PM (America/Chicago) var date = Date(timeIntervalSince1970: 1520971846) date = calendar.date(byAdding: .day, value: -7, to: date)! //or = calendar.date(byAdding: .weekOfYear, value: -1, to: date)! let lastSunday = calendar.nextDate(after: date, matching: DateComponents(weekday: 1), matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .forward)!