计算给定月份的周数 - 斯威夫特

时间:2015-08-12 15:09:05

标签: swift swift2

看了几个关于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。

5 个答案:

答案 0 :(得分:6)

您的代码计算发生的周数(完整或部分) 在一个月。你显然想要的是周一的数量 在给定的月份。使用NSDateComponents,尤其是weekdayOrdinal 您可以计算第一个weekdayOrdinal=1属性 (weekdayOrdinal=-1)和最后一次(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 } )星期一 在一个月。然后计算周数差异(并添加一个)。

Swift 2:

中的可能实施方式
weekdayOrdinal

注意:从文档结尾看,负数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 } 从月末开始倒计时。它被观察到了 Determine NSDate for Memorial Day in a given yearconfirmed by Dave DeLong)。

更新 Swift 3:

WeekdayOrdinal

答案 1 :(得分:5)

实际上你的问题是:某个月有多少个星期一?

我的方法是计算当月的第一个星期一,这可以通过将CalendarUnit 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 } 设置为1来完成。然后获取总天数并做一些数学运算。

Swift 1.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
}

Swift 2

^[(0-9)|(_|\.)]|^[0-9]+$|[^a-zA-z0-9_.]{3,}|(_\.|\._)|\.{2,}|_{2,}

答案 2 :(得分:1)

Swift 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
}

答案 3 :(得分: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)

答案 4 :(得分:0)

快速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)