A couple of days ago, I fixed a bug by deleting the class. I don’t often get to do that, but this class was buggy, hard to use, and ill-considered in the first place. I won’t post the code, but some sample output is:
Clearly that’s not right, since the top and bottom date should be the
same. So, what was wrong with it? Well...
Fri Aug 27 00:00:00 EDT 1976
Julian Day: 2443017
Milliseconds since midnight: 43200000
Thu Aug 26 20:00:00 EDT 1976
- Julian dates use milliseconds since noon, not milliseconds since midnight.
- The milliseconds since noon should be 57600000, because we’re in EDT, which is 4 hours behind UTC. (The cause of this particular bug.)
- The class was implemented as a subclass of java.util.GregorianCalendar. A Calendar exists soley to link a java.util.Date and a java.util.TimeZone, but Julian dates are all relative to UTC, so should not be represented as a Calendar, much less a Gregorian Calendar.
I managed to replace almost all the occurrances with java.util.Dates, except for a couple of places where I needed to group things by day in EST. Those places I just created a new java.util.GregorianCalendar, and used it to figure out where to split my groups. The algorithm to go from the Julian days and milliseconds since noon to a java.util.Date, and back again is fairly easily derivable from the formula:
Solve for any one of the three lowercase variables, using a little
truncating-division, or a little modulo arithmatic to get rid of
unknown terms, and you’re good to go. So please, if you’re dealing
with dates or times, don’t make this mistake, at least not where I
might run across it.
date = (julianDate - JULIAN_START) * MILLIS_PER_DAY + julianMillis - MILLIS_PER_DAY/2