Git Product home page Git Product logo

sunkit's Introduction

SunKit

sunkit

GitHub GitHub stars GitHub issues Requires Core Location

SunKit is a Swift package that uses math and trigonometry to compute several pieces of information about the Sun.

SunKit was first developed as part of a bigger project: Sunlitt. Even though Sunlitt is not meant to be open-sourced, we decided to wrap the fundamental logic of the app and build a library out of it, free for anyone to use, embrace and extend.

sunkit

Attribution

SunKit is licensed under the Apache License 2.0. For attribution, we request that you include an unmodified vector of SunKit's logo, available here, along with our organization name "Sunlitt", both at legible sizes, and that they link back to our website.

If you are developing an app for Apple platforms, we additionally request that you include SunKit's license and copyright in the "Acknowledgments" section of your app's Settings.bundle file. We have included a Settings.bundle example here for you to download and import as is in your Xcode project.

Attribution is essential to make sure that our hard work is properly recognized and we thank you for complying with our requests.

Usage

CoreLocation framework is required for SunKit to work. SunKit only needs a location and the relative time zone. Everything is computed locally, no internet connection is needed.

Creating a Sun

// Creating a CLLocation object with the coordinates you are interested in
let naplesLocation: CLLocation = .init(latitude: 40.84014, longitude: 14.25226)

// Timezone for the location of interest. It's highly recommended to initialize it via identifier
let timeZoneNaples: Timezone = .init(identifier: "Europe/Rome") ?? .current

// Creating the Sun instance which will store all the information you need about sun events and his position
var mySun: Sun = .init(location: naplesLocation, timeZone: timeZoneNaples)

Retrieve information

// Creating a Date instance
let myDate: Date = Date() // Your current date

// Setting inside mySun object the date of interest
mySun.setDate(myDate)

      // All the following informations are related to the given location for the date that has just been set

// Azimuth of the Sun 
mySun.azimuth.degrees  

// Altitude of the Sun
mySun.altitude.degrees

// Sunrise Date
mySun.sunrise

// Sunset Date
mySun.sunset

// Evening Golden Hour Start Date
mySun.eveningGoldenHourStart

// Evening Golden Hour End Date
mySun.eveningGoldenHourEnd

// To know all the information you can retrieve go to the **Features** section.

Working with Timezones and Dates

To properly show the Sun Date Events use the following DateFormatter.

 //Creting a DateFormatter
 let dateFormatter =  DateFormatter()
 
 //Properly setting his attributes
 dateFormatter.locale    =  .current
 dateFormatter.timeZone  =  timeZoneNaples  // It shall be the same as the one used to initilize mySun
 dateFormatter.timeStyle = .full
 dateFormatter.dateStyle = .full
  
 //Printing Sun Date Events with the correct Timezone
  
 print("Sunrise: \(dateFormatter.string(from: mySun.sunrise))")
    

Features

  • Sun Azimuth
  • Sun Altitude
  • Civil Dusk Time
  • Civil Dawn Time
  • Sunrise Time
  • Solar Noon Time
  • Solar Midnight Time
  • Morning Golden Hour Time
  • Evening Golden Hour Time
  • Sunset Time
  • Astronomical Dusk
  • Astronomical Dawn
  • Nautical Dusk
  • Nautical Dawn
  • Morning Blue Hour Time
  • Evening Blue Hour Time
  • Sun Azimuth at Sunrise
  • Sun Azimuth at Sunset
  • Sun Azimuth at Solar Noon
  • Total Daylight Duration
  • Total Night Duration
  • March Equinox
  • June Solstice
  • September Equinox
  • December Solstice

References

  • NOAA Global Monitoring Division. General Solar Position Calculations: Link.
  • PV Education: Link.
  • Celestial Calculations: A Gentle Introduction to Computational Astronomy: Link.

MoonKit 🌙

Take a look at SunKit's spiritual brother, MoonKit.

Special thanks

sunkit's People

Contributors

davideilmito avatar seldon1000 avatar uevs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

sunkit's Issues

Working with the time zone

Hey,
I used SunKit and MoonKit in my upcoming application. I like them and it's great that the classes are still alive and that you keep improving them.

In practical implementation, I've encountered difficulties when working with time zones and would have a tip for an improvement that would greatly simplify their use.

My difficulties:
When I want to use a Sun class for a time zone other than the current time zone, I have to work very carefully with the time zone.
For example: the facility is located in Prague and I need the position of the sun during the day in Cupertino.

  • Before initializing, I need to calculate the time zone offset in Cupertino and pass it to the Sun class as a Double
  • pre-shift each date set via setDate() to the Cupertino time zone
  • in addition, I have to recalculate and set setTimeZone() before setDate() because the previous date could have a different DST

This is not a safe and convenient solution.

That's why I propose to initialize the Sun class with the TimeZone class.
The Sun class can then do all the necessary conversions for time zones by itself:

  • calculate the time zone offset itself
  • adjust the time passed via setDate by itself
  • calculate the DST itself

Michal Kus

SunKit in a view in Xcode

Hello,

I have downloaded SunKit and installed in via the Swift Package Manager in Xcode.

I want to show in a view (example the ContentView) for example the sunrise time.

Is it possible to provide me the code to do this. As I am relatively new to SwiftUI (You have to start somewhere I guess), I am a little bit lost 'in the moment' :)

Is it possible to help me and show me how I can show these time in a Xcode View?

Your help would be appreciated.

Sun azimuth at current time

Hello,

thank you for your awesome work.

As the sun moves from sunrise to sunset in a given location you provide the azimuth of the sun on sunrise and sunset.
I have a question: is it possible to have the data of the current position of the sun. For example if it is 10h30 to see the position of the sun on the map between sunrise and sunset, and if the time evolves you see the sun on a map moving?

is this possible?

Common ancestor for Sun and Moon

It would be practical if Sun and Moon had a common ancestor that had properties that both classes have the same (date, altitude, rise, set ....).

Right now I have two almost identical methods, although one would be enough.

Thanks, Michal Kůs

The package does not work well with daylight saving time.

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
    
}

}

Sunset time tomorrow

Hello I am a little bit confused.
I want to see the sunset time of tomorrow. I am a little bit stuck with the date.
How can I modify tthe code to retrieve the sunset time of tomorrow?

Wrong solar midnight time

When setting a date any day before 1AM, solar midnight time points to the previous day. This leads to wrong timings in specific situations, with up to 36 hours of distance between the current solar noon and midnight timings.

Dawn/dusk times reversed?

When testing SunKit, the dumpDateInfos function includes the following:

Civil dusk          -> Tuesday, May 2, 2023 at 5:31:09 AM Mountain Daylight Time
Civil Dawn           -> Tuesday, May 2, 2023 at 8:21:42 PM Mountain Daylight Time
Nautical Dusk     -> Tuesday, May 2, 2023 at 4:56:05 AM Mountain Daylight Time
Nautical Dawn      -> Tuesday, May 2, 2023 at 8:56:46 PM Mountain Daylight Time
Astronomical Dusk -> Tuesday, May 2, 2023 at 4:18:26 AM Mountain Daylight Time
Astronomical Dawn  -> Tuesday, May 2, 2023 at 9:34:25 PM Mountain Daylight Time

In each case, dawn is shown as being in the evening, while dusk is in the morning.

I thought at first that the dawn times were for tomorrow, i.e. the next time dawn arrived, but they all show the same date. Printing their UTC values shows the same issue, dusk occurs before dawn:

Civil dawn: 2023-05-03 02:21:42 +0000
Civil dusk: 2023-05-02 11:31:09 +0000

Nautical dawn: 2023-05-03 02:56:46 +0000
Nautical dusk: 2023-05-02 10:56:05 +0000

Astronomical dawn: 2023-05-03 03:34:25 +0000
Astronomical dusk: 2023-05-02 10:18:26 +0000

I don’t know if this means dawn and dusk times are reversed or if there’s some other problem.

My Package.resolved shows that I’m using tag 2.6.3, so I should be up to date.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.