1

I have a collection of Java Date objects, loaded from an old database which did not store timezone info.

I know that all the dates (which include hours, minutes and seconds) are for the U.S. Eastern time zone.

I want to derive the correct timezone abbreviation ("EST" or "EDT") for each date.

Here is my attempt (using Java 11). It is unwieldy, to say the least.

I looked into the following classes:

java.util.TimeZone
java.time.ZoneId
java.time.zone.ZoneRules

Here is my method - it uses two statements purely to give me a fighting chance of still understanding what I wrote, a week from now.

EDIT - based on @VGR's comment below, I have updated the example. Now it expects a timezone display name - for example "America/New_York":

public String getTimezoneAbbrev(Date date, String tzName) {
    TimeZone tz = TimeZone.getTimeZone(tzName);
    boolean isDaylightSavings = tz.toZoneId().getRules().isDaylightSavings(date.toInstant());
    return tz.getDisplayName(isDaylightSavings, TimeZone.SHORT);
}

It works (I have test cases), but is there a less verbose way?

(I did not find any code examples which use Date as their starting point).

andrewJames
  • 19,570
  • 8
  • 19
  • 51
  • 2
    The first line could be `boolean isDaylightSavings = TimeZone.getDefault().inDaylightTime(date);` – Dawood ibn Kareem Feb 16 '20 at 23:21
  • 1
    I’m confused by your use of `TimeZone.getTimeZone("America/New_York")` on one line and `TimeZone.getDefault()` on the next. I would have thought you’d want to use the same timezone everywhere. Maybe even store it in a static final field? – VGR Feb 17 '20 at 03:26
  • @VGR - Yes that is confusing (i.e. bad and wrong). I have fixed my example - thank you for pointing that out. – andrewJames Feb 17 '20 at 13:34

2 Answers2

0

Something like the following?

import java.util.Date;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) {
        System.out.println(TimeZone.getDefault().getDisplayName(TimeZone.getDefault().inDaylightTime(new Date()),TimeZone.SHORT));
    }
}
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Arvind (and @Dawood also): Ironically, I was using `ZoneRules.isDaylightSavings()` out of a wish to use the modern `java.time.zone` package. But `TimeZone.inDaylightTime()` is what I need, thanks. I completely missed it. Available since Java 1.1. – andrewJames Feb 17 '20 at 13:42
0

I have accepted Arvind's answer because he pointed out TimeZone.inDaylightTime() - but for the record, here is the updated version of the method in my question.

It is more concise now:

// tzName is a timezone display name, such as "America/New_York"

public static String getTimezoneAbbrev(Date date, String tzName) {
    TimeZone tz = TimeZone.getTimeZone(tzName);
    return tz.getDisplayName(tz.inDaylightTime(date), TimeZone.SHORT);        
}

Warning

I also found answers in this question helpful - because if you type a non-existent timezone display name (or ID) when using TimeZone.getTimeZone(), Java will return "the specified TimeZone, or the GMT zone if the given ID cannot be understood" (emphasis mine). See here.

Typing...

America/New-York

...instead of...

America/New_York

...is enough to cause problems.

Therefore...

We should use java.time.ZoneId instead. This will throw an error for an invalid/unknown ID.

andrewJames
  • 19,570
  • 8
  • 19
  • 51