Skip to content

Releases: mannylopez/TinyMoon

[3.0.1] Add timezone to fullMoonName computed property

05 Sep 07:06
521310a
Compare
Choose a tag to compare

What's Changed

Bug fix

  • Add timezone to fullMoonName computed property by @mannylopez in #43

Full Changelog: 3.0.0...3.0.1

[3.0.0] Add more metadata to Moon and ExactMoon. Update to API.

25 Jul 00:27
e77760d
Compare
Choose a tag to compare

Breaking change

If your app uses the Moon.moonDetail property to access any of the following properties

public struct MoonDetail: Hashable {

    public let julianDay: Double
    /// Number of days elapsed into the synodic cycle, represented as a fraction
    public let daysElapsedInCycle: Double
    /// Age of the moon in days, minutes, hours
    public let ageOfMoon: (days: Int, hours: Int, minutes: Int)
    /// Illuminated portion of the Moon, where 0.0 = new and 0.99 = full
    public let illuminatedFraction: Double
    /// Distance of moon from the center of the Earth, in kilometers
    public let distanceFromCenterOfEarth: Double
    /// Phase of the Moon, represented as a fraction
    ///
    /// Varies between `0.0` to `0.99`.
    /// `0.0` new moon,
    /// `0.25` first quarter,
    /// `0.5` full moon,
    /// `0.75` last quarter
    public let phase: Double
}

these properties can now be accessed directly via Moon

public struct Moon: Hashable {

    init() {...}

    // MARK: Public

    /// Represents where the phase is in the current synodic cycle. Varies between `0.0` to `0.99`.
    ///
    /// `0.0` new moon, `0.25` first quarter, `0.5` full moon, `0.75` last
    public let phaseFraction: Double
    /// Illuminated fraction of Moon's disk, between `0.0` and `1.0`.
    ///
    /// `0` indicates a new moon and `1.0` indicates a full moon.
    public let illuminatedFraction: Double
    public let moonPhase: MoonPhase
    public let name: String
    public let emoji: String
    public let date: Date
    /// Returns `0` if the current `date` is a full moon
    public var daysTillFullMoon: Int
    /// Returns `0` if the current `date` is a new moon
    public var daysTillNewMoon: Int
    public var moonDetail: TinyMoon.MoonDetail

    public var fullMoonName: String? {
      if isFullMoon() {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.month], from: date)
        if let month = components.month {
          return fullMoonName(month: month)
        }
      }
      return nil
    }

    public func isFullMoon() -> Bool {
      switch moonPhase {
      case .fullMoon: true
      default: false
      }
    }
}

What's Changed

Full Changelog: 2.4.1...3.0.0

[2.4.1] Create TimeTestHelper and move timezone and Date helpers there

23 Jul 04:38
64ccd1a
Compare
Choose a tag to compare

What's Changed

  • Move time date and timezone helpers to TimeTestHelper by @mannylopez in #37

Full Changelog: 2.4.0...2.4.1

[2.4.0] Add MoonDetail to public API

13 Jul 17:38
8705319
Compare
Choose a tag to compare

MoonDetail includes much more granular properties for the moon at a given time. The plan is to expose these in the public API soon, but for now, they can be accessed through the public API via MoonDetail.

public struct MoonDetail: Hashable {

    public let julianDay: Double
    /// Number of days elapsed into the synodic cycle, represented as a fraction
    public let daysElapsedInCycle: Double
    /// Age of the moon in days, minutes, hours
    public let ageOfMoon: (days: Int, hours: Int, minutes: Int)
    /// Illuminated portion of the Moon, where 0.0 = new and 0.99 = full
    public let illuminatedFraction: Double
    /// Distance of moon from the center of the Earth, in kilometers
    public let distanceFromCenterOfEarth: Double
    /// Phase of the Moon, represented as a fraction
    ///
    /// Varies between `0.0` to `0.99`.
    /// `0.0` new moon,
    /// `0.25` first quarter,
    /// `0.5` full moon,
    /// `0.75` last quarter
    public let phase: Double
}

[2.3.0] Accurate phase (MoonTool)

13 Jul 00:38
50b5dfd
Compare
Choose a tag to compare

What's Changed

TinyMoon is now a lot more accurate. SunCalc has known issues in it's Moon calculations. In my tests, I discovered two bugs

1//
The phase value "jumped" around the full moon. This happened when the angle switched from positive to negative and the ternary operator caused a non linear jump, when phase should be gradual.

// https://github.com/mourner/suncalc/blob/master/suncalc.js#L245
phase: 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI,

This is what I mean by "jump" and not gradual:

...
phase = 0.47
phase = 0.48
phase = 0.51
phase = 0.50
phase = 0.49
...

2//
Also noticed that moon phases are off by about 4.5hrs. Documented here: #27

Solution

I found the excellent MoonTool program, https://www.fourmilab.ch/moontoolw/, that allowed me to download the source code. I converted the C code to Swift and removed the non-relevant parts. I then replaced phase calculations to use the new MoonTool-based method and all tests passed.

I removed most of SunCalc's formulas.

Changelog

Full Changelog: 2.2.0...2.3.0

[2.2.0] TimeZone support

09 Jul 01:26
39a9eee
Compare
Choose a tag to compare

What's Changed

Full Changelog: 2.1.0...2.2.0

[2.1.0] Update moon calculations under the hood

08 Jun 04:31
2f013f2
Compare
Choose a tag to compare

What's Changed

Full Changelog: 2.0.0...2.1.0

[2.0.0] Refactor TinyMoon to act as namespace

30 May 01:43
9ee3712
Compare
Choose a tag to compare

Breaking change This is a major release, will update version to 2.0.0

TinyMoon namespace

Main change is that instead of having to instantiate TinyMoon, like this

let moon = TinyMoon().calculateMoonPhase()

Now the API is simpler and TinyMoon acts as a namespace, like this

let moon = TinyMoon.calculateMoonPhase()

Simplify Moon

I've also moved the logic of instantiating the Moon object into the Moon initializer, so instead of this

public struct Moon: Hashable {
  init(moonPhase: MoonPhase, lunarDay: Double, maxLunarDay: Double, date: Date) {...}
...
}

The Moon initializer now looks like this

public struct Moon: Hashable {
  init(date: Date) {...}
...
}

This will make it easier to test the functions inside of Moon

To update

// Replace the following
TinyMoon().calculateMoonPhase()
// with
TinyMoon.calculateMoonPhase()

[1.2.0] Add daysTillNewMoon property

30 May 00:03
4f57a87
Compare
Choose a tag to compare

Adds a new property, daysTillNewMoon, to the TinyMoon API.

Usage

let moon = TinyMoon().calculateMoonPhase(Date())
print(moon.daysTillNewMoon) // prints number of days till new moon

Will return 0 if the date given is a new moon

[1.1.0] Make Moon properties public

16 May 23:43
Compare
Choose a tag to compare

Full Changelog: main@{1day}...main

Makes the following properties public on Moon object:

  • lunarDay
  • date
  • isFullMoon