+-
看了几个关于SO的不同建议,我无法确定为什么下面的函数不起作用。它似乎在几个月内返回6,在其他月份返回5。当几周改变几天时,它完美地运作。
例如,尝试
weeksInMonth(8, forYear 2015)
结果6。
我相信我对日历上的“第一周日”财产有误解,但没有得到Apple或网上的充分解释。
试过了.WeekOfMonth和.WeekOfYear。再也无法找到确切差异的解释。
任何建议都会受到欢迎。
func weeksInMonth(month: Int, forYear year: Int) -> Int?
{
if (month < 1 || month > 12) { return nil }
let dateString = String(format: "%4d/%d/01", year, month)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd"
if let date = dateFormatter.dateFromString(dateString),
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
{
calendar.firstWeekday = 2 // Monday
let weekRange = calendar.rangeOfUnit(.WeekOfMonth, inUnit: .Month, forDate: date)
let weeksCount = weekRange.length
return weeksCount
}
else
{
return nil
}
}
更新:
道歉我的问题不明确。我想弄清楚一个月里有多少个星期,其中包括星期一。对于八月,这应该是5。
6
投票
投票
您的代码计算一个月内(完整或部分)发生的周数。你显然想要的是给定月份的星期一数量。使用NSDateComponents
,尤其是weekdayOrdinal
属性,你可以计算一个月内的第一个(weekdayOrdinal=1
)和最后一个(weekdayOrdinal=-1
)。然后计算周数差异(并添加一个)。
Swift 2中可能的实现:
func numberOfMondaysInMonth(month: Int, forYear year: Int) -> Int?
{
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
calendar.firstWeekday = 2 // 2 == Monday
// First monday in month:
let comps = NSDateComponents()
comps.month = month
comps.year = year
comps.weekday = calendar.firstWeekday
comps.weekdayOrdinal = 1
guard let first = calendar.dateFromComponents(comps) else {
return nil
}
// Last monday in month:
comps.weekdayOrdinal = -1
guard let last = calendar.dateFromComponents(comps) else {
return nil
}
// Difference in weeks:
let weeks = calendar.components(.WeekOfMonth, fromDate: first, toDate: last, options: [])
return weeks.weekOfMonth + 1
}
注意:从文档开始,从月底开始向后计数的负weekdayOrdinal
不明显。它在Determine NSDate for Memorial Day in a given year和confirmed by Dave DeLong观察到。
Swift 3更新:
func numberOfMondaysInMonth(_ month: Int, forYear year: Int) -> Int? {
var calendar = Calendar(identifier: .gregorian)
calendar.firstWeekday = 2 // 2 == Monday
// First monday in month:
var comps = DateComponents(year: year, month: month,
weekday: calendar.firstWeekday, weekdayOrdinal: 1)
guard let first = calendar.date(from: comps) else {
return nil
}
// Last monday in month:
comps.weekdayOrdinal = -1
guard let last = calendar.date(from: comps) else {
return nil
}
// Difference in weeks:
let weeks = calendar.dateComponents([.weekOfMonth], from: first, to: last)
return weeks.weekOfMonth! + 1
}
5
投票
投票
实际上你的问题是:一个月内有多少个星期一?
我的方法是计算当月的第一个星期一,这可以通过将CalendarUnit WeekdayOrdinal
设置为1来完成。然后获取总天数并进行一些数学计算。
Swift 1.2
func mondaysInMonth(month: Int, forYear year: Int) -> Int?
{
if 1...12 ~= month {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let components = NSDateComponents()
components.weekday = 2 // Monday
components.weekdayOrdinal = 1
components.month = month
components.year = year
if let date = calendar.dateFromComponents(components) {
let firstDay = calendar.component(.CalendarUnitDay, fromDate: date)
let days = calendar.rangeOfUnit(.CalendarUnitDay, inUnit:.CalendarUnitMonth, forDate:date).length
return (days - firstDay) / 7 + 1
}
}
return nil
}
斯威夫特2
func mondaysInMonth(month: Int, forYear year: Int) -> Int?
{
guard 1...12 ~= month else { return nil }
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let components = NSDateComponents()
components.weekday = 2 // Monday
components.weekdayOrdinal = 1
components.month = month
components.year = year
if let date = calendar.dateFromComponents(components) {
let firstDay = calendar.component(.Day, fromDate: date)
let days = calendar.rangeOfUnit(.Day, inUnit:.Month, forDate:date).length
return (days - firstDay) / 7 + 1
}
return nil
}
1
投票
投票
斯威夫特2
以下代码计算一个月中的周数。它不取决于月份开始或结束的那一天。
func weeksInMonth(month: Int, year: Int) -> (Int)? {
let calendar = NSCalendar.currentCalendar()
let comps = NSDateComponents()
comps.month = month+1
comps.year = year
comps.day = 0
guard let last = calendar.dateFromComponents(comps) else {
return nil
}
// Note: Could get other options as well
let tag = calendar.components([.WeekOfMonth,.WeekOfYear,
.YearForWeekOfYear,.Weekday,.Quarter],fromDate: last)
return tag.weekOfMonth
}
// Example Usage:
if let numWeeks = weeksInMonth(8,year: 2015) {
print(numWeeks) // Prints 6
}
if let numWeeks = weeksInMonth(12,year: 2015) {
print(numWeeks) // Prints 5
}
0
投票
投票
Swift 4+:
//-- Get number of weeks from calendar
func numberOfWeeksInMonth(_ date: Date) -> Int {
var calendar = Calendar(identifier: .gregorian)
calendar.firstWeekday = 1
let weekRange = calendar.range(of: .weekOfMonth,
in: .month,
for: date)
return weekRange!.count
}
//-- Implementation
let weekCount = numberOfWeeksInMonth(Date)
0
投票
投票
Swift 4+:
从组件生成日期:
let dateComponents = DateComponents.init(year: 2019, month: 5)
let monthCurrentDayFirst = Calendar.current.date(from: dateComponents)!
let monthNextDayFirst = Calendar.current.date(byAdding: .month, value: 1, to: monthCurrentDayFirst)!
let monthCurrentDayLast = Calendar.current.date(byAdding: .day, value: -1, to: monthNextDayFirst)!
从日期检测周数:
let numberOfWeeks = Calendar.current.component(.weekOfMonth, from: monthCurrentDayLast)