A Swift micro library for generating Sunrise and Sunset times.

Overview

Solar

Version Carthage compatible POD compatible SPM compatible Build Status MIT licensed

A Swift helper for generating Sunrise and Sunset times.

Solar performs its calculations locally using an algorithm from the United States Naval Observatory, and thus does not require the use of a network.

Usage

Solar simply needs a date and a location specified as a latitude and longitude:

let solar = Solar(for: someDate, coordinate: CLLocationCoordinate2D(latitude: 51.528308, longitude: -0.1340267))
let sunrise = solar?.sunrise
let sunset = solar?.sunset

We can also omit providing a date if we just need the sunrise and sunset for the current date and time:

let solar = Solar(coordinate: CLLocationCoordinate2D(latitude: 51.528308, longitude: -0.1340267))
let sunrise = solar?.sunrise
let sunset = solar?.sunset

Note that all dates are UTC. Don't forget to format your date into the appropriate timezone if required.

Types of sunrise and sunset

There are several types of sunrise and sunset that Solar generates. They differ by how many degrees the sun lies below the horizon:

  • Official (~0°)

  • Civil (6° below horizon)

  • Nautical (12° below horizon)

  • Astronomical (18° below horizon)

For more information, see https://www.timeanddate.com/astronomy/different-types-twilight.html

Convenience methods

Solar also comes packaged with some convenience methods:

// Whether the location specified by the `latitude` and `longitude` is in daytime on `date`
let isDaytime = solar.isDaytime

// Whether the location specified by the `latitude` and `longitude` is in nighttime on `date`
let isNighttime = solar.isNighttime

Installation

Solar is available through CocoaPods, Carthage, and Swift Package Manager.

CocoaPods

To include Solar in an application, add the following pod to your Podfile, then run pod install:

pod "Solar", "~> 2.2"

To include Solar in another pod, add the following dependency to your podspec:

s.dependency "Solar", "~> 2.2"

Carthage

Add the ceek/Solar project to your Cartfile, then follow the rest of Carthage’s XCFramework installation instructions:

github "ceeK/Solar" ~> 2.2

Swift Package Manager

To include Solar in an application in Xcode:

  1. Go to File ‣ Swift Packages ‣ Add Package Dependency.
  2. Enter https://github.com/ceeK/Solar.git as the package repository and click Next.
  3. Set Rules to Version, Up to Next Major, and enter 2.2.0 as the minimum version requirement. Click Next.

To include Solar in another Swift package, add the following dependency to your Package.swift:

.package(name: "Solar", url: "https://github.com/ceeK/Solar.git", from: "2.2.0")

License

The MIT License (MIT)

Copyright (c) 2016-2021 Chris Howell

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • Timezone handling is putting date to one day ahead and daylight savings is not being processed

    Timezone handling is putting date to one day ahead and daylight savings is not being processed

    Hi Chris,

    I think I've found an issue to do with time zones. When calling Solar with my lat/long (latitude: -38.2613, longitude: 145.1896), the returned date is always one day ahead of the for-date for all times (sunset, sunrise, all modes). Also, daylight savings is not being processed for my timezone (Melbourne, Australia)

    I think the day-ahead problem may stem from line 188;

    let localT = UT + (Double(timeZone.secondsFromGMT) / 3600.0)
    

    as this pushes the "hour" variable in the following line;

    let hour = floor(localT)
    

    into numbers between 24 and 48 (i.e. the next day)

    I tried fixing this up by putting the hour back into 0-24 hour range, but this mucked up the minute and second calculations. So, I had a think about timezones and went back to the underlying returned NSDate being an absolute number of seconds, regardless of timezone and that all your calculations were for UTC time. Given this, I (hack) changed line 188 to do nothing as follows;

    let localT = UT
    

    and replaced line 199;

    var date = calendar.dateFromComponents(components)
    

    with;

    calendar.timeZone = NSTimeZone(abbreviation: "UTC")!
    return calendar.dateFromComponents(components)
    

    By changing the the time zone to suit your calculated UTC time, the returned NSDate will be the correct absolute number of seconds and any code using the returned NSDate will have the appropriate timezone set. This means the time zone calculations for the calling apps purposes will all be handled by the Swift libraries. As a side effect of getting the day correct, this also fixed up the issue where daylight savings was not being handled correctly.

    NB: the early return I added in line 200 intentionally means lines 202 onwards are not called as they are no longer required.

    I tested this fix for both Melbourne, Australia and London, England. It got the correct day, time and daylight savings was processed correctly. What do you think?

    Cheers, Graham.

    bug 
    opened by grumBit 8
  • SPM support

    SPM support

    SPM support for the library. I have changed the sample json file to use multilane string to be compatible with sim prior swift 5.3 (resources). Both Carthage and pods version are still supported. SPM package contains passing tests and I have defined other supported platforms iOS(.v8), .macOS(.v10_15), .watchOS(.v4), .tvOS(.v11)

    Fixes #11.

    enhancement build 
    opened by mateuszmackowiak 4
  • error when excute carthage update

    error when excute carthage update

    There is error when I adding Solar to my project with carthage and hope you can check it out :) log: *** Fetching Solar *** Checking out Solar at "2.0.0" *** xcodebuild output can be found in /var/folders/0m/bv501p9j043_w386gf5g7dlh0000gn/T/carthage-xcodebuild.vDSKOj.log *** Building scheme "Solar" in Solar.xcodeproj Build Failed Task failed with exit code 65: /usr/bin/xcrun xcodebuild -project .../Carthage/Checkouts/Solar/Solar.xcodeproj -scheme Solar -configuration Release -derivedDataPath /Users/brucewzp/Library/Caches/org.carthage.CarthageKit/DerivedData/Solar/2.0.0 -sdk iphoneos ONLY_ACTIVE_ARCH=NO BITCODE_GENERATION_MODE=bitcode CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES clean build

    This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/0m/bv501p9j043_w386gf5g7dlh0000gn/T/carthage-xcodebuild.vDSKOj.log

    bug build 
    opened by brucewzp 4
  • isNighttime calculation incorrect

    isNighttime calculation incorrect

    official sunset today (2/12/17) was 5:45 pm in San Francisco. The isNighttime method returned true at 5:31 pm.

    I believe this is because it's using Date() without a time zone to calculate when sunset is. However, in Pacific timezone, it is already reporting GMT sunset for 2/14

    bug 
    opened by andrewkouri 4
  • Xcode 12.5 Build Warning

    Xcode 12.5 Build Warning

    I get the following build warning when building with Xcode 12.5:

    /Users/me/Library/Developer/Xcode/DerivedData/Project/SourcePackages/checkouts/Solar/Package.swift The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.5.99.
    

    This appears to have been fixed for Solar.podspec by 07e6310. Solar's Package.swift was likely overlooked. Please update the Package.swift deployment target to be consistent with the Solar.podspec.

    bug build 
    opened by sepw 3
  • Fix Carthage build errors

    Fix Carthage build errors

    Only build the test bundle as part of the Solar scheme when building for test. Removed the SolarTests scheme, which is redundant.

    Fixes #21.

    /cc @ceeK @bsudekum

    build 
    opened by 1ec5 3
  • calculate function uses hard coded

    calculate function uses hard coded "Official" rather than passed-in zenith

    Hi Chris,

    Thank you loads for the work porting the calculations to Swift, it's been very helpful!

    In testing I found the sunset times for offical, civil, etc., were all the same. In Solar.swift on line 162, I noticed the calculate function was not using the passed-in zenith and was instead always using the "Official" zenith;

       let cosH = (cos(Zenith.Official.rawValue.degreesToRadians) - (sinDec * sin(latitude.degreesToRadians))) / (cosDec * cos(latitude.degreesToRadians))
    

    This can be corrected with the following;

       let cosH = (cos(zenith.rawValue.degreesToRadians) - (sinDec * sin(latitude.degreesToRadians))) / (cosDec * cos(latitude.degreesToRadians))
    

    Cheers, Graham.

    bug 
    opened by grumBit 3
  • v3.0.0

    v3.0.0

    Updated the Xcode project, CocoaPods podspec, and readme for v3.0.0. This is a major version because of #53 #55, which increases the minimum iOS deployment target.

    Added a Solar-dev podspec that I’m planning to push to CocoaPods trunk. Initially it’ll be a workaround for #51, but we can treat it as a way to distribute prereleases in the future.

    /cc @MaximAlien @ceeK

    build 
    opened by 1ec5 2
  • Xcode 10 build error

    Xcode 10 build error

    After updating Xcode to version 10, it shows me the following error on import Solar: Module compiled with Swift 4.1.2 cannot be imported by the Swift 4.2 compiler. Any ideas how to fix this?

    build 
    opened by euroboy 2
  • Add sun position

    Add sun position

    Would you consider adding sun position information to this library, i.e. altitude and azimuth? See the docs at https://github.com/mourner/suncalc for an example. Feel free to close this issue if it's out of scope.

    enhancement 
    opened by jhurliman 2
  • v2.2.0

    v2.2.0

    Updated the Xcode project (using agvtool), CocoaPods podspec, and readme for ~~v2.3.0~~ v2.2.0. Also updated copyright statements for this year. A draft GitHub release has been prepared.

    @ceeK, I’ll need your help to push ~~v2.3.0~~ v2.2.0 to CocoaPods trunk once this PR lands (or I can do it if you make me a co-owner of the pod). Thanks!

    build 
    opened by 1ec5 1
  • WeatherKit

    WeatherKit

    WeatherKit has a CurrentWeather.isDaylight property and SunEvents struct that essentially replicate the functionality of this library. However, WeatherKit is only available for this year’s operating system releases (iOS 16, iPadOS 16, macOS 13, tvOS 16, watchOS 9). Should this library somehow integrate with WeatherKit on supported platforms, perhaps becoming a compatibility shim for it on unsupported Swift platforms like Linux?

    question 
    opened by 1ec5 3
  • isDaytime and isNightTime return incorrect values for polar day

    isDaytime and isNightTime return incorrect values for polar day

    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

    opened by ddekanski 0
  • Fix for incorrect results if local day is

    Fix for incorrect results if local day is "tomorrow" in UTC

    Fixes #40

    This issue appears if the date/time given to calculate is already "tomorrow" at UTC. For example, I'm in New York City, which is GMT-5. If I calculate between 00:00 - 18:59 hrs local time, I get a correct result. But if I calculate 19:00-23:59 local time, Solar return's tomorrow's result. A test is included in this PR to demonstrate.

    To fix, I added an optional timezone: parameter to Solar(). If timezone is not specified, UTC is assumed. This makes the patch backwards compatible. If timezone is included, the current time (in seconds) is offset by the time different between local and UTC. This ensures the calculations are done on the correct date, and not possibly "tomorrow's" date.

    opened by aaronfreimark 4
  • Resubmitted: Fixed issue when SunSet/Sunrise is on a different day from variable date

    Resubmitted: Fixed issue when SunSet/Sunrise is on a different day from variable date

    Resubmitted from #44

    Fixed the following scenario.

    When Sunrise timing is 2300 while current time is 2330, isDayTime wrongly shows false. When sunset timing is 0050 while current time is 0030, isDayTime wrongly shows false.

    bug 
    opened by Pehon1 0
  • Sunrise and Sunset dates off by 1 day.

    Sunrise and Sunset dates off by 1 day.

    It seems that the dates are 1 day in the future if the local time is the next day UTC.

    Not sure if this is the same problem as reported in #24?

    Here is a complete test. Note that the reported times are one day in the future from the correct times.

        ///    Sun and Moon Data for One Day
        ///
        ///    U.S. Naval Observatory
        ///    Astronomical Applications Department
        ///
        ///    (Longitude W 94° 0', Latitude N 39° 0')
        ///
        ///    Friday, May 3, 2019    Universal Time - 5h
        ///    Sun
        ///    Begin civil twilight    05:47
        ///    Sunrise    06:16
        ///    Sun transit    13:13
        ///    Sunset    20:11
        ///    End civil twilight    20:40
        ///    Moon
        ///    Moonrise    05:56
        ///    Moon transit    12:24
        ///    Moonset    19:00
        ///
        /// [https://aa.usno.navy.mil/data/docs/RS_OneDay.php](https://aa.usno.navy.mil/data/docs/RS_OneDay.php)
        func testPlainLatLon() {
            var tdf: DateFormatter = {
                let df = DateFormatter()
                df.dateFormat = "MM/dd/yyyy HH:mm zzz"
                return df
            }()
            let testCriticalEvening = tdf.date(from: "05/03/2019 19:20 CDT")!
            let testLocation: CLLocation = CLLocation(latitude: 39.00, longitude: -94.0)
            let expectedSunrise = "05/03/2019 06:16 CDT"
            let expectedSunset = "05/03/2019 20:11 CDT"
            let solar = Solar(for: testCriticalEvening, coordinate: testLocation.coordinate)
    
            XCTAssert(tdf.string(from: solar!.sunrise!) == expectedSunrise,
                      "Expected: \(expectedSunrise), Received: \(tdf.string(from: solar!.sunrise!))")
            XCTAssert(tdf.string(from: solar!.sunset!) == expectedSunset,
                      "Expected: \(expectedSunset), Received: \(tdf.string(from: solar!.sunset!))")
        }
    

    The results of the test are:

    UI Test Activity: 
    Assertion Failure: Solar_iOSTests.swift:198: XCTAssertTrue failed - Expected: 05/03/2019 06:16 CDT, Received: 05/04/2019 06:14 CDT
    
    UI Test Activity: 
    Assertion Failure: Solar_iOSTests.swift:200: XCTAssertTrue failed - Expected: 05/03/2019 20:11 CDT, Received: 05/04/2019 20:11 CDT
    
    opened by neilt 3
Releases(3.0.1)
Owner
Chris Howell
iOS @deliveroo. Twitter: @howellck
Chris Howell
A command-line tool and Swift Package for generating class diagrams powered by PlantUML

SwiftPlantUML Generate UML class diagrams from swift code with this Command Line Interface (CLI) and Swift Package. Use one or more Swift files as inp

null 374 Jan 3, 2023
A Swift micro-framework to easily deal with weak references to self inside closures

WeakableSelf Context Closures are one of Swift must-have features, and Swift developers are aware of how tricky they can be when they capture the refe

Vincent Pradeilles 72 Sep 1, 2022
Scaffold is a tool for generating code from Stencil templates, similar to rails gen.

?? Scaffold Scaffold is a tool for generating code from Stencil templates, similar to rails gen. It happens to be written in Swift, but it can output

Joshua Kaplan 33 Apr 5, 2022
Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. (Pure Swift, Supports Linux)

SwiftFoundation Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. Goals Provide a cross-platform in

null 620 Oct 11, 2022
Focus is an Optics library for Swift (where Optics includes Lens, Prisms, and Isos)

Focus Focus is an Optics library for Swift (where Optics includes Lens, Prisms, and Isos) that is inspired by Haskell's Lens library. Introduction Foc

TypeLift 201 Dec 31, 2022
Plugin and runtime library for using protobuf with Swift

Swift Protobuf Welcome to Swift Protobuf! Apple's Swift programming language is a perfect complement to Google's Protocol Buffer ("protobuf") serializ

Apple 4.1k Dec 28, 2022
A cross-platform library of Swift utils to ease your iOS | macOS | watchOS | tvOS and Linux development.

Mechanica A library of Swift utils to ease your iOS, macOS, watchOS, tvOS and Linux development. Requirements Documentation Installation License Contr

Alessandro 28 Aug 28, 2022
A μframework of extensions for SequenceType in Swift 2.0, inspired by Python's itertools, Haskell's standard library, and other things.

SwiftSequence Full reference here. (If you're looking for data structures in Swift, those have been moved to here) SwiftSequence is a lightweight fram

Donnacha Oisín Kidney 376 Oct 12, 2022
Swift library and command line tool that interacts with the mach-o file format.

MachO-Reader Playground project to learn more about the Mach-O file format. How to run swift run MachO-Reader <path-to-binary> You should see a simila

Gonzalo 5 Jun 25, 2022
A Swift library for converting to and from opus/ogg format

swift-ogg This library provides a very simple API to convert between opus/ogg and MPEG4AAC/m4a files. It uses opus's libopus libogg to convert between

Element 13 Dec 31, 2022
swift-highlight a pure-Swift data structure library designed for server applications that need to store a lot of styled text

swift-highlight is a pure-Swift data structure library designed for server applications that need to store a lot of styled text. The Highlight module is memory-efficient and uses slab allocations and small-string optimizations to pack large amounts of styled text into a small amount of memory, while still supporting efficient traversal through the Sequence protocol.

kelvin 4 Aug 14, 2022
ZIP Foundation is a library to create, read and modify ZIP archive files.

ZIP Foundation is a library to create, read and modify ZIP archive files. It is written in Swift and based on Apple's libcompression for high performa

Thomas Zoechling 1.9k Dec 27, 2022
Butterfly is a lightweight library for integrating bug-report and feedback features with shake-motion event.

Butterfly is a lightweight library for integrating bug-report and feedback features with shake-motion event. Goals of this project One of th

Zigii Wong 410 Sep 9, 2022
📘A library for isolated developing UI components and automatically taking snapshots of them.

A library for isolated developing UI components and automatically taking snapshots of them. Playbook Playbook is a library that provides a sandbox for

Playbook 969 Dec 27, 2022
Hammer is a touch, stylus and keyboard synthesis library for emulating user interaction events

Hammer is a touch, stylus and keyboard synthesis library for emulating user interaction events. It enables better ways of triggering UI actions in unit tests, replicating a real world environment as much as possible.

Lyft 626 Dec 23, 2022
Pigeon is a SwiftUI and UIKit library that relies on Combine to deal with asynchronous data.

Pigeon ?? Introduction Pigeon is a SwiftUI and UIKit library that relies on Combine to deal with asynchronous data. It is heavily inspired by React Qu

Fernando Martín Ortiz 369 Dec 30, 2022
μ-library enabling if/else and switch statements to be used as expressions.

swift-expression Many languages such as Scala, Rust and Kotlin support using if/else and switch statements as expressions – meaning that they can by t

Nikita Mounier 1 Nov 8, 2021
macOS system library in Swift

SystemKit A macOS system library in Swift based off of libtop, from Apple's top implementation. For an example usage of this library, see dshb, a macO

null 323 Jan 5, 2023
Swift library to develop custom Alexa Skills

AlexaSkillsKit AlexaSkillsKit is a Swift library that allows you to develop custom skills for Amazon Alexa, the voice service that powers Echo. It tak

Claus Höfele 170 Dec 27, 2022