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