将公历日期转换为朱利安日期然后再返回(随时间)

时间:2012-10-12 18:01:14

标签: c++ date gregorian-calendar date-conversion

我正在编写一个程序,必须将当前的格里高利日期和时间转换为朱利安日期,然后再返回格里高利门。最终我需要添加能够添加年,月,日,小时,分钟和秒的功能,但我需要先将这部分放在一边。

现在我有从Gregorian Date到Julian Date的转换,所以从逻辑上来说,我觉得我应该能够以某种方式反转这个等式,而且这很简单。然而,我正在做一个两步过程,我首先将格里高利日转换为儒略日数,然后转换为儒略日(差异是天数不包括时间)。所以将其转换回来应该意味着我必须从等式中得到小时,分钟和秒钟,然后将朱利安日数单独转换回格里高利日期。我想这是一个简单的分割和修改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

我希望我已经解释了我需要的东西!感谢您提供的任何帮助!

3 个答案:

答案 0 :(得分:1)

你可以使用这个库。 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/

What are the default values taken (say 1721119) to calculate the Gregorian Year, Month, Day from Julian Day

http://www.projectpluto.com/source.htm

答案 1 :(得分:1)

free, open source C++11/14 date/time library使用<chrono>基础通过设置来自所有日历的转换来促进任意两个日历之间的转换3}}

碰巧有朱利安历法以及公历的两个变体({年,月,日}和{年,月,工作日,指数}),基于ISO周的日历和(不完美) )伊斯兰历法。日历相对容易添加,一旦添加日历,就可以与所有其他日历互操作,并且<chrono>的{​​{1}}可以任意精确度。

示例代码:

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};
}

如果您想了解有关基础算法的更多详细信息,请在此处讨论(并经过验证):

Unix Time

答案 2 :(得分:0)

这是一种解决方案,其中全部时间以hhmmss格式返回,但你会得到它们。请参阅函数的结尾处 //小时:秒/ 3600%24,分:秒/ 60%60,秒秒%60

unsigned JulianToTime(double julianDate) {      double remainder = julianDate - (unsigned)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; 

}