我认为这是我去年6月向Apple报告的错误(错误号41023217),但没有得到答复。欢迎任何见识。
摘要:
前后扫描匹配月份的日期会产生奇怪的结果。前向扫描似乎无法正确处理夏令时。向后扫描会产生有时看似根本错误的结果。
复制步骤:
在终端中启动快速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)
答案 0 :(得分:0)
我认为您误用了匹配政策和重复时间政策。
但是,如果您希望通过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')
时,日历按字面月份的偏移量进行搜索
答案 1 :(得分:0)
您可以进一步限定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,下一个日期:20/1 / 20,12:00 AM
月:3,下一个日期:19/1/19上午12:00
月:4,下一个日期:19/4 / 1,12:00 AM
月:5,下一个日期:19/5 / 1,12:00 AM
月:6日,下一个日期:19年6月1日,上午12:00
月:7日,下一个日期:19年7月1日,上午12:00
月:8日,下一个日期:19年8月1日,上午12:00
月:9,下一个日期:19/1 / 19,12:00 AM
月:10,下一个日期:19/10/1/19,上午12:00
月:11日,下一个日期:19/11/1/19上午12:00
月:12,下一个日期:19/12/1/19,上午12:00
向后扫描
月:1,下一个日期:19-1-1 / 19上午12:00
月:2,下一个日期:19/2 / 1,12:00 AM
月:3日,下一个日期:18年3月1日,上午12:00
月:4,下一个日期:18/4/1,上午12:00
月:5日,下一个日期:18年5月1日,上午12:00
月:6日,下一个日期:2018年6月1日,上午12:00
月:7日,下一个日期:18年7月1日,上午12:00
月:8日,下一个日期:18年8月1日,上午12:00
月:9日,下一个日期:18年9月1日,上午12:00
月:10,下一个日期:18/10/1 / 18,12:00 AM
月:11日,下一个日期:18/11/1/18上午12:00
月:12,下一个日期:18/12/1/18上午12:00