我想在 Swift 中找到“当前日期之前一个月的最后一个星期日”,但是使用 Calendar nextDate 函数不起作用(总是返回 nil)。
var calendar: Calendar = Calendar(identifier: .gregorian)
calendar.timeZone = .gmt
let lastSundayDateComponents: DateComponents = DateComponents(
weekday: 1,
weekdayOrdinal: -1
)
let previousLastSundayDate: Date? = calendar.nextDate(
after: Date.now,
matching: lastSundayDateComponents,
matchingPolicy: .nextTime,
repeatedTimePolicy: .first,
direction: .backward
)
print(previousLastSundayDate ?? "Not found") // "Not found"
如果我使用正的 weekdayOrdinal,它可以正常工作,并且相同的 nextDate 方法提供正确的日期。
let firstSundayDateComponents: DateComponents = DateComponents(
weekday: 1,
weekdayOrdinal: 1
)
当我检查日期组件是否可以为给定日历提供有效日期时,它返回 false...
let lastSundayInNovember2023DateComponents: DateComponents = DateComponents(
year: 2023,
month: 11,
weekday: 1,
weekdayOrdinal: -1
)
// THIS RETURNS FALSE
let isValid: Bool = lastSundayInNovember2023DateComponents.isValidDate(in: calendar)
print(isValid) // false
...即使可以创建正确的日期。
let lastSundayInNovember2023: Date = calendar.date(from: lastSundayInNovember2023DateComponents)!
print(lastSundayInNovember2023) // 2023-11-26 00:00:00 +0000
这是基金会的一个错误吗?
在 Swift 的 Calendar 类中将负 weekdayOrdinal 值与 nextDate 函数结合使用似乎可能存在问题。此行为没有详细记录,并且实施中可能存在不一致或限制。
作为解决方法,您可以使用以下方法查找当前日期之前一个月的最后一个星期日:
import Foundation
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = .current
let currentDate = Date()
// Get the first day of the current month
let firstDayOfMonth = calendar.date(from: calendar.dateComponents([.year, .month], from: currentDate))!
// Calculate the last day of the previous month
let lastDayOfPreviousMonth = calendar.date(byAdding: DateComponents(day: -1), to: firstDayOfMonth)!
// Find the last Sunday of the previous month
if let lastSunday = calendar.date(from: calendar.dateComponents([.yearForWeekOfYear, .weekOfYear, .weekday], from: lastDayOfPreviousMonth)) {
print(lastSunday)
} else {
print("Not found")
}
这种方法首先计算当月的第一天,然后找到上个月的最后一天。最后,它使用 dateComponents 方法根据年份、年份中的星期和工作日组件获取上个月的最后一个星期日。
此解决方法应该为您提供正确的结果,而不依赖于负的 weekdayOrdinal 值。