VB icon

Long integer Julian Day Number computation

Email
Submitted on: 1/1/2015 12:11:00 PM
By: Bob Stout (republished under Open Content License) (from psc cd)  
Level: Intermediate
User Rating: By 2 Users
Compatibility: C, C++ (general), Microsoft Visual C++, Borland C++, UNIX C++
Views: 1222
 
     These routines convert Gregorian and Julian calendar dates to and from Julian Day Numbers. Julian Day Numbers (JDN) are used by astronomers as a date/time measure independent of calendars and convenient for computing the elapsed time between dates. The JDN for any date/time is the number of days (including fractional days) elapsed since noon, 1 Jan 4713 BC. Julian Day Numbers were originated by Joseph Scaliger in 1582 and named after his father Julius, not after Julius Caesar. They are not related to the Julian calendar. Based on formulae originally posted by Tom Van Flandern / Washington, DC / metares@well.sf.ca.us in the UseNet newsgroup sci.astro. Reposted 14 May 1991 in FidoNet C Echo conference by Paul Schlyter (Stockholm) Minor corrections, added JDN to julian, and recast into C by Raymond Gardner Englewood, Colorado.
 

INCLUDE files:

Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
//**************************************
//INCLUDE files for :Long integer Julian Day Number computation
//**************************************
/* +++Date last modified: 05-Jul-1997 */
/*
** Header for SNIPPETS date & time function, excluding scalar dates
*/
#ifndef DATETIME__H
#define DATETIME__H
#include "sniptype.h"
/*
** Julian day number functions from JDN_L.C
*/
long ymd_to_jdnl(int y, int m, int d, int julian);
void jdnl_to_ymd(long jdn, int *yy, int *mm, int *dd, int julian);
/*
** Add times from ADDTIME.C
*/
int add_time(unsigned basehrs, unsigned basemins, unsigned basesecs,
 int spanhrs, int spanmins, int spansecs,
 unsigned *hrs, unsigned *mins, unsigned *secs, int *days);
/*
** Determine the date of Easter for any given year
*/
void easter(int year, int *easter_month, int *easter_day);
/*
** Moon phase from MOON_AGE.C
*/
int moon_age(int month, int day, int year);
/*
** Date parser from PARSDATE.C
*/
typedef enum {USA, ISO, EUROPE} Syntax_T;
Boolean_T parse_date(const char *str, unsigned *year, unsigned *month,
 unsigned *day, Syntax_T syntax);
/*
** Time parser from PARSTIME.C
*/
Boolean_T parse_time(const char *str, unsigned *hours, unsigned *mins,
 unsigned *secs);
#endif /* DATETIME__H */
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
				
//**************************************
// Name: Long integer Julian Day Number computation
// Description:These routines convert Gregorian and Julian calendar dates to and
from Julian Day Numbers. Julian Day Numbers (JDN) are used by
astronomers as a date/time measure independent of calendars and
convenient for computing the elapsed time between dates. The JDN
for any date/time is the number of days (including fractional
days) elapsed since noon, 1 Jan 4713 BC. Julian Day Numbers were
originated by Joseph Scaliger in 1582 and named after his father
Julius, not after Julius Caesar. They are not related to the
Julian calendar.
Based on formulae originally posted by Tom Van Flandern / Washington, DC / metares@well.sf.ca.us
 in the UseNet newsgroup sci.astro. Reposted 14 May 1991 in FidoNet C Echo conference by Paul Schlyter (Stockholm) Minor corrections, added JDN to julian, and recast into C by Raymond Gardner Englewood, Colorado.
// By: Bob Stout (republished under Open Content License) (from psc cd)
//**************************************

/* +++Date last modified: 05-Jul-1997 */
/* jdn_l.c -- Julian Day Number computation
**
** public domain Julian Day Number functions
**
Based on formulae originally posted by
Tom Van Flandern / Washington, DC / metares@well.sf.ca.us
 in the UseNet newsgroup sci.astro.
Reposted 14 May 1991 in FidoNet C Echo conference by
 Paul Schlyter (Stockholm)
Minor corrections, added JDN to julian, and recast into C by
Raymond Gardner Englewood, Colorado
**
Synopsis:
 long ymd_to_jdnl(int year, int month, int day, int julian_flag)
 void jdnl_to_ymd(long jdnl, int *year, int *month, int *day,
 int julian_flag)
 year is negative if BC
 if julian_flag is > 0, use Julian calendar
 if julian_flag is == 0, use Gregorian calendar
 if julian_flag is < 0, routines decide based on date
**
These routines convert Gregorian and Julian calendar dates to and
from Julian Day Numbers. Julian Day Numbers (JDN) are used by
astronomers as a date/time measure independent of calendars and
convenient for computing the elapsed time between dates. The JDN
for any date/time is the number of days (including fractional
days) elapsed since noon, 1 Jan 4713 BC. Julian Day Numbers were
originated by Joseph Scaliger in 1582 and named after his father
Julius, not after Julius Caesar. They are not related to the
Julian calendar.
**
For dates from 1 Jan 4713 BC thru 12 Dec Feb 32766 AD, ymd_to_jdnl()
will give the JDN for noon on that date. jdnl_to_ymd() will compute
the year, month, and day from the JDN. Years BC are given (and
returned) as negative numbers. Note that there is no year 0 BC;
the day before 1 Jan 1 AD is 31 Dec 1 BC. Note also that 1 BC,
5 BC, etc. are leap years.
**
Pope Gregory XIII decreed that the Julian calendar would end on
4 Oct 1582 AD and that the next day would be 15 Oct 1582 in the
Gregorian Calendar. The only other change is that centesimal
years (years ending in 00) would no longer be leap years
unless divisible by 400. Britain and its possessions and
colonies continued to use the Julian calendar up until 2 Sep
1752, when the next day became 14 Sep 1752 in the Gregorian
Calendar. These routines can be compiled to use either
convention. By default, the British convention will be used.
Simply #define PAPAL to use Pope Gregory's convention.
**
Each routine takes, as its last argument, a flag to indicate
whether to use the Julian or Gregorian calendar convention. If
this flag is negative, the routines decide based on the date
itself, using the changeover date described in the preceding
paragraph. If the flag is zero, Gregorian conventions will be used,
and if the flag is positive, Julian conventions will be used.
**
Proper JDN's are always floating point values so as to include the
time as well as the date. These functions avoid the overhead of
floating point math by computing only the integral value of the JDN.
*/
#include "datetime.h"
#ifdef PAPAL/* Pope Gregory XIII's decree */
#define LASTJULDATE 15821004L/* last day to use Julian calendar */
#define LASTJULJDN 2299160L/* jdn of same */
#else/* British-American usage */
#define LASTJULDATE 17520902L/* last day to use Julian calendar */
#define LASTJULJDN 2361221L/* jdn of same */
#endif
long ymd_to_jdnl(int y, int m, int d, int julian)
{
long jdn;
if (julian < 0) /* set Julian flag if auto set */
julian = (((y * 100L) + m) * 100 + d <= LASTJULDATE);
if (y < 0) /* adjust BC year */
y++;
if (julian)
jdn = 367L * y - 7 * (y + 5001L + (m - 9) / 7) / 4
+ 275 * m / 9 + d + 1729777L;
else
jdn = (long)(d - 32076)
+ 1461L * (y + 4800L + (m - 14) / 12) / 4
+ 367 * (m - 2 - (m - 14) / 12 * 12) / 12
- 3 * ((y + 4900L + (m - 14) / 12) / 100) / 4
+ 1;/* correction by rdg */
return jdn;
}
void jdnl_to_ymd(long jdn, int *yy, int *mm, int *dd, int julian)
{
long x, z, m, d, y;
long daysPer400Years = 146097L;
long fudgedDaysPer4000Years = 1460970L + 31;
if (julian < 0) /* set Julian flag if auto set */
julian = (jdn <= LASTJULJDN);
x = jdn + 68569L;
if ( julian )
{
x += 38;
daysPer400Years = 146100L;
fudgedDaysPer4000Years = 1461000L + 1;
}
z = 4 * x / daysPer400Years;
x = x - (daysPer400Years * z + 3) / 4;
y = 4000 * (x + 1) / fudgedDaysPer4000Years;
x = x - 1461 * y / 4 + 31;
m = 80 * x / 2447;
d = x - 2447 * m / 80;
x = m / 11;
m = m + 2 - 12 * x;
y = 100 * (z - 49) + y + x;
*yy = (int)y;
*mm = (int)m;
*dd = (int)d;
if (*yy <= 0)/* adjust BC years */
(*yy)--;
}
#ifdef TEST
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
 int day, yr, mo;
 char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
 long jdn;
 if (3 > argc)
 {
puts("Usage: JDN d m y");
puts("where: d = day (1 - 31)");
puts("m = month (1 - 12)");
puts("y = year (1 - 99, 1800 - 3000)");
return -1;
 }
 yr = atoi(argv[3]);
 mo = atoi(argv[2]);
 day = atoi(argv[1]);
 if (mo < 1 || 12 < mo)
return -1;
 if (day < 1 || 31 < day)
return -1;
 if (100 > yr)
yr += 1900;
 printf("User specified %d-%s-%d...\n\n", day, months[mo - 1], yr);
 jdn = ymd_to_jdnl(yr, mo, day, 0);
 jdnl_to_ymd(jdn, &yr, &mo, &day, 0);
 printf("jdn_l(%d-%s-%d) = %ld\n", day, months[mo - 1], yr, jdn);
 return 0;
}
#endif /* TEST */


Other 4 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Intermediate category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.