我有一个包含许多表的数据库,这些表以 UTC 数字格式(修改后的儒略日数字)存储日期/时间。
这很好用,但是当然任何时间日期都需要显示给用户,日期/时间必须从 UTC 数字格式转换为本地化的字符串格式。因为 JDK 日历 API 提供了历史上准确的夏令时和时区偏移,所以我一直使用公历来实现这个唯一目的。我只使用它来将时间戳从 UTC 映射到本地时间。
因为我有很多表需要执行这种转换,而且 Calendar 对象的创建成本很高,所以我只在语言环境时区更改时才创建新的 GregorianCalendar 对象。我一直将当前日历保存在 JulianDay 类的静态成员字段中(这是提供我用来将 UTC 提供到本地映射的函数的类)。以下是 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; }
:
:
}
以上是在一个单线程的客户端 GUI 应用程序中,但我很快需要开发一个服务器端的 Web 应用程序,它将使用这个 API 的大部分。我需要弄清楚如何保留我对 JDK 日历 API 的投资,并以某种方式保证我的应用程序线程安全。Joda time 是一个选项,但如果可能的话,我不想添加该依赖项(无论如何,我使用 Java API 只是对时区数据库的 easymode 访问)。
由于日历显然是线程敌对的,我不确定如何从这里开始。
我的想法是,由于 JulianDay 类构造了 GregorianCalendar 的所有实例(来自时区 id 字符串),我可以重构我的代码,以便我可以消除getCurrentCalendar()
发布日历引用的方法。
如果我可以限制GregorianCalendar
对 within的所有访问JulianDay
,我是否可以安全地假设,即使它是一个危险的可变类,我的应用程序也是线程安全的?即使在我的课堂上,我仍然需要将访问GregorianCalendar
与锁定对象同步JulianDay
,对吗?