Converting Gregorian date to Julian Date and then back again (with time)
Asked Answered
W

3

3

I'm writing a program that has to convert the current gregorian date and time to a Julian Date and then back to Gregorian gate. Eventually I will need to add the functionality of being able to add years, months, days, hours, minutes and seconds, but I need to get this part out of the way first.

Right now I have the conversion from Gregorian Date to Julian Date, so logically I feel like I should simply be able to reverse the equation somehow and that that would be fairly simple. However I'm doing a two step process where I first convert the Gregorian Date to a Julian Day Number, and then to a Julian Date (difference being day number doesn't include time). So converting it back should just mean that I have to get the hours, minutes and seconds back from the equation, and then do the seperate conversion for Julian Day Number back to Gregorian date. I would like to think it's simple process of dividing and moding 3 times for hours, minutes and seconds, and normally I'm pretty good with math and thinking these things through logically, but my brain is simply not functioning on this one.

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

The bottom half there are the calculations I'll need once I've been able to get out my hours, minutes and seconds. All they do Is put the Julian Day Number back to Gregorian Date.

The wiki page explains the whole julian date thing for those who aren't farmiliar: http://en.wikipedia.org/wiki/Julian_day

I hope I've explained what I need well enough! Thanks for any help you guys can offer!

Wicopy answered 12/10, 2012 at 18:1 Comment(2)
The Boost Date_Time library already does all this.Brooch
You might be able to use or adapt the C++ code linked at the bottom of this page. It's by Edward M. Reingold, one of the authors of Calendrical Calculations.Bubaline
E
3

This free, open source C++11/14 date/time library uses the <chrono> foundation to facilitate conversions between any two calendars by setting up conversions from all calendars to and from Unix Time.

It happens to have a Julian calendar as well as two variants of the Gregorian calendar ({year, month, day} and {year, month, weekday, index}), the ISO week-based calendar, and an (imperfect) Islamic calendar. Calendars are relatively easily added, and once added a calendar is interoperable with all other calendars, and <chrono>'s system_clock::time_point at any precision.

Example code:

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

which outputs:

2016-10-11
2016-09-28
2016/Oct/Tue[2]

If you would like more details about the underlying algorithms, they are discussed (and proven) here:

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

Evangelin answered 11/10, 2016 at 15:5 Comment(0)
H
1

You could just use this library. http://www.iausofa.org/current_C.html Or gain some insight by just looking it over and using the concepts. I've used it before and it's pretty straight forward. Lots of pointers though so be prepared. The one I do know about is cal2jd and the other is jd2cal. Those get you the dates. There are more for time and formatting. It has some examples in the docs. And if you are so inclines to want to C++ then there is http://www.naughter.com/aa.html which has functions for astronomical calculations. Good luck! Some other resources... 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

Heeheebiejeebies answered 11/10, 2016 at 5:8 Comment(0)
P
0

This is one solution where the full time is returned as hhmmss format but you get them sperately. See the end of the function at //hours: secs/3600 % 24, min: secs/60 % 60, secs secs % 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; 

}

Passably answered 11/12, 2013 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.