Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
JulianDate.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <janus/janus.hpp>
5#include <tuple>
7
8namespace vulcan::time {
9
10// =============================================================================
11// Calendar ↔ Julian Date Conversions (Numeric Only - I/O Operations)
12// =============================================================================
13
24[[nodiscard]] inline double calendar_to_jd(int year, int month, int day,
25 int hour = 0, int min = 0,
26 double sec = 0.0) {
27
28 // Algorithm from Vallado, "Fundamentals of Astrodynamics", 4th Ed., Eq.
29 // 3-14 JD = 367*Y - floor(7*(Y + floor((M+9)/12))/4) + floor(275*M/9) + D +
30 // 1721013.5
31 // + ((sec/60 + min)/60 + hour)/24
32
33 double jd =
34 367.0 * year -
35 std::floor(7.0 * (year + std::floor((month + 9.0) / 12.0)) / 4.0) +
36 std::floor(275.0 * month / 9.0) + day + 1721013.5 +
37 ((sec / 60.0 + min) / 60.0 + hour) / 24.0;
38
39 return jd;
40}
41
45[[nodiscard]] inline std::tuple<int, int, int, int, int, double>
46jd_to_calendar(double jd) {
47 double jd_plus = jd + 0.5;
48 int Z = static_cast<int>(std::floor(jd_plus));
49 double F = jd_plus - Z;
50
51 int A;
52 if (Z < 2299161) {
53 A = Z;
54 } else {
55 int alpha = static_cast<int>(std::floor((Z - 1867216.25) / 36524.25));
56 A = Z + 1 + alpha - alpha / 4;
57 }
58
59 int B = A + 1524;
60 int C = static_cast<int>(std::floor((B - 122.1) / 365.25));
61 int D = static_cast<int>(std::floor(365.25 * C));
62 int E = static_cast<int>(std::floor((B - D) / 30.6001));
63
64 double day_frac = B - D - std::floor(30.6001 * E) + F;
65 int day = static_cast<int>(std::floor(day_frac));
66
67 int month = (E < 14) ? E - 1 : E - 13;
68 int year = (month > 2) ? C - 4716 : C - 4715;
69
70 double frac = day_frac - day;
71 double hours_total = frac * 24.0;
72 int hour = static_cast<int>(std::floor(hours_total));
73 double mins_total = (hours_total - hour) * 60.0;
74 int min = static_cast<int>(std::floor(mins_total));
75 double sec = (mins_total - min) * 60.0;
76
77 // Handle numerical edge cases
78 if (sec >= 60.0 - 1e-10) {
79 sec = 0.0;
80 min += 1;
81 }
82 if (min >= 60) {
83 min = 0;
84 hour += 1;
85 }
86 if (hour >= 24) {
87 hour = 0;
88 day += 1;
89 }
90
91 return {year, month, day, hour, min, sec};
92}
93
94// =============================================================================
95// Modified Julian Date Conversions (Templated)
96// =============================================================================
97
102template <typename Scalar>
103[[nodiscard]] constexpr Scalar jd_to_mjd(const Scalar &jd) {
104 return jd - constants::time::MJD_OFFSET;
105}
106
110template <typename Scalar>
111[[nodiscard]] constexpr Scalar mjd_to_jd(const Scalar &mjd) {
112 return mjd + constants::time::MJD_OFFSET;
113}
114
115// =============================================================================
116// J2000.0 Reference Utilities (Templated)
117// =============================================================================
118
123template <typename Scalar>
124[[nodiscard]] constexpr Scalar jd_to_j2000_seconds(const Scalar &jd) {
126}
127
131template <typename Scalar>
132[[nodiscard]] constexpr Scalar j2000_seconds_to_jd(const Scalar &sec) {
134}
135
139template <typename Scalar>
140[[nodiscard]] constexpr Scalar jd_to_j2000_centuries(const Scalar &jd) {
142}
143
147template <typename Scalar>
148[[nodiscard]] constexpr Scalar j2000_centuries_to_jd(const Scalar &T) {
150}
151
152// =============================================================================
153// Day of Year Utilities (Numeric - Calendar Operations)
154// =============================================================================
155
156[[nodiscard]] inline constexpr bool is_leap_year(int year) {
157 return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
158}
159
160[[nodiscard]] inline int day_of_year(int year, int month, int day) {
161 constexpr int days_before_month[] = {0, 31, 59, 90, 120, 151,
162 181, 212, 243, 273, 304, 334};
163 int doy = days_before_month[month - 1] + day;
164 if (month > 2 && is_leap_year(year)) {
165 doy += 1;
166 }
167 return doy;
168}
169
170[[nodiscard]] inline std::tuple<int, int> doy_to_month_day(int year, int doy) {
171 constexpr int days_in_month[] = {31, 28, 31, 30, 31, 30,
172 31, 31, 30, 31, 30, 31};
173 int remaining = doy;
174 for (int m = 1; m <= 12; ++m) {
175 int days = days_in_month[m - 1];
176 if (m == 2 && is_leap_year(year))
177 days = 29;
178 if (remaining <= days)
179 return {m, remaining};
180 remaining -= days;
181 }
182 return {12, 31};
183}
184
185} // namespace vulcan::time
constexpr double SECONDS_PER_DAY
Seconds per day.
Definition TimeConstants.hpp:45
constexpr double MJD_OFFSET
Julian Date offset: JD = MJD + MJD_OFFSET.
Definition TimeConstants.hpp:16
constexpr double DAYS_PER_CENTURY
Days per Julian century.
Definition TimeConstants.hpp:51
constexpr double JD_J2000
Julian Date of J2000.0 epoch (2000-01-01 12:00:00 TT).
Definition TimeConstants.hpp:10
Definition Epoch.hpp:12
constexpr Scalar mjd_to_jd(const Scalar &mjd)
Convert Modified Julian Date to Julian Date.
Definition JulianDate.hpp:111
std::tuple< int, int > doy_to_month_day(int year, int doy)
Definition JulianDate.hpp:170
std::tuple< int, int, int, int, int, double > jd_to_calendar(double jd)
Convert Julian Date to calendar date/time (numeric only).
Definition JulianDate.hpp:46
constexpr Scalar j2000_centuries_to_jd(const Scalar &T)
Convert Julian centuries since J2000.0 to Julian Date.
Definition JulianDate.hpp:148
constexpr bool is_leap_year(int year)
Definition JulianDate.hpp:156
constexpr Scalar j2000_seconds_to_jd(const Scalar &sec)
Convert seconds since J2000.0 to Julian Date.
Definition JulianDate.hpp:132
constexpr Scalar jd_to_j2000_seconds(const Scalar &jd)
Convert Julian Date to seconds since J2000.0.
Definition JulianDate.hpp:124
int day_of_year(int year, int month, int day)
Definition JulianDate.hpp:160
constexpr Scalar jd_to_j2000_centuries(const Scalar &jd)
Convert Julian Date to Julian centuries since J2000.0.
Definition JulianDate.hpp:140
constexpr Scalar jd_to_mjd(const Scalar &jd)
Convert Julian Date to Modified Julian Date.
Definition JulianDate.hpp:103
double calendar_to_jd(int year, int month, int day, int hour=0, int min=0, double sec=0.0)
Convert calendar date/time to Julian Date.
Definition JulianDate.hpp:24