<i18n dev> Java should handle user defined TimeZone subclass instances supporting historic rule changes properly

Yoshito Umaoka y.umaoka at gmail.com
Mon Oct 20 15:22:27 UTC 2014


Thanks for your quick reply. I looked at the JDK-6380023. I think my 
point was slightly different - what I want to do is to create my own 
time zone and use it as default JRE's time zone. But, I agree that the 
things discussed in the bug are necessary to achieve my goal with 

With JSR-310 changes, can we do this through ZoneRulesProvider SPI? 
Assume my goal is to support 'latest' rules from tz database, without 
waiting/updating time zone data update patch from Oracle (or others) - 
and use them in both traditional date/time APIs (Calendar/DateFormat) as 
well as java.time APIs. In this case, can I achieve the goal with -

1) Implement my own ZoneRulesProvider with a new unique zone id - e.g. 
2) TimeZone.setDefault(TimeZone.getTimeZone("Boston-MA"))

With this approach, can I override the default time zone of the JRE, 
with all historic/future rule changes implemented by my custom zone 


On 10/19/2014 8:03 PM, Masayoshi Okutsu wrote:
> Hi Umaoka-san,
> Thanks for your bug report which I've closed as a duplicate of 
> JDK-6380023. Yes, it's an API design flaw of java.util.TimeZone.
> Since we now have the java.time API, I guess JDK-6380023 doesn't have 
> any high priority (unless it gets escalated by someone).
> Regards,
> Masayoshi
> On 10/18/2014 5:43 AM, Yoshito Umaoka wrote:
>> Dear Java i18n team,
>> I was looking at recent Russian time zone changes and noticed a 
>> design issue in JDK. I think I knew this issue, but I forgot about 
>> this until recently. The problem is - Java does not support user 
>> defined custom TimeZone implementation properly.
>> java.util.TimeZone is quite old, and the original design assumed 'raw 
>> offset' and 'daylight saving amount' will never changed. To implement 
>> a subclass of TimeZone, you have to override an awkward abstract 
>> method - abstract int getOffset(int era, int year, int month, int 
>> day, int dayOfWeek, int milliseconds). This method signature itself 
>> does not limit a custom TimeZone implementation to support historic 
>> raw/dst offset changes. However, if you do so, you will see some 
>> problems in other places.
>> I filed a bug below:
>> ====
>> Java should handle user defined TimeZone subclass instances 
>> supporting historic rule changes properly.
>> You can create a custom time zone implementation class by extending 
>> java.util.TimeZone. By the contract, the subclass must implement a 
>> few methods:
>> abstract int getOffset(int,int,int,int,int,int);
>> abstract int getRawOffset();
>> abstract boolean inDaylightTime(Date);
>> abstract void setRawOffset(int);
>> abstract boolean useDaylightTime();
>> Although, the interface above do not assume UTC offset or daylight 
>> saving amount is not changing time to time, a user can provide an 
>> implementation supporting historic UTC offset changes by int 
>> getOffset(int,int,int,int,int,int). However, there are two Java 
>> implementation problems.
>> 1. The default implementation of TimeZone#getOffset(long date) does 
>> not use the abstract method - int getOffset(int,int,int,int,int,int). 
>> Therefore, when a different 'raw' offset was used in the past, or 
>> will be used in future, getOffset(long) always returns a result 
>> calculated from getRawOffset() and getDSTSavings(). Although a 
>> subclass implementation can provide TimeZone#getOffset(long date), 
>> the default implementation should use 
>> getOffset(int,int,int,int,int,int).
>> 2. java.util.GregorianCalendar checks if a TimeZone instance is 
>> sun.util.calendar.TimZone or not, and if not, the offset field is 
>> calculated based on getRawOffset() / getDSTSavings(). Therefore, even 
>> a custom TimeZone implementation support different 'raw' offsets in 
>> the past or future, current 'raw' offset (getRawOffset()) value is used.
>> Use case:
>> A user may want to create a custom TimeZone instance from iCalendar 
>> VTIMEZONE component. iCalendr VTIMEZONE can support historic time 
>> zone rule changes.
>> Suggestions:
>> 1) Add API TimeZone#getRawOffset(long) with the default 
>> implementation - return getRawOffset().
>> 2) Add API TimeZone#getDSTSavings(long) with the default 
>> implementation - return getDSTSavings().
>> 2) Update the default implementation of TimeZone#getOffset(long) to 
>> use #getRawOffset(long) #getDSTSavings(long) above along is existing 
>> #inDaylightTime(Date).
>> 3) Gregorian calendar to use #getRawOffset(long) and 
>> #getDSTSavings(long), if not ZoneInfo.
>> ====
>> There is an IETF working draft for timezone service protocol. In 
>> future, someone may want to create a custom time zone, interacting 
>> with a timezone service server to get the latest time zone rule data, 
>> instead of applying tzdata update utility. In this case, such 
>> limitation becomes a blocker. There are several ways to resolve the 
>> issue - I just suggested one way in the bug report. Are there anyone 
>> willing to look into this?
>> Thanks,
>> Yoshito

More information about the i18n-dev mailing list