NSCalendar дает неправильные номера недель по месяцам в году


У меня есть функция, которая возвращает массив чисел недели из-за месяца и года.

Вот код:

let calendar = NSCalendar.currentCalendar()
let weekRange = calendar.rangeOfUnit(NSCalendarUnit.CalendarUnitWeekOfYear, inUnit: .CalendarUnitMonth, forDate: NSDate())
weekArray = Array(weekRange.location..<weekRange.location + weekRange.length)

Пример: для 2015-08-21 он вернется [31, 32, 33, 34, 35, 36] что является правильным из-за этого веб-сайта .

Он работает нормально, когда, но я нашел одну ошибку, если я передаю эту дату "2016-01-01" он возвращается [1, 2, 3, 4, 5] но правильный массив должен быть [53 (с 2015 года), 1, 2, 3, 4] (еще раз проверил на этом сайте ).

Как упомянутый на этом веб-сайте:

Первая неделя года (WN 1) - Это неделя, содержащая 4 января или первый вторник года.

Итак, я должен написать какой-то расчет, чтобы заставить его работать? Или есть более простое решение? Спасибо за помощь.

1 2

1 ответ:

Результат зависит от типа календаря, локали и настроек первого дня недели.

Календарь на упомянутом сайте основан на ISO 8601, ваш currentCalendar(), вероятно, на григорианском, оба типа похожи, но не идентичны.

Пожалуйста, проверьте это на игровой площадке и попробуйте также раскомментировать комментируемую строку и предоставить другие идентификаторы локали.

Код предназначен для Swift 2.0, в Swift 1.2 используются .CalendarUnitWeekOfYear и .CalendarUnitMonth

let components = NSDateComponents()
components.year = 2016
components.month = 1

var weekNumbersForCalendarIdentifier = { ( identifier : String) -> [Int] in
  let calendar = NSCalendar(calendarIdentifier: identifier)!
  // calendar.locale = NSLocale(localeIdentifier: "us_POSIX")
  let weekRange = calendar.rangeOfUnit(.WeekOfYear, inUnit: .Month, forDate: calendar.dateFromComponents(components)!)
  return Array(weekRange.location..<weekRange.location + weekRange.length)
}

let resultISO = weekNumbersForCalendarIdentifier(NSCalendarIdentifierISO8601)
let resultGregorian = weekNumbersForCalendarIdentifier(NSCalendarIdentifierGregorian)

Есть одно особое поведение независимо от различных настроек:

NSCalendar отображает порядковый номер 0, а не фактический номер 52 или 53 предыдущего года.