3

我正在编写一个程序,该程序必须将当前的公历日期和时间转换为儒略日期,然后再转换回公历门。最终,我将需要添加能够添加年、月、日、小时、分钟和秒的功能,但我需要先把这部分排除在外。

现在我有从公历日期到儒略日期的转换,所以从逻辑上讲,我觉得我应该能够以某种方式简单地反转等式,这将相当简单。但是,我正在执行一个两步过程,首先将公历日期转换为儒略日数,然后转换为儒略日数(差异是天数不包括时间)。所以将它转换回来应该只是意味着我必须从等式中得到小时、分钟和秒,然后将儒略日数单独转换回公历日期。我想这是一个简单的过程,将小时、分钟和秒划分和调制 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

我希望我已经很好地解释了我需要什么!感谢你们提供的任何帮助!

4

3 回答 3

3

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

它恰好有一个儒略历和两个公历变体({year,month,day} 和 {year,month,weekday,index})、基于 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

于 2016-10-11T15:05:25.933 回答
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

于 2016-10-11T05:08:53.310 回答
0

这是一种解决方案,其中完整时间以 hhmmss 格式返回,但您可以单独获取它们。在 //hours: secs/3600 % 24, min: secs/60 % 60, secs secs % 60 处查看函数的结尾

无符号 JulianToTime(double julianDate) { double 余数 = 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; 

}

于 2013-12-11T08:41:34.213 回答