以下是我认为是去年6月我向Apple报告的一个错误(错误号41023217),但未收到回复。欢迎任何见解。
摘要:
向后和向前扫描与月份匹配的日期会产生奇怪的结果。正向扫描似乎无法正确处理夏令时。向后扫描会产生有时看似错误的结果。
重现步骤:
在终端中启动swift REPL并运行以下代码:
import Foundation
var now = Date()
var cal = Calendar.current
var comp = DateComponents()
print("Scanning forward")
for monthNo in 1...12 {
comp.setValue(monthNo, for: .month)
let nextDate = cal.nextDate(after: now, matching: comp, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .forward)
print("Month: ", monthNo, ", next date: ", nextDate)
}
print("Scanning backward")
for monthNo in 1...12 {
comp.setValue(monthNo, for: .month)
let nextDate = cal.nextDate(after: now, matching: comp, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .backward)
print("Month: ", monthNo, ", next date: ", nextDate)
}
预期成绩:
下一个日期与前向搜索的相应月份值。最近的日期与反向搜索的相应月份值(或至少从最近的范围开始,具有相应的月份值)。
实际结果:
Scanning forward
Month: 1 , next date: Optional(2020-01-01 00:00:00 +0000)
Month: 2 , next date: Optional(2020-02-01 00:00:00 +0000)
Month: 3 , next date: Optional(2019-03-01 00:00:00 +0000)
Month: 4 , next date: Optional(2019-03-31 23:00:00 +0000)
Month: 5 , next date: Optional(2019-04-30 23:00:00 +0000)
Month: 6 , next date: Optional(2019-05-31 23:00:00 +0000)
Month: 7 , next date: Optional(2019-06-30 23:00:00 +0000)
Month: 8 , next date: Optional(2019-07-31 23:00:00 +0000)
Month: 9 , next date: Optional(2019-08-31 23:00:00 +0000)
Month: 10 , next date: Optional(2019-09-30 23:00:00 +0000)
Month: 11 , next date: Optional(2019-11-01 00:00:00 +0000)
Month: 12 , next date: Optional(2019-12-01 00:00:00 +0000)
Scanning backward
Month: 1 , next date: Optional(2019-01-05 00:00:00 +0000)
Month: 2 , next date: Optional(2018-02-01 01:00:00 +0000)
Month: 3 , next date: Optional(2018-03-02 23:00:00 +0000)
Month: 4 , next date: Optional(2018-03-31 23:00:00 +0000)
Month: 5 , next date: Optional(2018-05-02 23:00:00 +0000)
Month: 6 , next date: Optional(2018-05-31 23:00:00 +0000)
Month: 7 , next date: Optional(2018-07-01 23:00:00 +0000)
Month: 8 , next date: Optional(2018-08-31 22:00:00 +0000)
Month: 9 , next date: Optional(1970-08-31 23:00:00 +0000)
Month: 10 , next date: Optional(2018-10-03 00:00:00 +0000)
Month: 11 , next date: Optional(2018-11-01 00:00:00 +0000)
Month: 12 , next date: Optional(2018-12-31 23:59:59 +0000)
我认为您滥用了匹配政策和重复的时间政策。
但是,如果您希望使用Calendar
获得预期结果,可以使用以下代码:
// Import Foundation to use 'Calendar' and 'Date' classes and structures
import Foundation
/// Setting the current user calendar
let cal = Calendar.autoupdatingCurrent
/// Saving the current date
let now = Date()
print("Forward scanning... ->")
for i in 1...12 {
/// Storing result
let date = cal.date(byAdding: .month, value: i, to: now)
// Print result
print("Mounth: \(i), date: \(date!.debugDescription)")
}
print("\nBackward scanning... ->")
for i in 1...12 {
/// Storing result << please take note of the second argument>>>
let date = cal.date(byAdding: .month, value: -i, to: now)
// Print result
print("Mounth: \(i), date: \(date!.debugDescription)")
}
当您使用date(byAdding: 'Calendar.Component', value: 'Int', to: 'Date')
时,日历搜索按文字月份的偏移量
您可以进一步限定DateComponents
,我相信您可以获得您正在寻找的价值:
var comp = DateComponents(calendar: cal, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)
从而:
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .short
let now = Date()
let calendar = Calendar.current
var components = DateComponents(calendar: calendar, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)
print("Scanning forward")
for monthNo in 1...12 {
components.setValue(monthNo, for: .month)
let nextDate = calendar.nextDate(after: now, matching: components, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .forward)
print("Month: ", monthNo, ", next date: ", formatter.string(from: nextDate!))
}
print("Scanning backward")
for monthNo in 1...12 {
components.setValue(monthNo, for: .month)
let nextDate = calendar.nextDate(after: now, matching: components, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .backward)
print("Month: ", monthNo, ", next date: ", formatter.string(from: nextDate!))
}
生产:
向前扫描 月份:1,下一个日期:1/1 / 20,12:00 AM 月份:2,下一个日期:2/1 / 20,12:00 AM 月:3,下一个日期:3/1/19,中午12:00 月份:4,下一个日期:4/1 / 19,12:00 AM 月份:5,下一个日期:5/1/19,中午12:00 月份:6,下一个日期:2009年6月1日上午12:00 月份:7,下一个日期:7月1日/ 19日,上午12:00 月份:8,下一个日期:2009年8月1日上午12:00 月:9,下一个日期:9/1/19,中午12:00 月:10,下一个日期:10/1/19,中午12:00 月份:11,下次日期:11/1/19,中午12:00 月份:12,下一个日期:12/1/19,中午12:00 向后扫描 月份:1,下一个日期:1/1 / 19,12:00 AM 月份:2,下一个日期:2/1 / 19,12:00 AM 月份:3,下一个日期:3/1 / 18,12:00 AM 月份:4,下一个日期:4/1 / 18,12:00 AM 月份:5,下一个日期:5/1/18,中午12:00 月份:6,下一个日期:6/1 / 18,12:00 AM 月份:7,下一个日期:7月1日18日,中午12:00 月份:8,下一个日期:8/1 / 18,12:00 AM 月份:9,下一个日期:9/1/18,中午12:00 月:10,下一个日期:10/1 / 18,12:00 AM 月份:11,下一个日期:11/1 / 18,12:00 AM 月份:12,下一个日期:12/1 / 18,12:00 AM