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

时间:2018-03-13 21:18:34

标签: ios swift

今天是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". E.g. "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 change。我已经尝试了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)!

Bug report已根据建议提交。

2 个答案:

答案 0 :(得分:1)

这可能是一个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)!

enter image description here

答案 1 :(得分:0)

另一种选择是从“今天”减去七天,然后只搜索.forward。就个人而言,由于此DST问题以及this other post,我不会搜索.backward

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)!