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

bar*_*bus 4 swift swift2

看了几个关于SO的不同建议,我无法确定为什么下面的函数不起作用.它似乎在几个月内返回6,在其他月份返回5.当几周改变几天时,它完美地运作.

例如,尝试

weeksInMonth(8, forYear 2015) 
Run Code Online (Sandbox Code Playgroud)

结果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
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

道歉我的问题不明确.我想弄清楚一个月里有多少个星期,其中包括星期一.对于八月,这应该是5.

Mar*_*n R 6

您的代码计算一个月内(完整或部分)发生的周数.你显然想要的是给定月份的星期一数量.使用NSDateComponents,特别是weekdayOrdinal属性,您可以计算一个月中的first(weekdayOrdinal=1)和last(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
}
Run Code Online (Sandbox Code Playgroud)

注意:weekdayOrdinal从月末开始向后计数的负数在文档中并不明显.在给定年份的确定纪念日的NSDate中观察到 并且由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
}
Run Code Online (Sandbox Code Playgroud)


vad*_*ian 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
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特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
}
Run Code Online (Sandbox Code Playgroud)

  • 4小时没有,然后10秒内2个答案:) (2认同)
  • :-)我喜欢你计算月份最后一个工作日的方法. (2认同)