Sunlitt/SunKit

The package does not work well with daylight saving time.

BlackBird-One opened this issue · 1 comments

I tested how the package works after plugging in TimeZone. Unfortunately, I found a bug in working with daylight saving time.
Example: sunrise in Los Angeles
March 11: calculates 07:08, (this is an error, should be 06:08)
March 12th is the end of daylight saving time
March 13: calculates 07:06 (this is correct)

This error is not in the MoonKit package.

func testSun() throws {
    //https://gml.noaa.gov/grad/solcalc/sunrise.html
    //https://www.timeanddate.com/sun/usa/los-angeles?month=3&year=2023
    
    guard let pst = TimeZone(abbreviation: "PST") else {
        abort()
    }
    
    guard let utc = TimeZone(abbreviation: "UTC") else {
        abort()
    }
    
    let location: CLLocation = .init(latitude: 34.052235, longitude: -118.243683)

    let sun = Sun.init(location: location, timeZone: pst)
    
    sun.setDate(SunKit.createDateCustomTimeZone(day: 11, month: 3, year: 2023, hour: 22, minute: 00, seconds: 00, timeZone: pst))
    XCTAssertEqual(sun.sunrise.toString(pst), "03/11, 06:08") //XCTAssertEqual failed: ("03/11, 07:08") is not equal to ("03/11, 06:08")
    XCTAssertEqual(sun.sunset.toString(pst), "03/11, 17:58")  //XCTAssertEqual failed: ("03/11, 18:58") is not equal to ("03/11, 17:58")
    XCTAssertEqual(sun.sunrise.toString(utc), "03/11, 14:08") //XCTAssertEqual failed: ("03/11, 15:08") is not equal to ("03/11, 14:08")
    XCTAssertEqual(sun.sunset.toString(utc), "03/12, 01:58")  //XCTAssertEqual failed: ("03/12, 02:58") is not equal to ("03/12, 01:58")

    sun.setDate(SunKit.createDateCustomTimeZone(day: 13, month: 3, year: 2023, hour: 22, minute: 00, seconds: 00, timeZone: pst))
    XCTAssertEqual(sun.sunrise.toString(pst), "03/13, 07:06")
    XCTAssertEqual(sun.sunset.toString(pst), "03/13, 18:59")
    XCTAssertEqual(sun.sunrise.toString(utc), "03/13, 14:06")
    XCTAssertEqual(sun.sunset.toString(utc), "03/14, 01:59")
}




extension Date {

func toString(_ timeZone: TimeZone) -> String {
    let df = DateFormatter()
    df.timeZone = timeZone
    let custom = DateFormatter.dateFormat(fromTemplate: "MMdd HH:mm",
                                          options: 0,
                                          locale: Locale(identifier: "en"))
    df.dateFormat = custom
    return df.string(from: self)
}

}

extension TimeZone {

func offset(_ date: Date) -> Double {
    let res =
        Int(self.secondsFromGMT(for: date))
        + Int(self.daylightSavingTimeOffset(for: date))
        - Int(Calendar.current.timeZone.secondsFromGMT(for: date))
        - Int(Calendar.current.timeZone.daylightSavingTimeOffset(for: date))
    print("\(date.toString())  \(Int(self.secondsFromGMT(for: date)/3600)), \(Int(self.daylightSavingTimeOffset(for: date)/3600)), \(Int(Calendar.current.timeZone.secondsFromGMT(for: date)/3600)), \(Int(Calendar.current.timeZone.daylightSavingTimeOffset(for: date)/3600))")
    return Double(res)/3600.0
    
}

}

Hi @BlackBird-One, fix is on the branch related to this issue. Let me know if the problem has been fixed. Thanks.