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-dev", "~> 3.0"

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

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

Carthage

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

github "ceeK/Solar" ~> 3.0

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 3.0.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: "3.0.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
Dates and times made easy in iOS

DateTools DateTools was written to streamline date and time handling in iOS. Classes and concepts from other languages served as an inspiration for Da

Matthew York 7.2k Dec 30, 2022
Typical master detail SAMPLE application written in Swift to test NY Times Most Popular API

NYTimes-Demo: Typical master detail SAMPLE application written in Swift to test NY Times Most Popular API. This SAMPLE application is written in Swift

Atif Naveed 0 Nov 3, 2021
🕐 Format your dates/times as emojis.

EmojiTimeFormatter Format your dates/times as emojis ?? ?? ?? Description You can build easy to understand user interfaces with EmojiTimeFormatter or

Thomas Paul Mann 80 Feb 7, 2022
SwiftMoment - A time and calendar manipulation library for iOS 9+, macOS 10.11+, tvOS 9+, watchOS 2+ written in Swift 4.

SwiftMoment This framework is inspired by Moment.js. Its objectives are the following: Simplify the manipulation and readability of date and interval

Adrian Kosmaczewski 1.6k Dec 31, 2022
NTP library for Swift and Objective-C. Get the true time impervious to device clock changes.

TrueTime for Swift Make sure to check out our counterpart too: TrueTime, an NTP library for Android. NTP client for Swift. Calculate the time "now" im

Instacart 530 Jan 4, 2023
Timekeeper is an easy-to-use time measurement library written in Swift, with support for iOS, tvOS, watchOS and macOS.

Timekeeper is an easy-to-use time measurement library written in Swift, with support for iOS, tvOS, watchOS and macOS. Installation Timekee

Andreas Pfurtscheller 1 Oct 18, 2021
SwiftUI library to display a clock. You can move the arms to change the time, change the style of the clock and customise some configurations.

SwiftClockUI Clock UI for SwiftUI This library has been tested ✅ ?? macOS Catalina 10.15.3 ✅ ?? macOS Big Sur 11.6 ✅ ?? iOS 13 ✅ ?? iOS 14 ✅ ?? iOS 15

Renaud Jenny 239 Dec 29, 2022
Elegant NTP date library in Swift

Kronos is an NTP client library written in Swift. It supports sub-seconds precision and provides a stable monotonic clock that won't be affected by ch

Mobile Native Foundation 575 Dec 23, 2022
Building a better date/time library for Swift

Time Time is a Swift package that makes dealing with calendar values a natural and straight-forward process. Working with calendars can be extremely c

Dave DeLong 2k Dec 31, 2022
UmaBasicAlertKit is a Swift UI library for iOS

UmaBasicAlertKit UmaBasicAlertKit is a Swift UI library for iOS. This library al

UmaKim 3 Jan 28, 2022
Customizable Calendar SwiftUI Library

SwiftUI Customizable Calendar Library

LeeProgrammer 8 Oct 11, 2022
A Cocoa NSFormatter subclass to convert dates to and from ISO-8601-formatted strings. Supports calendar, week, and ordinal formats.

ISO 8601: The only date format worth using Obligatory relevant xkcd: How to use this code in your program Add the source files to your project. Parsin

Peter Hosey 601 Sep 4, 2022
A TimeZonePicker UIViewController similar to the iOS Settings app. Search and select from a range of cities and countries to find your most suitable time zone.

TimeZonePicker A TimeZonePicker UIViewController similar to the iOS Settings app. Search and select from a range of cities and countries to find your

Gligor Kotushevski 125 Dec 13, 2022
A basic countdown app that allows the user to create, edit, and delete events. Each event contains a live countdown timer to a specified date and time.

Event Countdown App (iOS) Created by Lucas Ausberger About This Project Created: January 4, 2021 Last Updated: January 8, 2021 Current Verison: 1.1.1

Lucas Ausberger 1 Jan 8, 2022
Create your own faces for watchOS. Customize the watch hands, layout, colors, and images. Edit faces on your phone and switch them on the watch.

AppleWatchFaces Design your own watch faces for the apple watch. They are not real watch faces, but a watchOS app running on the watch that tells you

Mike Hill 395 Oct 20, 2022
Sudoless Frequency Metric Retrieval for MacOS (Supports Apple Silicon and Intel CPUs and iGPUs)

SFMRM ('sifˌmərˌim) Sudoless Frequency Metric Retrieval for MacOS This project is designed to retrieve active frequency and residency metrics from you

BitesPotatoBacks 20 Dec 25, 2022
Time is a Swift package that makes dealing with calendar values a natural and straight-forward process.

Time Time is a Swift package that makes dealing with calendar values a natural and straight-forward process. Working with calendars can be extremely c

Dave DeLong 2k Dec 31, 2022
📆 Breeze through Date, DateComponents, and TimeInterval with Swift!

Datez ?? Breeze through Date, DateComponents, and TimeInterval Highlights Two Custom Structs Only (value types FTW!): DateView: An Date associated wit

Kitz 263 Dec 7, 2022
SwiftDate 🐔 Toolkit to parse, validate, manipulate, compare and display dates, time & timezones in Swift.

Toolkit to parse, validate, manipulate, compare and display dates, time & timezones in Swift. What's This? SwiftDate is the definitive toolchain to ma

Daniele Margutti 7.2k Jan 4, 2023