Files
Moon-Watch/Shared/MoonPhase.swift
dave-enterprise 87f8c7173c Add MoonWatch app, widget extension, shared module, and .gitignore
Adds the real MoonWatch implementation on top of the initial Xcode
template: new SwiftUI views (MoonDiskView, StarFieldView), the
MoonWatchWidget extension, and a Shared module containing the moon
phase calculator, shadow shape, and shared asset catalog. Also adds a
Swift/Xcode/macOS .gitignore and untracks per-user xcuserdata files.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 21:05:16 -07:00

51 lines
1.6 KiB
Swift

//
// MoonPhase.swift
// Shared between MoonWatch and MoonWatchWidget.
//
import Foundation
public enum MoonPhaseName: String, CaseIterable, Sendable {
case newMoon = "New Moon"
case waxingCrescent = "Waxing Crescent"
case firstQuarter = "First Quarter"
case waxingGibbous = "Waxing Gibbous"
case fullMoon = "Full Moon"
case waningGibbous = "Waning Gibbous"
case thirdQuarter = "Third Quarter"
case waningCrescent = "Waning Crescent"
}
public struct MoonPhaseSnapshot: Equatable, Sendable {
public let date: Date
/// Position in synodic month, 0 at new moon approaching 1 at the next new moon.
public let normalizedPhase: Double
/// Days since last new moon, in `[0, synodicMonth)`.
public let moonAgeDays: Double
public let namedPhase: MoonPhaseName
/// Fraction of the apparent disk illuminated, 01.
public let illuminatedFraction: Double
/// The next phase that will begin after the current one.
public let nextPhaseName: MoonPhaseName
/// Days until the next phase transition.
public let daysToNextPhase: Double
public init(
date: Date,
normalizedPhase: Double,
moonAgeDays: Double,
namedPhase: MoonPhaseName,
illuminatedFraction: Double,
nextPhaseName: MoonPhaseName,
daysToNextPhase: Double
) {
self.date = date
self.normalizedPhase = normalizedPhase
self.moonAgeDays = moonAgeDays
self.namedPhase = namedPhase
self.illuminatedFraction = illuminatedFraction
self.nextPhaseName = nextPhaseName
self.daysToNextPhase = daysToNextPhase
}
}