z
is a valid pattern for SimpleDateFormat
(according to javadoc, it's the timezone designator) for any locale.
The only difference is that for some values the result might be locale dependent (example: if you use zzzz
, the timezone America/Los_Angeles
can be formatted as Pacific Daylight Time in English (as it's currently in Daylight Saving Time) or Horário de luz natural do Pacífico in Portuguese), but the pattern z
itself is not invalid regardless of the locale.
And getDateTimeInstance
will use predefined built-in hardcoded patterns. As the short patterns usually don't include the timezone, you'll have to add the z
manually:
DateFormat f = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.ENGLISH);
SimpleDateFormat sf = (SimpleDateFormat) f;
String pattern = sf.toPattern();
// add z to the format, use the same locale
SimpleDateFormat sdf = new SimpleDateFormat(pattern + " z", Locale.ENGLISH);
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.
As 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.
Unfortunately the predefined built-in patterns are still hardcoded and you have to add the timezone manually, but at least you'll get rid of all the problems explained in the links above:
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.FormatStyle;
import java.time.ZonedDateTime;
// get built-in localized format for a specified locale
String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT,
FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.ENGLISH);
// create a formatter, add the timezone manually, use same locale
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern + " z", Locale.ENGLISH);
// format a date
System.out.println(fmt.format(ZonedDateTime.now()));
As you're printing the timezone, I'm using a ZonedDateTime
, which represents a date and a time in a specific timezone. Check the tutorial for more details about the new date types.
DateTimeFormatter
also have more options than SimpleDateFormat
. Check the javadoc for details.
If you still need interoperability with a java.util.Date
, you can easily convert it to the new API:
// convert to Instant (UTC)
ZonedDateTime z = new Date().toInstant()
// convert to some timezone
.atZone(ZoneId.of("Europe/London"));
The API uses IANA timezones names (always in the format Continent/City
, like America/Sao_Paulo
or Europe/Berlin
).
Avoid using the 3-letter abbreviations (like CST
or PST
) because they are ambiguous and not standard.