Calendar icon indicating copy to clipboard operation
Calendar copied to clipboard

WeekStartDay

Open TobiasDoe opened this issue 9 years ago • 2 comments

Hi is it possible to set the firstdayoftheweek to Monday?

TobiasDoe avatar Sep 04 '15 11:09 TobiasDoe

I made some changes to the code: In CalendarLogic.swift I changed the code as follows:

private var numberOfDaysInPreviousPartialWeek: Int {
    return baseDate.weekDay - 2; // Glorified fix for the SUNDAY AS THE FIRST WEEK DAY situation //
}
private var calculatePreviousMonthVisibleDays: [Date] {
    var dates = [Date]()

    let date = baseDate.firstDayOfPreviousMonth
    let numberOfDaysInMonth = date.numberOfDaysInMonth

    let numberOfVisibleDays = numberOfDaysInPreviousPartialWeek + 1; // Start from Sunday again, otherwise crash, boom, bang! //
    let parts = date.monthDayAndYearComponents

    if (numberOfDaysInMonth - (numberOfVisibleDays - 1)) < numberOfDaysInMonth {
        for i in (numberOfDaysInMonth - (numberOfVisibleDays - 1))...numberOfDaysInMonth {
            dates.append(Date(day: i, month: parts.month, year: parts.year))
        }
    }
    return dates
}

And in WeekHeaderView.swift I made small change in the loop to rearrange the weekdays:

for i in 0..<formatter.weekdaySymbols.count {
    if (i+1) < formatter.weekdaySymbols.count {
        let weekDayString = formatter.weekdaySymbols[i+1]
        labels[i].text = weekDayString.substringToIndex(weekDayString.startIndex.advancedBy(3)).uppercaseString
    } else {
        let weekDayString = formatter.weekdaySymbols[0]
        labels[i].text = weekDayString.substringToIndex(weekDayString.startIndex.advancedBy(3)).uppercaseString
    }
}

And finally, I'm not quite sure if it's part of the fix, or just a redundant piece of work, but in NSDateAdditions.swift I added a private method to return an NSCalendar object with firstWeekday = 2 Here is the whole file (so you can copy/paste it directly instead of me pointing every change):

//
//  Additions.swift
//  CalendarLogic
//
//  Created by Lancy on 01/06/15.
//  Copyright (c) 2015 Lancy. All rights reserved.
//

import Foundation

extension NSDate {

    class func date(day: Int, month: Int, year: Int) -> NSDate {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "dd/MM/yyyy"

        let dayString = String(format: "%02d", day)
        let monthString = String(format: "%02d", month)
        let yearString = String(format: "%04d", year)

        return dateFormatter.dateFromString(dayString + "/" + monthString + "/" + yearString)!
    }

    var startOfDay: NSDate {
        let components = self.components

        components.hour = 0
        components.minute = 0
        components.second = 0

        return self.fixCalendar().dateFromComponents(components)!
    }

    var endOfTheDay: NSDate {
        let components = self.components

        components.hour = 23
        components.minute = 59
        components.second = 59

        return self.fixCalendar().dateFromComponents(components)!
    }

    var firstDayOfTheMonth: NSDate {
        var date: NSDate?
        self.fixCalendar().rangeOfUnit(.Month, startDate:&date , interval: nil, forDate: self)
        return date!
    }

    var firstDayOfPreviousMonth: NSDate {
        return firstDay(false)
    }

    var firstDayOfFollowingMonth: NSDate {
        return firstDay(true)
    }

    var monthDayAndYearComponents: NSDateComponents {
        let components: NSCalendarUnit = [.Year, .Month, .Day]
        return self.fixCalendar().components(components, fromDate: self)
    }

    var weekDay: Int {
        return components.weekday
    }

    var numberOfDaysInMonth: Int {
        return self.fixCalendar().rangeOfUnit(.Day, inUnit: .Month, forDate: self).length
    }

    var day: Int {
        return components.day
    }

    var month: Int {
        return components.month
    }

    var year: Int {
        return components.year
    }

    var minute: Int {
        return components.minute
    }

    var second: Int {
        return components.second
    }

    var hour: Int {
        return components.hour
    }

    //MARK: Private variable and methods.

    private func fixCalendar() -> NSCalendar {
        let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian);
        calendar?.firstWeekday = 2;
        calendar?.locale = NSLocale.currentLocale();
        calendar?.timeZone = NSTimeZone.defaultTimeZone();
        return calendar!;
    }

    private var components: NSDateComponents {
        let calendarUnit = NSCalendarUnit(rawValue: UInt.max)
        let components = self.fixCalendar().components(calendarUnit, fromDate: self)
        return components
    }

    private func firstDay(followingMonth: Bool) -> NSDate {
        let dateComponent = NSDateComponents()
        dateComponent.month = followingMonth ? 1: -1

        let date = self.fixCalendar().dateByAddingComponents(dateComponent, toDate: self, options: NSCalendarOptions(rawValue: 0))
        return date!.firstDayOfTheMonth
    }
}

I hope I helped somehow :)

awedeebawe avatar Apr 02 '16 18:04 awedeebawe

update: somehow when the month starts from Monday, the month before starts from the wrong day. I should investigate further this situation. @lancy98 you can always give us a hand, please :)

awedeebawe avatar Apr 02 '16 18:04 awedeebawe