将公历日期转换为儒略日期,再将其转换回来(包括时间)

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 希望我已经足够清楚地解释了我所需要的内容!感谢您能提供任何帮助!

Boost Date_Time 库已经完成了所有这些工作。 - Dirk Eddelbuettel
你可能可以使用或调整底部链接的C++代码(http://emr.cs.iit.edu/~reingold/calendars.shtml)。这是由Calendrical Calculations的作者之一Edward M. Reingold编写的。 - Blastfurnace
3个回答

3
这个 免费、开源的 C++11/14 日期/时间库 使用 <chrono> 基础设施来促进任意两个日历之间的转换,通过设置从所有日历到Unix Time的转换以及从Unix Time到所有日历的转换。

它恰好有一个儒略日历以及两个格里高利日历变体({年,月,日}和{年,月,星期几,索引}),ISO 基于周的日历和一个(不完美的)伊斯兰教日历。日历相对容易添加,一旦添加了日历,它就与所有其他日历互操作,并且与<chrono>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]

如果您想了解更多关于基础算法的细节,可以在这里找到相关讨论和证明:

http://howardhinnant.github.io/date_algorithms.html


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/

计算公历年月日从儒略日时采用哪些默认值(例如1721119)?

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


0

这是一个解决方案,其中完整时间以hhmmss格式返回,但您可以将它们分开。请参见函数末尾处的代码: //hours: secs/3600 % 24, min: secs/60 % 60, secs secs % 60

无符号的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; 

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接