ipraba / EPCalendarPicker

Colourful calendar for iOS written in Swift
MIT License
347 stars 73 forks source link

Values selected correspond to one day earlier #21

Open RichSamar opened 8 years ago

RichSamar commented 8 years ago

When I select a few dates (e.g. 19, 20, 21 June 2016) and then click "done" the actual dates in arrSelectedDates are one day earlier (i.e. 18, 19, 20 June 2016). See screen shots below. (Problem is the same if I select a single date or multiple dates).

It is very strange. The value of cell.lblDay.text is correctly set to 19 (if for example I select 19 June 2016) but cell.currentDate is set to value 18 June 2016.

override public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

[...]

cell.currentDate = currentDate
cell.lblDay.text = "\(currentDate.day())"

I tried to modify cell.currentDate = currentDate by adding one day to it cell.currentDate = currentDate.dateByAddingDays(1). The return values in arrSelectedDates are then correct. But when I scroll out and scroll back in the wrong dates are highlighted.

Could this have something to do with different time zones or is it a completely different problem? Any idea what could be the issue? I am running iOS 9.3.2 and Xcode 7.3.1. The issue happens on my iPhone as well as different simulators.

screen shot 2016-06-18 at 02 02 41 screen shot 2016-06-18 at 02 02 58

pushpendra996 commented 8 years ago

I am also facing same issue, when i select any date from Date Picker it returning me one date earlier from the selected date.

RichSamar commented 8 years ago

@ipraba @pushpendra996

I think my initial comment may be right and the issue might be related to different time zones. The calendar should be fully based on UTC (GMT) and time zone neutral. However, I found the following issue related to the extension of NSDate:

override public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
{
   let startDate = NSDate(year: startYear, month: 1, day: 1)
[...]
}

This is a convenience initialiser added to NSDate inEPExtensions.swift. I put that extension into a playground to test:

import UIKit
extension NSDate
{
    convenience init(year : Int, month : Int, day : Int)
    {
        let calendar = NSCalendar.currentCalendar()
        let dateComponent = NSDateComponents()
        dateComponent.year = year
        dateComponent.month = month
        dateComponent.day = day
        self.init(timeInterval:0, sinceDate:calendar.dateFromComponents(dateComponent)!)
    }
}
let startYear = 2016
let startDate = NSDate(year: startYear, month: 1, day: 1)
print(startDate)

Output is as follows for the last three lines of code: 2016 "Jan 1, 2016, 12:00 AM" "2015-12-31 16:00:00 +0000\n"

As you can see, the individual values are all correct. But the start date is one day earlier.

I have not had much time but attempted this change, which for now seems to have fixed the problem. @pushpendra996 - pls test if that fixes the issue for you too and let me know.

In EPExtensions.swift I made the following modification adding explicitly UTC. I also set the calendar to Gregorian explicitly (as in my app I do not support other calendar types but that part is optional).

convenience init(year : Int, month : Int, day : Int)
{
        ///    let calendar = NSCalendar.currentCalendar()
        //    set explicitly Gregorian calendar
        let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)!
        //    make sure time zone is UTC
        calendar.timeZone = NSTimeZone(abbreviation: "UTC")!

        let dateComponent = NSDateComponents()
        dateComponent.year = year
        dateComponent.month = month
        dateComponent.day = day
        self.init(timeInterval:0, sinceDate:calendar.dateFromComponents(dateComponent)!)
}