Как рассчитать количество дней в каждом квартале

Я хотел бы знать, как правильно получить количество дней в каждом квартале. Взять на учетный високосный год.

Например:

  • 1 квартал: 90 (или 91 високосный год)
  • 2 квартал: 91 - текущий квартал
  • 3 квартал: 92
  • 4 квартал: 92

Из документов можно понять, что мы должны разделить 12-й год на 4 части. Затем получите сумму дня каждого квартала, например 3 * (количество дней в 3 месяца). Но как это можно сделать более сложным способом и без жесткого кода.

Ответ 1

Вы должны использовать объект NSCalendar, чтобы рассчитать количество дней за каждый квартал.

Например: за первый квартал: с 01 января по 01 апреля

let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd"

let firstDate = df.date(from: "2017-01-01")!
let secondDate = df.date(from: "2017-04-01")!

let calendar = Calendar(identifier: .gregorian)
let dateComponents = calendar.dateComponents([Calendar.Component.day], from: firstDate, to: secondDate)

print("number of day of Q1: \(dateComponents.day)")

Ответ 2

Вы можете использовать DateFormatter dateFormat "q" и преобразовать его в целое.

extension Formatter {
    static let quarter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "q"
        return formatter
    }()
}

extension Calendar {
    static let iso8601 = Calendar(identifier: .iso8601)
}

extension Date {
    var year: Int { return Calendar.iso8601.dateComponents([.year], from: self).year ?? 0 }
    var quarter: Int { return Int(Formatter.quarter.string(from: self))! }

    var firstDayOfYear: Date { return DateComponents(calendar: .iso8601, year: year, month: 1, day: 1).date!}
    var firstDayOfNextYear: Date { return DateComponents(calendar: .iso8601, year: year.advanced(by: 1), month: 1, day: 1).date! }

    var quarters: (q1: Int, q2: Int, q3: Int, q4: Int) {
        var date = firstDayOfYear
        var q1 = 0, q2 = 0, q3 = 0, q4 = 0
        while date < firstDayOfNextYear {
            switch date.quarter {
            case 1: q1 += 1
            case 2: q2 += 1
            case 3: q3 += 1
            case 4: q4 += 1
            default:
                break
            }
            date = Calendar.iso8601.date(byAdding: DateComponents(day: 1), to: date)!
        }
        return (q1: q1, q2: q2, q3: q3, q4: q4)
    }
}

Тестирование игровых площадок:

Date().quarter                  // 2
Date().firstDayOfYear.quarter   // 1

Date().quarters   // q1 90, q2 91, q3 92, q4 92)