Я пишу программу, которая должна преобразовать текущую григорианскую дату и время в юлианскую дату, а затем обратно в григорианские ворота. В конце концов мне нужно будет добавить функциональность, позволяющую добавлять годы, месяцы, дни, часы, минуты и секунды, но мне нужно сначала убрать эту часть.
Прямо сейчас у меня есть преобразование из григорианской даты в юлианскую дату, так что логически я чувствую, что должен просто каким-то образом изменить уравнение, и это будет довольно просто. Однако я делаю двухэтапный процесс, в котором я сначала конвертирую григорианскую дату в число юлианских дней, а затем в юлианскую дату (разница в том, что число дней не включает время). Таким образом, преобразование обратно должно означать, что я должен получить часы, минуты и секунды из уравнения, а затем выполнить отдельное преобразование для номера дня в Юлиане обратно в григорианскую дату. Я хотел бы думать, что это простой процесс деления и модификации 3 раза по часам, минутам и секундам, и обычно я довольно хорошо разбираюсь в математике и продумываю эти вещи логически, но мой мозг просто не работает на этом.
jdn_t gregorian_to_jd(year_t year, month_t month, day_t day, hour_t hour, minute_t minute, second_t second)
{
//implement the conversion from gregorian to jdn
long long a = (14 - month)/12;
long long y = year + 4800 - a;
long long m = month + 12*a - 3;
jdn_t jdn = day + (153 * m + 2)/5 + 365*y + y/4 - y/100 + y/400 - 32045 - 0.5;
jdnt_t jdnt = jdn + (hour-12)/24 + minute/1440 + second/86400;
}
void jdn_to_gregorianTime(jdnt_t jdnt,year_t & year, month_t & month, day_t & day, hour_t & hour, minute_t & minute, second_t & second)
{
long long j = static_cast<long long>(jdnt + 0.5) + 32044;
long long g = j / 146097;
long long dg = j % 146097;
long long c = (dg / 36524 + 1) * 3 / 4;
long long dc = dg - c * 36524;
long long b = dc / 1461;
long long db = dc % 1461;
long long a = (db / 365 + 1) *3 / 4;
long long da = db - a * 365;
long long y = g * 400 + c * 100 + b * 4 + a;
long long m = (da * 5 + 308) / 153 - 2;
long long d = da - (m+4) * 153 / 5 + 122;
year = y - 4800 + (m + 2) / 12;
month = (m + 2) % 12 + 1;
day = static_cast<day_t>(d + 1);
В нижней части приведены расчеты, которые мне понадобятся, как только я смогу вывести свои часы, минуты и секунды. Все, что они делают, это возвращают юлианский номер дня обратно к григорианской дате.
Вики-страница объясняет всю юлианскую дату для тех, кто не знаком с фермой: http://en.wikipedia.org/wiki/Julian_day
Надеюсь, я достаточно хорошо объяснил, что мне нужно! Спасибо за любую помощь, которую вы, ребята, можете предложить!
Вы можете просто использовать эту библиотеку.
http://www.iausofa.org/current_C.html
Или получить некоторое представление, просто просматривая его и используя концепции.
Я использовал это раньше, и это довольно просто. Много указателей, хотя так быть готовым.
Тот, о котором я знаю, это cal2jd, а другой — jd2cal.
Те, вы получите даты. Есть больше времени и форматирования. У этого есть несколько примеров в документах.
И если вы так склонны хотеть C ++, то есть
http://www.naughter.com/aa.html
который имеет функции для астрономических расчетов.
Удачи!
Некоторые другие ресурсы …
http://129.79.46.40/~foxd/cdrom/musings/formulas/formulas.htm
http://robm.fastmail.fm/articles/date_class.html
https://www.autoitscript.com/forum/topic/182372-standalone-moon-phase-calculation/
это бесплатная библиотека с открытым исходным кодом C ++ 11/14 дата / время использует <chrono>
основа для облегчения конверсии между любой два календаря путем настройки конверсий из все календари от и до Unix Time.
Он имеет юлианский календарь, а также два варианта григорианского календаря ({год, месяц, день} и {год, месяц, день недели, индекс}), недельный календарь ISO и (несовершенный) исламский календарь , Календари относительно легко добавляются, и после добавления календарь совместим со всеми другими календарями, и <chrono>
«s system_clock::time_point
с любой точностью.
Пример кода:
#include "date.h"#include "julian.h"#include <iostream>
int
main()
{
using namespace date::literals;
auto ymd = 2016_y/oct/11;
auto jymd = julian::year_month_day{ymd};
auto ymd2 = date::year_month_day{jymd};
std::cout << ymd << '\n';
std::cout << jymd << '\n';
auto ymd2 = date::year_month_weekday{jymd};
}
какие выводы:
2016-10-11
2016-09-28
2016/Oct/Tue[2]
Если вам нужны более подробные сведения об основных алгоритмах, они обсуждаются (и проверены) здесь:
Это одно из решений, в котором полное время возвращается в формате hhmmss, но вы получаете их отдельно. Смотрите конец функции на
// часы: секунды / 3600% 24, минуты: секунды / 60% 60, секунды с% 60
неподписанный JulianToTime (двойной julianDate)
{
двойной остаток = julianDate — (без знака) julianDate;
const unsigned long long base = 1000000;
const unsigned long long halfbase = 500000;
const unsigned secsPerDay = 86400;
// "rounded" remainder after adding half a day
unsigned long long rndRemainder = (unsigned long long)(remainder * base + halfbase) % base;
rndRemainder *= secsPerDay;
// "rounded" number of seconds
unsigned long long nsecs = (rndRemainder + halfbase) / base;
//hours: secs/3600 % 24, min: secs/60 % 60, secs secs % 60
unsigned rtn = (nsecs/3600 % 24) * 10000 + (nsecs/60 % 60) * 100 + (nsecs % 60);
return rtn;
}