我目前面临一个奇怪的问题。我试图找出给定的Date
实例在每月的哪一周。
我的代码如下:
var calendar : Calendar {
var calendar = Calendar(identifier: .iso8601)
calendar.timeZone = .UTC
return calendar
}
func generateDate(year: Int, month: Int, day: Int) -> Date {
let dateComponents = DateComponents(year: year, month: month, day: day)
return calendar.date(from: dateComponents)!
}
print(calendar.component(.weekOfMonth, from: Date.generateDate(year: 2019, month: 12, day: 1))) // prints "0"
print(calendar.component(.weekOfMonth, from: Date.generateDate(year: 2020, month: 1, day: 1))) // prints "1"
generateDate
只需借助calendar
生成一个日期。当我同时打印两个语句时,得到的结果分别为0
和1
。我认为这是错误的。我会假设两个值都相同,因为两个日期都应该在各自月份值的第一周。
另一个例子是2019年12月2日,这应该是第二周,而2020年1月6日也应该是第二周。
有人知道这里有什么问题或我的错误可能在哪里吗?
答案 0 :(得分:1)
这是由于该月的第一天是星期日,如果要确认,请尝试2020年3月1日。
Swift根据自己的标准选择每月的第一周,因为ISO标准没有建议任何特定的实现方式,因此Swift团队选择了此方法。您可以在他们的论坛中询问他们,其背后的原因是Wikipedia link
答案 1 :(得分:1)
.weekOfMonth
的逻辑似乎是,如果“第一”周少于半周(即3天),则它被认为是第0周,否则被认为是第1周。但是请注意,取决于所使用的语言环境,对于像加拿大这样的国家/地区,将星期日作为一周的第一天,则运行以下代码时永远不会出现星期0。因此,当一周的第一天是星期一.weekOfMonth
将返回0到5之间的值,但是当它是星期日时,范围是1到6。
可以看到在操场上运行以下代码
let calendar = Calendar.current
let year = 2019
print("First day of week: \(calendar.weekdaySymbols[calendar.firstWeekday - 1])")
for month in 1...12 {
print(calendar.monthSymbols[month - 1])
let first = calendar.date(from: DateComponents(year: year, month: month, day: 1))!
if let range = calendar.range(of: .day, in: .month, for: first) {
var currentWeek = -1
for day in range {
let date = calendar.date(from: DateComponents(year: year, month: month, day: day))!
let week = calendar.component(.weekOfMonth, from: date)
if week > currentWeek {
currentWeek = week
let dayOfWeek = calendar.component(.weekday, from: date)
print("Week# \(week), weekday \(calendar.weekdaySymbols[dayOfWeek - 1])")
}
}
}
}
在我看来,如果您希望第一天的任何一天成为weekOfMonth的第一天= 1,那么您需要为此编写自己的代码