I have a database with many tables that store date/times in a UTC numeric format (modified Julian Day numbers).
This works well, but of course any time dates need to be displayed to the user, the date/time must be converted from a UTC numeric format to a localized String format. Because the JDK Calendar API provides for historically accurate daylight savings and time zone offsets, I have been using Gregorian Calendar for this sole purpose. I use it only to map timestamps from UTC to local time.
Because I have so many tables that need to perform this conversion and because Calendar objects are expensive to create, I have been creating new GregorianCalendar objects only when the locale time zone changes. I've been keeping the current calendar in a static member field in the JulianDay class (this is the class that provides the functions I use to provide the UTC to local mappings). Here are the fields of JulianDay:
public final class JulianDay {
private static final int YEAR = 0;
private static final int MONTH = 1;
private static final int DAY = 2;
private static final int HOURS = 3;
private static final int MINUTES = 4;
private static final int SECONDS = 5;
private static final int MILLIS = 6;
public static final double POSIX_EPOCH_MJD = 40587.0;
private static final String TIME_ZONE_UTC = "UTC";
private static final GregorianCalendar CAL_UTC =
new GregorianCalendar(TimeZone.getTimeZone(TIME_ZONE_UTC));
private static GregorianCalendar c_selCal = null;
public static void setCurrentCalendar(String tzid)
{ JulianDay.c_selCal = JulianDay.findCalendarForTimeZone(tzid); }
public static GregorianCalendar getCurrentCalendar()
{ return JulianDay.c_selCal; }
:
:
}
The above is in a single-threaded client-side GUI application, but I will soon need to develop a server-side web application that will use much of this API. I'll need to figure out how to preserve my investment in the JDK Calendar API and somehow keep my application thread safe. Joda time is an option, but if possible I'd like to not add that dependency (all I use the Java API for anyway is the easymode access to the time zone database).
Since Calendar is patently thread hostile, I'm not exactly sure how to go from here.
My thought is that since the JulianDay class constructs all the instances of GregorianCalendar (from a time zone id string), I can refactor my code so that I can eliminate the getCurrentCalendar()
method which publishes the reference of the calendar.
If I can confine all the access to GregorianCalendar
to within JulianDay
, may I safely assume that, even though it's a dangerously mutable class, my application is thread safe? I will still need to synchronize access to the GregorianCalendar
with a locking object even in my JulianDay
class, is that right?