9

I'm making analog clock in Java Swing. To calculate clock pointer angles I need:

  1. UTC time in milliseconds which I can get with System.currentTimeMillis()
  2. TimeZone offset
  3. TimeZone DST savings.

For 2) and 3) I thought of using TimeZone.getDefault().getRawOffset() and TimeZone.getDefault().getDSTSavings().

But getDSTSavings() always returns 3600000 regardless of current date is in winter/summer time.
It looks like it only checks to see if that zone is under DST management and if so it returns 3600000 otherwise 0.
Is this a bug in getDSTSavings()?
If not then only way to get current DST correction in miliseconds is to use Calendar instance like: Calendar.getInstance.get(Calendar.DST_OFFSET)?

Calendar cal1 = Calendar.getInstance(TimeZone.getDefault());        //currentZone: CET/CEST +1/+2, GMT+1:00
System.out.println("System time, " + System.currentTimeMillis()); //UTC current milis
System.out.println("Calendar time, " + cal1.getTime().getTime());   //UTC current milis
System.out.println("Calendar milis, " + cal1.getTimeInMillis());       //UTC current milis
System.out.println("Calendar Zone Offset: " + cal1.get(Calendar.ZONE_OFFSET));
System.out.println("Calendar DST Offset: " + cal1.get(Calendar.DST_OFFSET));
System.out.println("Calendar Zone Offset: " + cal1.getTimeZone().getRawOffset());
System.out.println("Calendar DST Offset: " + cal1.getTimeZone().getDSTSavings());
System.out.println("");

// Winter time, CET
cal1.set(2010, 11, 15, 14, 15, 5);
System.out.println("Calendar milis, " + cal1.getTimeInMillis()); //UTC
System.out.println("Calendar Zone Offset: " + cal1.get(Calendar.ZONE_OFFSET)); // 3600000 correct
System.out.println("Calendar DST Offset: " + cal1.get(Calendar.DST_OFFSET)); // 0 correct
System.out.println("Calendar Zone Offset: " + cal1.getTimeZone().getRawOffset()); // 3600000 correct
System.out.println("Calendar DST Offset: " + cal1.getTimeZone().getDSTSavings()); // 3600000 wrong !!!
System.out.println("");

// Summer time - CEST
cal1.set(2010, 8, 15, 14, 15, 5);
System.out.println("Calendar milis, " + cal1.getTimeInMillis()); //UTC
System.out.println("Calendar Zone Offset: " + cal1.get(Calendar.ZONE_OFFSET)); // 3600000 correct
System.out.println("Calendar DST Offset: " + cal1.get(Calendar.DST_OFFSET)); // 3600000 correct
System.out.println("Calendar Zone Offset: " + cal1.getTimeZone().getRawOffset()); // 3600000 correct
System.out.println("Calendar DST Offset: " + cal1.getTimeZone().getDSTSavings()); // 3600000 correct
Cœur
  • 37,241
  • 25
  • 195
  • 267
zlatanmomic
  • 93
  • 1
  • 1
  • 4

2 Answers2

12

Here is an example of how DST is used:

TimeZone london = TimeZone.getTimeZone("Europe/London");
System.out.println(london.getOffset(date.getTime()));

This will print 3600000 if Daylight Saving Time is in effect in London at the specified date. Otherwise it will print 0.

dogbane
  • 266,786
  • 75
  • 396
  • 414
  • 3
    Yes, that is what I was looking for. Offset is just zone and time dependent. Now I don't need to create new calendar instance on every tick. Instead just detect current zone when starting the clock. final TimeZone timeZone = TimeZone.getDefault(); final long utcTime = System.currentTimeMillis(); final long timeOffset = timeZone.getOffset(utcTime); final long t = utcTime + timeOffset; – zlatanmomic Nov 09 '10 at 08:27
2

The cal1 instance the you retrieve on the first line is in GMT+1 and that does not change regardless of what time / date you set on it. If you need to check the current timezone on every tick of the clock, you will need to retrieve a new Calendar instance at each tick.

As a side-note, if you're willing to add a dependency to your project - Joda Time is a wonderful Date and Time library.

DaGGeRRz
  • 1,611
  • 1
  • 12
  • 13