diff --git a/Colander.podspec b/Colander.podspec index 09562ab..2baf14f 100644 --- a/Colander.podspec +++ b/Colander.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Colander' - s.version = '0.2.3' + s.version = '0.2.4' s.summary = 'A highly customizable iOS calendar view' s.description = <<-DESC diff --git a/Colander/Classes/DateExtensions.swift b/Colander/Classes/DateExtensions.swift index b6ed093..3812454 100644 --- a/Colander/Classes/DateExtensions.swift +++ b/Colander/Classes/DateExtensions.swift @@ -1,18 +1,26 @@ import SwiftDate -extension Calendar { +internal extension Calendar { static let gregorian = Calendar(identifier: Calendar.Identifier.gregorian) } -extension Date { +internal extension Date { var beginningOfMonth: Date { - var firstDayOfStartMonth = Calendar.gregorian.dateComponents( [.era, .year, .month], from: self) + var calendar = Calendar(identifier: Calendar.Identifier.gregorian) + if let timeZone = TimeZone(secondsFromGMT: 0) { + calendar.timeZone = timeZone + } + var firstDayOfStartMonth = calendar.dateComponents( [.era, .year, .month], from: self) firstDayOfStartMonth.day = 1 - return Calendar.gregorian.date(from: firstDayOfStartMonth) ?? Date.nowAt(.startOfMonth) + return calendar.date(from: firstDayOfStartMonth) ?? Date.nowAt(.startOfMonth) } var beginningOfWeek: Date { - return Calendar.gregorian.date(from: Calendar.gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) ?? Date.nowAt(.startOfWeek) + var calendar = Calendar(identifier: Calendar.Identifier.gregorian) + if let timeZone = TimeZone(secondsFromGMT: 0) { + calendar.timeZone = timeZone + } + return calendar.date(from: calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) ?? Date.nowAt(.startOfWeek) } var endOfWeek: Date { diff --git a/Colander/Classes/MonthInfo.swift b/Colander/Classes/MonthInfo.swift index a6ee32e..0311ea5 100644 --- a/Colander/Classes/MonthInfo.swift +++ b/Colander/Classes/MonthInfo.swift @@ -15,15 +15,18 @@ struct MonthInfo { let firstDayWeekdayIndex: Int let numberOfDaysInMonth: Int - init(forMonthContaining date: Date, with calendar: Calendar = Calendar.gregorian) throws { - guard let numberOfDaysInMonth = calendar.range(of: .day, in: .month, for: date)?.count else { + init(forMonthContaining date: Date, with calendar: Calendar? = nil) throws { + var targetCalendar = calendar ?? Calendar(identifier: Calendar.Identifier.gregorian) + targetCalendar.timeZone = calendar?.timeZone ?? TimeZone(secondsFromGMT: 0)! + + guard let numberOfDaysInMonth = targetCalendar.range(of: .day, in: .month, for: date)?.count else { throw DateError.Generic("Could not determine number of days in month for \(date)") } let beginningOfMonth = date.beginningOfMonth self.startDate = beginningOfMonth self.endDate = beginningOfMonth + numberOfDaysInMonth.days - self.firstDayWeekdayIndex = calendar.component(.weekday, from: startDate) - 1 // 1-indexed to 0-indexed + self.firstDayWeekdayIndex = targetCalendar.component(.weekday, from: startDate) - 1 // 1-indexed to 0-indexed self.numberOfDaysInMonth = numberOfDaysInMonth } } diff --git a/Example/Tests/Date+Mock.swift b/Example/Tests/Date+Mock.swift index bd8460f..cc69ca4 100644 --- a/Example/Tests/Date+Mock.swift +++ b/Example/Tests/Date+Mock.swift @@ -10,8 +10,13 @@ extension Date { /// - day: the desired day /// - Returns: a new instance of `Date` with the given components static func mockDateFrom(year: Int, month: Int, day: Int, hour: Int = 0) -> Date { - let c = DateComponents(year: year, month: month, day: day, hour: hour) - let dateInRegion : DateInRegion = DateInRegion(components: c, region: nil)! + var components = DateComponents(year: year, month: month, day: day, hour: hour) + // nsdate is timezone independent, essentially representing GMT, + // so make sure the calendar is parsing the date in GMT as well + if let timeZone = TimeZone(secondsFromGMT: 0) { + components.timeZone = timeZone + } + let dateInRegion : DateInRegion = DateInRegion(components: components, region: nil)! return dateInRegion.date } } diff --git a/Example/Tests/MonthInfoSpec.swift b/Example/Tests/MonthInfoSpec.swift index 270413b..9057f1f 100644 --- a/Example/Tests/MonthInfoSpec.swift +++ b/Example/Tests/MonthInfoSpec.swift @@ -57,6 +57,14 @@ class MonthInfoSpec: QuickSpec { // Feburary 2017 has 28 days expect(monthInfo.numberOfDaysInMonth).to(equal(29)) } + + it("Correctly decides beginningOfMonth for startDate") { + // September 10, 2019 + let monthInfo = try! MonthInfo(forMonthContaining: Date.mockDateFrom(year: 2019, month: 9, day: 10)) + + // September 1, 2019 is a Sunday + expect(monthInfo.startDate.beginningOfMonth.day).to(equal(1)) + } } } }