I am writing a program which converts a Gregorian calender date to a Julian day number. I am having some problems implementing the portion which includes time. For reference - http://en.wikipedia.org/wiki/Julian_day (scroll to calculation section)

My code:

jdn_t gregorian_to_jdn_with_time( year_t year, month_t month, day_t day, hour_t hour, min_t min, sec_t sec ) {
    assert( month <= 12 && "Max month is December(12)" );
    assert( month >= 1 && "Min month is January(1)" );
    assert( day >= 1 && "Min day is 1" );
    assert( day <= 31 && "Max day is 31" );
    // TODO: Implement the conversion from Gregorian to Jdn
    // http://en.wikipedia.org/wiki/Julian_day
    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;
    jdn_t jdnTime = jdn +  (hour - 12) /  24 + min / 1440 + sec / 86400  ;

    return jdnTime;
}

Typedefs:

    typedef double jdn_t;
    typedef long long year_t;
    typedef int month_t;
    typedef int day_t;
    typedef int hour_t;
    typedef int min_t;
    typedef int sec_t;

The jdnTime turns out to be some huge negative number when I try to test it with January 1, 2000 at 12:00:00 which should equate to julian day # 2451545.0. I have no idea what I'm doing wrong, any suggestions?

Member Avatar for iamthwee

Have you tried using more parentheses.

I have. I always get the same output - jdnTime -9.2559631349317831e+061 double

Member Avatar for iamthwee

Only other thing I can suggest if your classes is implemented correctly is using a bigNum library to rule out floating point rounding errors etc.

long long y = year + 4800 + a;

should be this

long long y = year + 4800 - a;

First, don't use a double. It's inaccurate. A long is good for 4 billion values. A long long (assuming it works) is astronomically larger.

Second, take that hellacious equation and break it up into manageable segments.
Calculate the year. Then the month. Then the day. Then put them together. This way you can output intermediate values to see if they are correct.

I noticed I accidently put the break point in the wrong place and that's why it was returning that odd value. All is well now, thanks for the help.

I am also trying to come up with a jdn_to_time_of_day function which takes in a Julian Day (JD) and returns the hour, min, and sec of that number. I figured I could reverse engineer the code which comes up with the JD including time which is:

jdn_t jdnTime = jdn + ( (hour - 12) / 24 ) + ( min / 1440 ) + ( sec / 86400 );

So far I've figured:

jdn = jdn + 0.5;
double intpart, frac;

frac = modf( jdn, &intpart ); //returns the fraction of the jdn (time part)

The next step would be to use floor function to calculate the hour, min, sec from that fraction; which is what I'm having trouble with.

From wikipedia about the time calculation:

The time of the day is then computed from the fractional day T = frac(JD + 0.5). The additive 0.5 constant can also be adjusted to take the local timezone into account, when computing an astronomical Gregorian date localized in another timezone than UTC. To convert the fractional day into actual hours, minutes, seconds, the astronomical Gregorian calendar uses a constant length of 24 hours per day (i.e. 86400 seconds exactly), ignoring leap seconds inserted or deleted at end of some specific days in the UTC Gregorian calendar.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.