TimeZone.getTimeZone(String) returns the GMT zone when it cannot understand the identifier, and it does not throw an exception for an
unknown identifier. A misspelled value such as America/Los_Angele therefore uses GMT instead of the intended zone.
The String overload of TimeZone.getTimeZone does not reject unknown identifiers. If the argument is not a named ID and
does not match custom GMT syntax, the method returns the GMT zone. The call succeeds, so the application can keep running with GMT instead of the
intended zone.
Use a named identifier that Java recognizes, such as America/Los_Angeles, or a custom GMT offset that matches the documented
syntax.
This rule accepts a named identifier when Java recognizes it, such as America/Los_Angeles. The recognized set can differ slightly
across JDK and time-zone database versions. Legacy three-letter IDs such as PST remain recognized for compatibility and are not
reported.
When no named ID matches, a custom GMT identifier can still be valid. The syntax is GMT followed by a sign and an offset:
GMT+10 and GMT-8:00 are accepted. Hours must be between 0 and 23, and minutes must be between 00 and 59. From Java 19,
seconds between 00 and 59 are also accepted, for example GMT+01:00:30. On earlier Java versions that form is not recognized and falls
back to GMT. When sonar.java.source is not set, this rule accepts identifiers that include seconds.
This rule does not raise an issue when the argument is not a compile-time constant String, including values computed at runtime.
void namedIds(String userZone) {
TimeZone.getTimeZone("America/Los_Angele"); // Noncompliant
}
void namedIds(String userZone) {
TimeZone.getTimeZone("America/Los_Angeles");
TimeZone.getTimeZone("PST"); // legacy three-letter ID
TimeZone.getTimeZone(userZone); // not a compile-time constant
}
void spacedId() {
TimeZone.getTimeZone("America/Los Angeles"); // Noncompliant
}
void spacedId() {
TimeZone.getTimeZone("America/Los_Angeles");
}
void customOffsets() {
TimeZone.getTimeZone("GMT+24"); // Noncompliant
TimeZone.getTimeZone("GMT1"); // Noncompliant
TimeZone.getTimeZone("UTC+0"); // Noncompliant: custom offsets must start with "GMT"
}
void customOffsets() {
TimeZone.getTimeZone("GMT+10");
TimeZone.getTimeZone("GMT-8");
TimeZone.getTimeZone("GMT+00:00");
}
For projects targeting Java 18 and earlier:
void customOffsetWithSeconds() {
TimeZone.getTimeZone("GMT+01:00:30"); // Noncompliant: seconds are not recognized before Java 19
}
void customOffsetWithSeconds() {
TimeZone.getTimeZone("GMT+01:00");
}
For projects targeting Java 19 and later:
void customOffsetWithSeconds() {
TimeZone.getTimeZone("GMT+01:00:60"); // Noncompliant: seconds must be between 00 and 59
}
void customOffsetWithSeconds() {
TimeZone.getTimeZone("GMT+01:00:30");
}
TimeZone (Java
SE 25)TimeZone (Java
SE 19)TimeZone (Java
SE 17).now() methods should specify a ZoneId or a Clock