TimeZone tz = (TimeZone) timezones.get(ID);
TimeZone tz = (TimeZone) timezones().get(ID);
  public static TimeZone getTimeZone(String ID)  {    // First check timezones hash    TimeZone tz = (TimeZone) timezones.get(ID);    if (tz != null)      {	if (tz.getID().equals(ID))	  return tz;	// We always return a timezone with the requested ID.	// This is the same behaviour as with JDK1.2.	tz = (TimeZone) tz.clone();	tz.setID(ID);	// We also save the alias, so that we return the same	// object again if getTimeZone is called with the same	// alias.	timezones.put(ID, tz);	return tz;      }    // See if the ID is really a GMT offset form.    // Note that GMT is in the table so we know it is different.    if (ID.startsWith("GMT"))      {	int pos = 3;	int offset_direction = 1;	if (ID.charAt(pos) == '-')	  {	    offset_direction = -1;	    pos++;	  }	else if (ID.charAt(pos) == '+')	  {	    pos++;	  }	try	  {	    int hour, minute;	    String offset_str = ID.substring(pos);	    int idx = offset_str.indexOf(":");	    if (idx != -1)	      {		hour = Integer.parseInt(offset_str.substring(0, idx));		minute = Integer.parseInt(offset_str.substring(idx + 1));	      }	    else	      {		int offset_length = offset_str.length();		if (offset_length <= 2)		  {		    // Only hour		    hour = Integer.parseInt(offset_str);		    minute = 0;		  }		else		  {		    // hour and minute, not separated by colon		    hour = Integer.parseInt		      (offset_str.substring(0, offset_length - 2));		    minute = Integer.parseInt		      (offset_str.substring(offset_length - 2));		  }	      }	    return new SimpleTimeZone((hour * (60 * 60 * 1000) +				       minute * (60 * 1000))				      * offset_direction, ID);	  }	catch (NumberFormatException e)	  {	  }      }    // Finally, return GMT per spec    return getTimeZone("GMT");  }