How do I get the current time in a different TimeZone in Java?
Question
OK - I feel pretty dumb asking such a basic question, but hey.
I'm trying to get the current time in a different timezone in a Java webapp. I've tried the following obvious solution: in my servlet,
Calendar localCalendar = Calendar.getInstance(myBean.getTimeZone());
then I pass the calendar object through to a JSP as a request attribute 'localCalendar':
It is now: [${requestScope.localCalendar.time}]
in TimeZone ${requestScope.localCalendar.timeZone.ID}
but my output seems to ignore the timezone set, i.e.
It is now: [Thu Nov 26 10:01:03 GMT 2009] in TimeZone Indian/Mahe
I'm guessing it's something to do with Locale settings, is there any way to just get the time formatted for my Locale, in another timezone?
Solution
The internal data of Calendar
is basically:
An instant in time can be represented by a millisecond value that is an offset from the Epoch, January 1, 1970 00:00:00.000 GMT (Gregorian).
So, it holds a long
that will be the same no matter what operations you use on it and toString
makes no promises.
You want to format the date as per locale and timezone. You can do this in the presentation layer (the JSP) using things like JSTL or you can format the date in your bean using a DateFormat and return the value as a string.
OTHER TIPS
If you want to display the date in a given format/timezone, use SimpleDateFormat
The answer by McDowell is correct, but the java.util.Calendar
(and java.util.Date
) classes are outmoded.
java.time
The java.time framework is built into Java 8 and later, and back-ported to Java 6 & 7 and to Android. These new classes supplant the old date-time classes as they have proven to be poorly designed, confusing, and troublesome.
An Instant
is the current moment in UTC.
Instant now = Instant.now();
Apply a time zone ZoneId
to get a ZonedDateTime
.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Time Zone vs Locale
Note that time zone and Locale
are orthogonal issues. The time zone affects the wall clock time, the offset from UTC. Locale
affects only the presentation. Locale is used for (a) human language for name of day and month, and (b) cultural norms regarding issues such as month before day-of-month, comma versus period, and so on.
For example, you might have a French-reading Québécois user accessing your page while working in India. So use a time zone of Asia/Kolkata
with a Locale.CANADA_FRENCH
.
To generate a formatted string use the DateTimeFormatter
class. Many example already exist in Stack Overflow. Specify the desired/expected Locale
via withLocale
method.