How to calculate a Julian Date

Hi,

I'm new to the Arduino, but have managed to make good progress despite being a bit thick.

I'm a bit stuck after having hooked up a DS1307 RTC... It's all working fine and I can read and output the date/time to the serial monitor. I now want to get the date (from the RTC) and convert it to a Julian date that I can then use in other calculations in my code. Any help would be most appreciated. Thanks :slight_smile:

Does it need to be the Julian date or would the Unix time do instead, ie the number of seconds that have elapsed since 00:00:00 Thursday, 1 January 1970, ?

Don’t they have Google where you come from?

https://aa.usno.navy.mil/faq/docs/JD_Formula.php

JD =367K - <(7(K+<(M+9)/12>))/4> + <(275M)/9> + I + 1721013.5 + UT/24

  • 0.5sign(100K+M-190002.5) + 0.5

where K is the year (1801 <= K <= 2099), M is the month (1 <= M <= 12), I is the day of the month (1 <= I <= 31), and UT is the universal time in hours ("<=" means “less than or equal to”). The last two terms in the formula add up to zero for all dates after 1900 February 28, so these two terms can be omitted for subsequent dates. This formula makes use of the sign and truncation functions described below:

The sign function serves to extract the algebraic sign from a number.
Examples: sign(247) = 1; sign(-6.28) = -1.

The truncation function < > extracts the integral part of a number.
Examples: <17.835> = 17; <-3.14> = -3.

The formula given above was taken from the 1990 edition of the U.S. Naval Observatory’s Almanac for Computers (discontinued).

// Return -1, 1 or 0 based upon sign of input.
double sign(const double x) { return (x > 0) - (x < 0); }

// Compute julian date.
double jday = 367.*year - rint((7.*(year + rint((month + 9.)/12.)))/4.) + rint((275.*month)/9.);
jday += (day + 1721013.5 - 0.5*sign(100*year + month - 190002.5) + 0.5);

Julian date calculations require special tricks on AVR-based Arduinos, because type “double” is not correctly supported.

The Julian date calculation (for whole days only) in the Solar Position library does work correctly, because it uses long integers to maintain > 8 digits of accuracy.

Abstracted here for convenience:

long JulianDate(int year, int month, int day) {
	long JD_whole;
	int A, B;
	if (month <= 2) {
		year--;
		month += 12;
	}
	A = year / 100;
	B = 2 - A + A / 4;
	JD_whole = (long) (365.25 * (year + 4716)) + (int) (30.6001 * (month + 1))
			+ day + B - 1524;
	return JD_whole;
}

Thanks jremington much appreciated, especially for the link to the Solar Position library :slight_smile: