Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

isDaytime and isNightTime return incorrect values for polar day #59

Open
ddekanski opened this issue Jun 2, 2022 · 1 comment
Open

Comments

@ddekanski
Copy link

ddekanski commented Jun 2, 2022

For places where there's a polar day in the given time/date (see the example), isDaytime returns false and isNightTime returns true for all times of day (just opposite to reality).

Code:

private func isSunUp(dateTime: Date, coords: LatLon) -> Bool {
    let solar = Solar(for: dateTime, coordinate: CLLocationCoordinate2D(latitude: coords.lat, longitude: coords.lon))
    return solar!.isDaytime
}

Params:
dateTime: 2022-06-03 06:00:00 +0000
coords: lat: 67.94753132376813, lon: 13.131613209843637

@daneden
Copy link

daneden commented Jun 26, 2024

I know this is an old bug, but I’ve been using Solar extensively for my project Solstice and polar days/nights are so tricky! I’ve figured out a workaround that involves checking whether the coordinates are within a polar circle:

import CoreLocation
import Solar

extension CLLocationCoordinate2D {
  var insideArcticCircle: Bool { latitude > 66.34 }
  var insideAntarcticCircle: Bool { latitude < -66.34 }
  var insidePolarCircle: Bool { insideArcticCircle || insideAntarcticCircle }
}

extension Solar {
  var isSunUp: Bool {
    if sunrise != nil && sunset != nil {
      return isDaytime
    }

    guard coordinate.insidePolarCircle else { return isDaytime }

    let month = Calendar.current.component(.month, from: date)
		
    switch month {
      case 1...3, 1012:
        return coordinate.insideAntarcticCircle
      default:
        return coordinate.insideArcticCircle
    } 
  }
}

This works by:

  1. Returning isDaytime if there is a sunrise/sunset (which is how isDaytime works under the hood anyway)
  2. Checking whether the coordinates lie within a polar circle, and returning isDaytime if they don't
  3. Returning a boolean based on:
    a. Which polar circle the coordinates are in
    b. Whether the date lies within the northern hemisphere’s winter months

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants