krz/moonrise

Night-sky companion for iPhone, Apple Watch and Vision Pro: what's up tonight, the Moon, planets, launches and missions, and a Library of the solar system. SwiftUI app with a Cloudflare Workers backend. astronomy cloudflare-workers ios night-sky space swiftui visionos watchos

Packages/MoonriseKit/Sources/SkyEngine/MarsTime.swift

45 lines · 1794 bytes

 1import Foundation
 2
 3/// Mars Coordinated Time and rover local times, after NASA GISS Mars24 (Allison & McEwen 2000).
 4public enum MarsTime {
 5    public struct Rover: Sendable, Identifiable {
 6        public var name: String
 7        public var site: String
 8        /// East longitude in degrees.
 9        public var longitude: Double
10        /// Mars Sol Date of the landing sol's local midnight (sol 0).
11        public var landingSol: Int
12        public var id: String { name }
13
14        public static let active: [Rover] = [
15            Rover(name: "Perseverance", site: "Jezero Crater", longitude: 77.45, landingSol: 52304),
16            Rover(name: "Curiosity", site: "Gale Crater", longitude: 137.44, landingSol: 49269),
17        ]
18    }
19
20    /// TT − UTC: 32.184 s plus 37 leap seconds (none since 2017).
21    static let ttMinusUTC = 69.184
22
23    /// Mars Sol Date.
24    public static func msd(_ date: Date) -> Double {
25        let jdTT = (date.timeIntervalSince1970 + ttMinusUTC) / 86_400 + 2_440_587.5
26        return (jdTT - 2_405_522.0028779) / 1.0274912517
27    }
28
29    /// Local mean solar time in hours (0..<24) at an east longitude.
30    public static func localMeanTime(_ date: Date, eastLongitude: Double) -> Double {
31        let mtc = (msd(date) * 24).truncatingRemainder(dividingBy: 24)
32        let t = (mtc + eastLongitude / 15).truncatingRemainder(dividingBy: 24)
33        return t < 0 ? t + 24 : t
34    }
35
36    /// Mission sol number (sol 0 is the landing sol).
37    public static func sol(_ date: Date, rover: Rover) -> Int {
38        Int((msd(date) + rover.longitude / 360).rounded(.down)) - rover.landingSol
39    }
40
41    public static func format(hours: Double) -> String {
42        let total = Int(hours * 60)
43        return String(format: "%02d:%02d", total / 60 % 24, total % 60)
44    }
45}