Geeks With Blogs

Astronomers frequently need to do arithmetic with dates, and rather than attempting to count the days in each month, it's far easier to simply convert the dates to Julian day numbers and just add or subtract. A while back I wrote a post on how to do this, but this method is slightly different - the subroutine in the book returns the number of days since 1900 January 0.5 (rather than the actual Julian date) due to the low-precision versions of BASIC in use at the time of writing. You can still get the actual Julian date by simply adding 2415020 to the result.

The method of calculating the J days is:

DJ = B + C + D + DY - 0.5 days

If year is negative:
year = year + 1
If month = 1 or 2:
year = year - 1
m1 = month + 12
If month is 3 or more:
m1 = month
If date is before 10/15/1582:
B = 0
If date is equal to, or after 10/15/1582:
A = INT(Year/100)
B = 2 - A + INT(A/4)
If year is negative:
C = INT((365.25 * year) - 0.75) - 694025
If year is positive:
C = INT(365.25 * year) - 694025
All dates:
D = INT(30.6001 * (m1 + 1))

Here's the method for doing the conversion:

```public static double Convert(int year, int month, double day)         {             if (year == 0)                 throw new ApplicationException();```

`            int monthOrig = month;`

```            if (year < 1)             {                 year = year + 1;             }```

```            if (month < 3)             {                 year = year - 1;                 month = month + 12;             }```

```            int A = ((year > 1582) || (year == 1582 && (monthOrig > 10 || day >= 15))) ? year / 100 : 0;             int B = ((year > 1582) || (year == 1582 && (monthOrig > 10 || day >= 15))) ? (2 - A + (A / 4)) : 0;             int C = (year < 0) ? (int)((365.25 * year) - 0.75) - 694025 : (int)(365.25 * year) - 694025;             int D = (int)(30.6001 * (month + 1));```

```            if (year == 1582 && A == 0)                 throw new ApplicationException();```

`            double JD = B + C + D + day - 0.5;`

```            return JD;         }```

And here's a test app:

`double d;`

```d = JulDay.Convert(1989, 2, 2); Console.WriteLine("Converting 2/2/1989 to J days since 1900 Jan 0.5: " + d.ToString()); Console.WriteLine("Julian date: " + (d + 2415020).ToString()); Console.WriteLine("");```

```d = JulDay.Convert(1900, 1, .5); Console.WriteLine("Converting 1/.5/1900 to J days since 1900 Jan 0.5: " + d.ToString()); Console.WriteLine("Julian date: " + (d + 2415020).ToString()); Console.WriteLine("");```

```d = JulDay.Convert(-4713, 1, 1.5); Console.WriteLine("Converting 1/1.5/-4713 to J days since 1900 Jan 0.5: " + d.ToString()); Console.WriteLine("Julian date: " + (d + 2415020).ToString()); Console.WriteLine("");```

`Console.ReadLine();`

If everything works properly, you should get 32539.5 for 2/2/1989, 0 for 1/.5/1900 (don't forget days can be expressed in decimals in Julian), and -2415020 for 1/1.5/-4713 (a BC date).

Technorati Tags: