tl;dr
Work in UTC whenever possible.
Instant.now() // Capture current moment in UTC.
Never depend on current default time zone setting of your host OS, your JVM, or your database. Specify desired/expected time zone explicitly.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
Never depend on server’s time zone setting
The real problem is that you have code depending on an aspect over which you have no control and which can be changed at any moment: The JVM’s current default time zone.
You should never write code that depends on the system's default time zone. Instead, always specify your desired/expected time zone explicitly as an optional argument passed to relevant classes.
The problem is, if the system timezone is changed, the java calendar keeps running with the date-time of the "old" timezone.
The host operating system (OS) has its own current default time zone setting and its own time zone definition (tzdata
). Ditto for your database server; if sophisticated in date-time handling such as Postgres, it may have its own tzdata
internally stored. And your JVM too has its own current default time zone setting and its own time zone definition (tzdata
). When the definition changes for time zones of interest, you should update the tzdata
in all three places, either by a software product version update or by a tzdata-specific updater.
All JVM implementations I know of default on launch to setting its own current default time zone to that of the host OS. After JVM launch, changing the host OS time zone setting should have no effect on your JVM, at least not in the Oracle and OpenJDK implementations I have seen.
We are calling java util calendar to get the server date-time.
Never use the troublesome old legacy date-time classes such as Date
& Calendar
. These have been entirely supplanted by the java.time classes.
Could you please tell us why tomcat need restart to reflect new timezone?
I would guess that your web app is inappropriately caching an offset-from-UTC rather than always using a time zone. An offset-from-UTC is just a number of hours-minutes-seconds of displacement from UTC. A time zone is much more, a history of past, present, and future changes to the offset used by the people of a particular region. So always use a time zone rather than a mere offset. See my Answer to a similar Question for much more detail.
Specify a proper time zone name in the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 3-4 letter abbreviation such as EST
or IST
as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
UTC
Generally best to always work in UTC unless a zone is required by your business logic or by your user-interface. You should learn to think, work, log, store, and exchange data in UTC. Forget about your own parochial time zone while at work as a programmer or admin.
The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now() ; // Capture current moment in UTC.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.