0

I am using java.util.TimeZone to get a time-zone in a json request, but when an invalid time-zone is provided, it is automatically converted to GMT, as shown in the code below. So, how can I avoid that automatic conversion so that I know that the provided time-zone is not valid?

import java.util.*;

public class MyClass {
    
    public static void main(String args[]) {

        TimeZone tz = TimeZone.getTimeZone("invalid time zone");
        
        System.out.println( tz.getID() ); //this prints GMT instead of "invalid time zone"
      
    }
}
Techy
  • 11
  • 3
  • 4
    Does this answer your question? [TimeZone validation in Java](https://stackoverflow.com/questions/13092865/timezone-validation-in-java) – rémy Oct 19 '21 at 21:47
  • @rémy No, that does not answer. – Techy Oct 19 '21 at 21:48
  • 2
    It... literally does? If you're stuck with `java.util.TimeZone` then the accepted answer to that question shows you exactly how to check whether a timezone is known or not. And if you're not stuck with `java.util`, start using [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html#package.description) as soon as possible =) – Mike 'Pomax' Kamermans Oct 19 '21 at 21:52
  • See the [correct Answer by yali](https://stackoverflow.com/a/57912411/642706) on the original of this duplicate Question. – Basil Bourque Oct 20 '21 at 05:41

2 Answers2

3

Java has 3 completely separate APIs for 'date stuff'.

  • There's java.util.Date (as well as TimeZone, which is what you use here, and a bunch of things that hang off of this, such as java.sql.Timestamp which inherits it).

  • There's java.util.Calendar (and GregorianCalendar and a few others).

  • There's everything in the java.time package.

Why are there 3 APIs? Because the Date one is so incredibly boneheaded, it needed to be replaced. Unfortunately, the replacement was even worse, so that too needed to be replaced. Fortunately, the third time really was the charm, and java.time is fantastic.

SOLUTION: Don't use the old obsolete bad APIs. If it starts with java.util, you don't want it.

You want java.time.ZoneId which represents an actual zone. This is something like Europe/Amsterdam, not something useless, like CEST or even the most useless, +01:00. Those latter two are fragile as all get out and do not allow any actual math. For example, an offset-based zone doesn't let you 'add an hour' - depending on where on the planet an appointment was made, 'add an hour' can mean different things (Daylight Savings Time is a thing!). CEST is too broad; the places on the planet that 'use CEST' changes all the time. Case in point: The EU passed a motion that all EU countries should move away from DST. But not all of the EU may choose the same zone to 'stick to', so that's an upcoming change of definition right there already.

If nevertheless you have one of these mostly useless zones, java.time.ZoneOffset can represent this.

They will error if you provide gobbledygook.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • I think it’s unfair to call it boneheaded. java.util.Date was in Java 1.0, which came out in the mid-1990s. The leading language for development was C, and C’s date-time type was `time_t`. java.util.Date was an analog for `time_t`, because it was important that Java not be so alien to C and C++ developers that they wouldn’t want to invest any effort in learning Java. And as far as I know, there was no better date-time API at the time than the APIs that used `time_t`. – VGR Oct 20 '21 at 00:43
  • 1
    @VGR at the time `j.u.Date` was written, we can argue if, given the context of the time, the boneheadedness is excusable. Probably; I bet if I was in charge way back then I wouldn't have done a better job. But with hindsight? It's horrible API. Starts with the name: `j.u.Date` _does not_ represent a date at all. It represents an instant. If the mission was "Be like C", making the name _worse_ is still inexcusable (`time_t` is closer to the truth, at least. Also, what you say is just flat out wrong, most of the C world was doing seconds-in-an-int, see 'the 2038 problem'). – rzwitserloot Oct 20 '21 at 00:57
0

You can use java.time.ZoneId.of, which will throw an Exception for an invalid zone.

import java.time.ZoneId;
import java.time.DateTimeException;
// ...
try {
    ZoneId zone = ZoneId.of("invalid time zone");
    System.out.println(zone);
} catch(DateTimeException e){
    System.out.println("Invalid time zone");
}
Unmitigated
  • 76,500
  • 11
  • 62
  • 80