使用 DateComponents 减去 2 个日期给出未定义的行为

Subtracting 2 Dates using DateComponents gives undefined behavior

鉴于我在扩展中添加到 Date 对象的以下方法:

extension Date {
    static func -(left: Date, right: Date) -> DateComponents {
        let components: Set<Calendar.Component> = [
            .year,
            .month,
            .day,
            .hour,
            .minute,
            .second,
            //.weekOfYear, // issue!
        ]

        let gregorian = Calendar(identifier: .gregorian)
        let dateComponents = gregorian.dateComponents(components, from: right, to: left)
        return dateComponents 
    }
}

给定以下日期(格式为月日,年,hh:mm:ss)你得到 1:

let day1 = Date(timeIntervalSince1970: 1516003200) // January 15, 2018, 00:00:00
let day2 = Date(timeIntervalSince1970: 1516089600) // January 16, 2018, 00:00:00
let diff = day2 - day1
print(diff.day!) // 1

但是给定以下日期,您还会得到 1:

let day3 = Date(timeIntervalSince1970: 1515916800) // January 14, 2018, 00:00:00
let day4 = Date(timeIntervalSince1970: 1516089600) // January 16, 2018, 00:00:00
let diff2 = day4 - day3
print(diff.day!) // 1

所以我的第一个问题是想知道为什么即使一对相隔 1 天而另一个相隔 2 天,但天差是相同的。

最后,根据以下日期,您得到正确的数字 14:

let day5 = Date(timeIntervalSince1970: 1516089600) // January 16, 2018, 00:00:00
let day6 = Date(timeIntervalSince1970: 1517299200) // January 30, 2018, 00:00:00
let diff3 = day6 - day5
print(diff3.day!)

但是,如果您要返回 static func -(left:right:) 并取消注释 .weekOfYear 并使用 day5day6 重新 运行 上面的代码块,您得到0天。所以我的第二个问题是 为什么如果我将 .weekOfYear 组件添加到集合中,我得到 0 天。

我在下面放了两个游乐场的截图,第一个 .weekOfYear 不包括在内,第二个包括 .weekOfYear:

在下面的代码中

let day3 = Date(timeIntervalSince1970: 1515916800) // January 14, 2018, 00:00:00
let day4 = Date(timeIntervalSince1970: 1516089600) // January 16, 2018, 00:00:00
let diff2 = day4 - day3
print(diff.day!) // 1

你正在使用 diff.day 而实际上你应该使用 diff2.day

至于您的第二期,日历将 return 日期组件按从最大值到最小值的顺序分配。也就是说当你加上weekOfYear的时候,它给weekOfYear赋值2。如果你要打印出 diff3.weekOfYear,你会得到 2(因为日期是 2 周)。由于日期转换为周后没有剩余天数,因此 diff3.day 为 0 天。如果您要使用日期 Jan 16thJan 31st,您会得到一个值 2 表示星期,1 表示日