how to set timezone for jvm through command line - java

My local machine's timezone is HST. But JVM giving me CUT/UTC timezone. I tried using java -Duser.timezone=America/Adak Example, but it sets HST only for Example.class . How/where can I See/Change the JVM's timezone?
The ZONE value in /etc/sysconfig/clock is pointing to HST timezone only.
class Example {
public static void main(String[] args) {
System.out.println(java.util.TimeZone.getDefault());
}
}
The Above code is giving me UTC timezone.
I am using CentOS vagrant box and java 8.
I can Set the Timezone by using java -Duser.timezone=America/Adak
by using above statement we are externally setting the timezone. But we are not taking the Default/machine's timezone.
I am asking how can we get/see/change the system's timezone using java.

You can see your JVM's timezone by
System.out.println(TimeZone.getDefault());
You can set it in the JVM call for example by
java -Duser.timezone=HST ...
or programmatically by something like
TimeZone.setDefault(TimeZone.getTimeZone("HST"));

See your JVM’s current default time zone by calling ZoneId.systemDefault().
You do not explain what is the default time zone of your host OS (which you have not described) versus that of your Vagrant box. I'm not knowledgeable with running Java containerized but I imagine your Java implementation (which you have not yet described) is picking up its default from either the host OS or the container.
Always specify your desired/expected zone
But here is the thing: You should not care. Your Java programming should never rely implicitly on the JVM’s current default time zone. Your Question itself is evidence for my point.
Instead, always specify a time zone explicitly in your code.
Never rely on default zone
Another reason you should never depend on the default is that it can be changed at any moment during runtime(!) by any code in any thread of any app running within the JVM.
Instead pass your desired/expected time zone as an optional argument.
For example, to get the current moment in a zone:
ZoneId z = ZoneId.of( "America/Adak" );
ZonedDateTime zdt = ZonedDateTime( z );
Look throughout the java.time classes and you'll see that wherever a time zone or offset is relevant you can pass a ZoneId or ZoneOffset object as an optional argument. Personally I believe Java programmers would be better off if those arguments were required rather than optional as so many of us fail to think about the issue of time zone and offset.

Related

How to ensure that java system property `user.timezone` is explicitly specified?

I want to be sure that my Java program is always run by explicitly specified user.timezone property. I pass -Duser.timezone=XXX as a command-line setting.
However, when I omit that system property at all, and then in my program I check the value of System.getProperty("user.timezone"), it is not null, instead, it contains the system timezone. So, I can't terminate my program, as the value of that property is never null.
I know that I can use a custom system property name(say tz) to accept the timezone ID and then execute TimeZone.setDefault(System.getProperty("tz")) in my code, but I prefer to use the system property user.timezone, which is intended to be used for that reason.
Is there any way to achieve what I need using user.timezone system property ?
Specify time zone explicitly as argument to method calls
Relying on the JVM’s current default time zone is inherently unreliable. Any code in any thread of any app within the JVM can, at any moment, change the default with a call to TimeZone.setDefault. Such a call immediately affects all other code relying on that default.
Instead, always specify explicitly the time zone you desire/expect.
Also, TimeZone is obsolete, supplanted years ago by the modern java.time classes defined in JSR 310. Specifically, ZoneId and ZoneOffset. You can pass an object of those classes as an optional argument to all the relevant methods.
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
UTC is the one true time
On a server, generally the best practice is to set the default time zone of both the host OS and JVM to UTC (an offset-from-UTC of zero).
And most of your business logic, logging, and debugging should all be in UTC as well.
A time zone should only be needed:
When localizing display to the user.
Where required by a particular business rule.
By the way, that property user.timezone is not listed as one of the standard default properties in Java 11.
I very much agree with the answer by Basil Bourque: Your solution is to write your code so it is independent of a JVM default time zone. Also as mentioned in the comments, when using java.time types with your SQL database through JDBC 4.2 (or later), no default time zone interferes.
Furthermore from what I have read drivers tend to use the database session time zone, not the JVM default time zone. You may want to search your database documentation and your JDBC driver documentation for ways to control the session time zone.
However to answer your question as asked:
String userTimezoneProp = System.getProperty("user.timezone");
boolean timezonePropertyEmpty = userTimezoneProp == null || userTimezoneProp.isEmpty();
if (timezonePropertyEmpty) {
System.err.println("You must set the user.timezone property to the same time zone as the database time zone.");
System.exit(-1);
}
Only you must do this before doing any operations that use the default time zone. Once such an operation is performed, the JVM will query the operating system for a default time zone and set the system property accordingly (if successful).
According to the documentation System.getProperty() should return null for a system property that has not been set. My Java returned an empty string in this example. So I take both possibilities into account. It may be something special for user.timezone. I didn’t find any documentation mentioning it. I still do not guarantee that the method is bullet-proof.

Strange behavior of OffsetDateTime.now() in Android

If I do in a generally Java program:
OffsetDateTime offsetDateTime = OffsetDateTime.now();
then I have an output of 2020-04-01T20:22:04.604+02:00.
If I do the same on Android then I have the output 2020-04-01T18:22:04.604Z.
Also with formatting to local_time:
String format = DateTimeFormatter.ISO_LOCAL_TIME.format(now);
the output is 18:22:04.604
But I want from now() my local DateTime 20.22 and not the UTC time.
The systems timezone in Android is European Summertime +02:00.
What is going on here?
The safest way is to pass the time zone that you want to the now method:
OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneId.of("Europe/Vienna"));
System.out.println(offsetDateTime);
Output when I ran just now:
2020-04-04T09:02:05.059927+02:00
Giving time zone explicitly frees us from relying on the default time zone of the JVM.
If I understand your question correctly, the JVM time zone setting didn’t reflect the time zone setting of your device. It’s possible for the two to be different, but how that came to be in your case, I cannot tell. Possible explanations include:
Your JVM was launched with a setting of the user.timeaone equal to UTC.
Some place in your program or another program running in the same JVM the time zone is set to UTC, either by setting the above mentioned system property or by calling TimeZone.setDefault().

Why Clock.systemDefaultZone().instant() returns different time than LocalTime.now()?

Why does Clock.systemDefaultZone().instant() return a different time than LocalTime.now()?
I understand that LocalTime has no timezone, but it shows just what my system clock (in tray on my computer) shows, right? Both "use" default time zone (Europe/Moscow), so time shall be the same?
My computer clock is Europe/Moscow, so both shall show exactly my computer time?
System.out.println(Clock.systemDefaultZone().instant()); // 2018-03-19T10:10:27.156Z
System.out.println(Clock.systemDefaultZone().getZone()); // Europe/Moscow
System.out.println(LocalTime.now()); // 13:10:27.166
If I found out correctly, the Instant returned by .instant() does not take care of any timezone information. With the correct timezone (ZoneId returned by Clock.systemDefaultZone().getZone()) you can get a ZonedDateTime from the Instant though (which does provide timezone information).
Example
System.out.println(Clock.systemDefaultZone().instant());
System.out.println(Clock.systemDefaultZone().instant().atZone(Clock.systemDefaultZone().getZone()));
Output
2018-03-19T10:30:47.032Z
2018-03-19T13:30:47.048+03:00[Europe/Moscow]
java.​time
public abstract class Clock extends Object
A clock providing access to the current instant, date and time using a time-zone.
Instances of this class are used to find the current instant, which can be interpreted using the stored time-zone to find the current date and time. As such, a clock can be used instead of System.currentTimeMillis() and TimeZone.getDefault().
Use of a Clock is optional. All key date-time classes also have a now() factory method that uses the system clock in the default time zone. The primary purpose of this abstraction is to allow alternate clocks to be plugged in as and when required. Applications use an object to obtain the current time rather than a static method. This can simplify testing.
Best practice for applications is to pass a Clock into any method that requires the current instant. A dependency injection framework is one way to achieve this:
public class MyBean {
private Clock clock; // dependency inject
...
public void process(LocalDate eventDate) {
if (eventDate.isBefore(LocalDate.now(clock)) {
...
}
}
}
This approach allows an alternate clock, such as fixed or offset to be used during testing.
The system factory methods provide clocks based on the best available system clock This may use System.currentTimeMillis(), or a higher resolution clock if one is available.
Implementation Requirements:
This abstract class must be implemented with care to ensure other classes operate correctly. All implementations that can be instantiated must be final, immutable and thread-safe.
The principal methods are defined to allow the throwing of an exception. In normal use, no exceptions will be thrown, however one possible implementation would be to obtain the time from a central time server across the network. Obviously, in this case the lookup could fail, and so the method is permitted to throw an exception.
The returned instants from Clock work on a time-scale that ignores leap seconds, as described in Instant. If the implementation wraps a source that provides leap second information, then a mechanism should be used to "smooth" the leap second. The Java Time-Scale mandates the use of UTC-SLS, however clock implementations may choose how accurate they are with the time-scale so long as they document how they work. Implementations are therefore not required to actually perform the UTC-SLS slew or to otherwise be aware of leap seconds.
Implementations should implement Serializable wherever possible and must document whether or not they do support serialization.
Implementation Note:
The clock implementation provided here is based on System.currentTimeMillis(). That method provides little to no guarantee about the accuracy of the clock. Applications requiring a more accurate clock must implement this abstract class themselves using a different external clock, such as an NTP server.
Since:
1.8
java.​time.​Clock
public static Clock systemDefaultZone()
Obtains a clock that returns the current instant using the best available system clock, converting to date and time using the default time-zone.
This clock is based on the best available system clock. This may use System.currentTimeMillis(), or a higher resolution clock if one is available.
Using this method hard codes a dependency to the default time-zone into your application. It is recommended to avoid this and use a specific time-zone whenever possible. The UTC clock should be used when you need the current instant without the date or time.
The returned implementation is immutable, thread-safe and Serializable. It is equivalent to system(ZoneId.systemDefault()).
Returns:
a clock that uses the best available system clock in the default zone, not null
See Also:
ZoneId.systemDefault()
java.​time.​Clock
public abstract Instant instant()
Gets the current instant of the clock.
This returns an instant representing the current instant as defined by the clock.
Returns:
the current instant from this clock, not null
Throws:
DateTimeException - if the instant cannot be obtained, not thrown by most implementations
To understand those results, we must first see how the Clock is intended to work. Taking a look at the javadoc, we can see the following description for the methods:
public abstract Instant instant()
Gets the current instant of the clock.
This returns an instant representing the current instant as defined by the clock.
public abstract ZoneId getZone()
Gets the time-zone being used to create dates and times.
A clock will typically obtain the current instant and then convert that to a date or time using a time-zone. This method returns the time-zone used.
So the instant() method will get the current instant as a java.time.Instant, which is a class that always works in UTC. And the key point here is: "as defined by the clock".
The Clock class allows you to create lots of different clock definitions - such as a fixed clock that always returns the same thing - and the most common is the one returned by systemDefaultZone(), which uses the system's current date/time.
As the instant() method returns a java.time.Instant and this class works only in UTC, the result will always be UTC.
The getZone() method will return the timezone used to create dates and times, and this is done by combining the Instant (returned by instant()) with the ZoneId returned by getZone().
You can create a clock with any timezone you want, but systemDefaultZone() just uses the JVM default timezone, which is - in your case - Europe/Moscow.
When you call LocalTime.now(), it internally uses the clock returned by systemDefaultZone().
Then, it uses the results from instant() and getZone(), and combine both to get the LocalTime.
Usage
According to javadoc:
Use of a Clock is optional. All key date-time classes also have a now() factory method that uses the system clock in the default time zone. The primary purpose of this abstraction is to allow alternate clocks to be plugged in as and when required. Applications use an object to obtain the current time rather than a static method. This can simplify testing.
So I wouldn't use the clock directly. Instead, I'd use the now methods from each class, depending on what I need.
If I want the current moment in UTC: Instant.now()
only the current date: LocalDate.now()
and so on...
The now() method without parameters can be very handy and convenient, but it has some drawbacks. It always uses the JVM default timezone behind the scenes. The problem, though, is that the default timezone can be changed at anytime, either by JVM/system's config or even by any application running in the same VM, and you have no control over it.
To not depend on the default configurations, you can use the alternatives now(ZoneId) (which uses an explicity timezone), or now(Clock), which makes your code more testable - see examples here.
While some of the other Answers have correct information, here is a simple summary.
UTC
Instant is in UTC, always, by definition.
Instant instant = Instant.now() // Captures the current moment in UTC. Your default time zone settings are irrelevant.
Implicit default time zone
Calling LocalTime.now() implicitly applies your JVM’s current default time zone.
When you type this code:
LocalTime.now()
… the JVM at runtime does this:
LocalTime.now( ZoneId.systemDefault() )
Not obvious which is why I recommend always passing the desired/expected time zone explicitly as the optional argument.
ZoneId z = ZoneId.systemDefault() ; // Make explicit the fact that you are intentionally relying on the user’s JVM’s current default time zone.
LocalTime lt = LocalTime.now( z ) ; // Capture the current moment in the Wall-clock time used by people of a particular region (a time zone).
Beware: The user’s JVM’s current default time zone can be changed at any moment during runtime. So if the zone is critical, confirm with the user as to their intended time zone, and pass as optional argument.
ZoneId z = ZoneId.of( “Africa/Tunis” ) ; // Or “Europe/Moscow”, whatever.
LocalTime lt = LocalTime.now( z ) ;

google appengine - Time zone changed

In ServletContextListener initialization method we are setting Time Zone as
public void contextInitialized(ServletContextEvent event) {
TimeZone.setDefault(TimeZone.getTimeZone("GMT+00:00"));
}
But when i check the Time Zone information in servlets and filters the Time Zone got changed.
Any one know what might be the reason.
Thanks
See, I've following class
public class TimeZ {
public static void main(String args[]){
System.out.println("1."+TimeZone.getTimeZone("GMT+00:00"));
System.out.println("2. "+TimeZone.getDefault());
TimeZone.setDefault(TimeZone.getTimeZone("GMT+00:00"));
System.out.println("3. "+TimeZone.getDefault());
System.out.println("4. "+TimeZone.getTimeZone("GMT+00:00"));
}
}
my output is:
1.sun.util.calendar.ZoneInfo[id="GMT+00:00",offset=0,dstSaving...
2. sun.util.calendar.ZoneInfo[id="Asia/Calcutta",offset=19800000,...
3. sun.util.calendar.ZoneInfo[id="GMT+00:00",offset=0,dstSaving...
4. sun.util.calendar.ZoneInfo[id="GMT+00:00",offset=0,dstSaving...
explanation: by default my timezone is india. It's going to return the
timezone of the JVM TimeZone.getDefault() is executed on. So if the
application is running on a server in India, it will be something like
"Asia/Calcutta" .when you set default timezone to GMT, it changes its timezone to
GMT zone. thats simple...
I cannot address your Question specifically as you do not show us the code for how you get time zone. But I can give you some tips.
Your code should be working. The problem is likely to be in (a) how you are getting the time zone or (b) the default zone being set somewhere else.
Add a line of code before and after where you set the zone to get the zone so as to log the change taking effect. See this done in the Answer by Sheeran.
Use the modern java.time classes rather than the troublesome old legacy date-time classes.
The default time zone applies to the entire JVM. Any code in any thread of any app within the JVM can change the default at any moment at runtime. Such a change affects all code in all threads of all apps within the JVM. So relying on the JVM’s current default time zone is risky and ill-advised in general but especially so on a server and even more so on a Servlet container.
Furthermore, the best practice on servers is to keep the default time zone in UTC. Though, again, you should not rely on that default.
There is almost never a need to set the default. Instead, pass explicitly the desired/expected time zone as a ZoneId (or ZoneOffset) as the optional argument to the various methods in java.time. Frankly I wish all those zone arguments were required rather than optional as most programmers fail to think about the crucial issue of zones and offsets.
Instant instant = Instant.now() ; // Current moment in UTC.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Much of your work should be done in UTC rather than with zoned values. Programmers should generally be thinking, working, logging, exchanging data, and serializing data all in UTC. As a programmer, you should stop thinking parochially about your own personal time zone while on the job, as constant conversions in/out of that zone will muddy your thoughts, lead to errors, and drive you crazy. Generally you should assign zones only where expected by your user in presentation in the user-interface.

Handling TimeZone change with Date class in JAVA

I am trying to print the current system date and time as below,
public class PrintDate {
public void getDate(){
while(true){
System.out.println(new Date());
}
}
public static void main(String[] args) {
new PrintDate().getDate();
}
}
This endless loop prints the current system time stamp as expected and it works fine when i make change in date or time in the OS but not with the timezone change..
Example :
I started the above code , which continuously print the current system time stamp as expected.
When i change the system date or time , it successfully gets reflected in the code.
When i change the system timezone , It is not reflecting in the code. It still show the same timezone since the program started.
May i know the reason behind this?
The time zone is part of the environment of the process. Changing the time zone globally for your system only affects new processes.
See also How to set time zone of a java.util.Date?:
Be aware that java.util.Date objects do not contain any timezone
information by themselves - you cannot set the timezone on a Date
object. The only thing that a Date object contains is a number of
milliseconds since the "epoch" - 1 January 1970, 00:00:00 UTC.
As ZZ Coder shows, you set the timezone on the DateFormat object, to
tell it in which timezone you want to display the date and time.
The answer by neuhaus is correct.
If you meant you changed the time zone of your host operating system while running that code, know that the Java Virtual Machine (JVM) has its own current default time zone.
Usually that default is picked up from that of the host OS. If so in your case, that must mean your Java implementation is detecting the host time zone only at launch and not checking for later changes in the host OS‘ time zone.
The time zone of your JVM can also be set as a configuration parameter upon launch. In that case I should think the JVM would purposely ignore the host OS’ time zone changes.
Any Java code in any thread of any app within that JVM can change the JVM’s current default time zone at any moment during runtime. Again, I should think the JVM would purposely ignore the host OS’ time zone changes.
The class doc for java.util.TimeZone.getDefault() outlines steps taking in determining the current default time zone.
If the cached default TimeZone is available, its clone is returned. Otherwise, the method takes the following steps to determine the default time zone.
• Use the user.timezone property value as the default time zone ID if it's available.
• Detect the platform time zone ID. The source of the platform time zone and ID mapping may vary with implementation.
• Use GMT as the last resort if the given or detected time zone ID is unknown.
The default TimeZone created from the ID is cached, and its clone is returned. The user.timezone property value is set to the ID upon return.
In my reading of that, it says the JVM is not going to detect any changes to the host OS setting. Once launched, and once a default has been determined, it is stored in that user.timezone property (and a value in cache) until changed with a call to setDefault.
java.time
You are using the old java.util.Date class which has been supplanted by the java.time framework in Java 8.
Use the java.time.ZonedDateTime class and specify the desired/expected time zone.
ZoneId zoneId = ZoneId.of( " America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( ZoneId );
You should almost never depend on the JVM’s current default time zone ( nor the current default Locale).
import java.util.Date;
public class DateDemo {
public static void main(String args[]) {
//Instantiate a Date object
Date date = new Date();
//display time and date using toString()
System.out.println(date.toString());
}
}

Categories

Resources