Swift Foundation Calendar nextDate()产生奇怪的结果

问题描述 投票:1回答:2

以下是我认为是去年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)
swift calendar foundation
2个回答
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')时,日历搜索按文字月份的偏移量


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,下一个日期: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

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.