1

Consider the below code:

if(strTimeZoneCd.equals("A"))
            locTz = TimeZone.getTimeZone("AST");
        else if(strTimeZoneCd.equals("M"))
            locTz = TimeZone.getTimeZone("MST");
        else if(strTimeZoneCd.equals("P"))
            locTz = TimeZone.getTimeZone("PST");
        else if(strTimeZoneCd.equals("H"))
            locTz = TimeZone.getTimeZone("HST");
        else if(strTimeZoneCd.equals("C"))
            locTz = TimeZone.getTimeZone("CST");
        else if(strTimeZoneCd.equals("E"))
            locTz = TimeZone.getTimeZone("EST");
        else if(strTimeZoneCd.equals("G"))
            locTz = TimeZone.getTimeZone("GMT");
        else if(strTimeZoneCd.equals("Y"))
            locTz = TimeZone.getTimeZone("AKST");

Here if I am passing A, it will give me AST. But instead of that I need to determine if I should return AST or ADT.

I need to determine if AST is under daylight saving now. If it is under daylight saving, I can return ADT and if it is not I can return AST. But I am not getting how to determine whether that timezone is under daylight saving or not.

Can someone please help me?

  • Follow this discussion https://stackoverflow.com/questions/10545960/how-to-tackle-daylight-savings-using-timezone-in-java. This might help you. – Simmant Sep 13 '17 at 10:06
  • 2
    This will not answer your question directly and maybe you can't change the odd one letter abbreviations you're mapping from. However, when handling time, it's sometimes better to keep the place for which the time applies (so the daylight saving applies "automatically") not the zone. E.g. instead of playing with "CET" or "CEST", you simply set "Europe/Paris" (if the entity represents Paris) and the daylight saving issue is simply eliminated. – Piohen Sep 13 '17 at 10:46
  • 1
    As has been mentioned, the three and four letter time zone abbreviations are often ambiguous. AST may be easy enough (and maybe your code already gives you what you want). Already MST is a lot worse, because when would you want MDT instead? If you’re in Arizona except Navajo Nation or in Creston BC, the answer is never because these and other places use MST all year. If in Alberta, Colorado or Baja California Sur, you will sometimes want MDT. In short, you’re posing impossible requirements. – Ole V.V. Sep 13 '17 at 13:49
  • 1
    As an aside, I recommend you stop using the outdated `TimeZone` class and its friends. The modern Java date and time API is so much nicer to work with. Its corresponding class is `ZoneId`. – Ole V.V. Sep 13 '17 at 13:59
  • 1
    Maybe, just maybe you want these pseudo-time zones: PST8PDT, EST5EDT, MST7MDT, CST6CDT. For AST I believe you can use America/Anchorage. For HST, I’m not sure at all, but you may consider either Pacific/Honolulu or US/Aleutian, note those two zones are different! – Ole V.V. Sep 13 '17 at 14:08

3 Answers3

2

First of all, avoid using the short abbreviations for timezones names (like CST, PST or CEST) because they are ambiguous and not standard.

CST, for example, is used by more than one timezone: it can be "Central Standard Time", "China Standard Time" or "Cuba Standard Time". And each one has different rules regarding Dayligh Saving Time, so using the abbreviation might not necessarily get the results you expect.

The TimeZone class assumes some defaults for those short names (all arbitrary choices, as any default is) and also has the bizarre behaviour of returning GMT when the name is unknown.

To avoid those ambiguities, it's better to use IANA timezones names (always in the format Region/City, like Asia/Kolkata or America/New_York).

You can get a list of available timezones (and choose the one that fits best your system) by calling TimeZone.getAvailableIDs().

Then you can use the inDaylightTime() method, as already explained in the other answers.

Another alternative is to use a formatter, because it checks automatically if it's in Daylight Saving Time and prints the zone short name. I also use a java.util.Locale to indicate that the names should be in English (I'm not sure if different languages affect the short zone names, it's a "just in case" approach):

// formatter with `z` (zone short name)
SimpleDateFormat sdf = new SimpleDateFormat("z", Locale.ENGLISH);
// set timezone in the formatter
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
// prints the zone name for the current date
System.out.println(sdf.format(new Date()));

The code above prints EDT (because today, September 13th 2017, New York is in Daylight Saving Time and the abbreviation used is EDT).

In this case, you could create the formatter, and use your if logic to set the correct timezone in it. Then, the formatter takes care of checking if the date is in Daylight Saving Time, returning the correct abbreviation.


Java new Date/Time API

The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.

If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.

If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it here).

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.

First I create a DateTimeFormatter with the z pattern (that corresponds to zone short name) and English locale.

Then I use a ZonedDateTime, which represents a date and time in a specific timezone, and the now() method to get the current date/time. I also use ZoneId to especify the timezone I want:

// create formatter for short zone name and English locale
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("z", Locale.ENGLISH);
// format current date in New York timezone
System.out.println(fmt.format(ZonedDateTime.now(ZoneId.of("America/New_York"))));

This also prints EDT as well. You could apply the same if logic above to define which timezone will be used in ZoneId.of(). Just remind to not use the short names (CST, etc), because the new API is not so lenient as the old one.

TimeZone assumes lots of arbitrary defaults and returns "GMT" when the zone doesn't exist, but ZoneId will throw an exception if you try to get an invalid zone (some abbreviations should work for retro-compatibility reasons, but the defaults are arbitrary as well, and you should avoid them).


Custom map of zone names

You can optionally create a custom map of timezone names, so you don't need to make lots of if clauses to determine the corresponding zone. Something like this:

// create custom map of zone names
Map<String, String> customZones = new HashMap<>();
// map "E" to New York
customZones.put("E", "America/New_York");
// map "G" to GMT
customZones.put("G", "GMT");
...

// create timezone using the custom map ("E" will create "America/New_York" zone)
ZoneId zone = ZoneId.of("E", customZones);
// format current date in specified timezone
System.out.println(fmt.format(ZonedDateTime.now(zone)));
Community
  • 1
  • 1
  • 2
    Hey, that custom map of zone names is a *very* good use of the two-arg `ZoneId.of` method. Brilliant thought. – Ole V.V. Sep 13 '17 at 16:13
  • @OleV.V. Thanks a lot! Indeed, I've finally found a good use for it (never used this in production code). –  Sep 13 '17 at 16:22
1

work around this:

For any particular TimeZone

TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());
0

You can use this program to determine whether that timezone is under day light saving or not.

Also see this link.

TimeZone.getTimeZone("CST") returns GMT

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

public class test {

    public static void main(String[] args) {
        System.out.println(TimeZone.getTimeZone("EST").inDaylightTime( new Date() ));
        System.out.println(TimeZone.getTimeZone( "GMT-9:00").inDaylightTime( new Date() ));
    }
}
Abhishek Honey
  • 645
  • 4
  • 13