I have this weird problem, when I create a calendar with a locale, the TimeZone just reverts to the local one
public void start(Locale locale){
String s
Locale
A Locale represents the pair of:
Locale
is not geographical. While a Locale
may use a country or region as a way of representing the cultural norms, that does not literally mean the user is in a particular geographic area. For example, an engineer from Québec at a conference in Tokyo Japan will be using a locale of Locale.CANADA_FRENCH
but her time zone may be Asia/Tokyo
for the duration of her trip.
ZoneId
A time zone, ZoneId, represents a history of the past, present, and future changes to the offset-from-UTC used by the people of a particular region. An offset is merely a number of hours-minutes-seconds ahead or behind the prime meridian used by UTC. Politicians around the world have shown a penchant for frequently redefining their time zones and changing the offset to be used by their jurisdiction(s). Indeed, those regions that adopted the silliness of Daylight Saving Time (DST) change their offset twice a year, about ever six months.
➥ So, no, you cannot get a current time nor a time zone from just a given locale.
when I create a calendar with a locale, the TimeZone just reverts to the local one
You are using terrible date-time classes that are now legacy, supplanted by the modern java.time classes defined by JSR 310.
To get the current moment in UTC (an offset of zero hours-minutes-seconds), use Instant
. An Instant
is always in UTC by definition.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
If you want the current moment in a particular time zone, specify the ZoneId
to get a ZonedDateTime
object.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment as seen in the wall-clock time used by the people of a particular region.
As for knowing the time zone to apply, as I said above you must either:
You can get a list of known time zones by calling ZoneId.getAvailableZoneIds.
Calendar c = new GregorianCalendar( locale ) ;
You may confused by this constructor of GregorianCalendar
taking a Locale
, and understandably so.
This constructor is one of the many poor and incorrect design decisions found in the legacy date-time classes. To be blunt, these legacy classes are quite terrible, designed by people who did not understand the complexities and subtleties of date-time handling. Sun, Oracle, and the JCP community decided to supplant them with java.time for good reason.
Locale
intersects with time zone when it comes to generating text representing the value of a date-time object for display to the user. A Locale
specifies the human language to use in translating name of month, name of day of week, and so on. And Locale
specifies the cultural norms for deciding issues such as abbreviating the month or day-of-week (Is the name capitalized? Is a FULL STOP appended?), ordering day, month, and year, and other such aspects.
The short answer: you can't.
The long answer: There is no such thing as "proper time zone for a locale". That's just because there are a few countries that have more than one time zone (for example United States). Time zone is a different concept.
Anyway, you are looking to solve your problem. I am guessing that you are writing a web application and you see that the time zone is reverting to the server default. That's a typical situation. Both Locale.getDefault()
and TimeZone.getDefault()
will return server-related information. The JVM has no way of knowing the "proper" time zone. So what can you do about it?
DateFormat
instance and it will convert time zone automatically.Out of these three possible choices, I always opt for number 1. By putting time zone information to user profile, you know for sure what his/her preferred time zone is, regardless of their current web browser, etc. Please keep in mind that some users might want to use your application while visiting other countries...