0

My java application is running on Ubuntu, I've a use case where I need to change OS timezone from java. I tried to achieve that by using Joda and Java.util.Timezone. but It seems, they changed just jvm timezone not the actual OS.

So, on server/machine restart I'm getting old timezone. Is there any way I can achieve that from java or I need to rely on Runtime.getRuntime().exec("os commands")?

NOTE: In this scenario, timezone will be a user specific(User will define it's own timezone). Different instances may have different timezones.

Muneeb Nasir
  • 2,414
  • 4
  • 31
  • 54
  • 5
    Permanently changing the OS timezone needs elevated permissions (specifically, on Linux, write access to `/etc/localtime`). You cannot do that from Java alone, unless your program is executing with root privileges. – Amadan Sep 05 '19 at 06:24
  • program have that privileges. – Muneeb Nasir Sep 05 '19 at 06:28
  • 2
    If you are running a Java program with elevated privileges, that could be a bad idea. Have you audited it? If this is product code, have you considered that your customers may (should) want to audit it? – Stephen C Sep 05 '19 at 06:35
  • Yes, if you are sure that this is a good idea, you need to rely on `Runtime.getRuntime().exec("os commands")` or some other way to manipulate the OS. – Ole V.V. Sep 05 '19 at 06:39
  • @OleV.V.: No, you do not (at least not for Linux). See my answer. – Amadan Sep 05 '19 at 06:40
  • In your last sentence, what do you mean by "User" and "instances"? – Basil Bourque Sep 05 '19 at 06:56
  • @BasilBourque actually this app/program is for enterprise users. Each customer (user) will have it's own customize application running in their environment. – Muneeb Nasir Sep 05 '19 at 07:04

3 Answers3

2

Assuming you have root permissions, this will change the OS timezone in Linux:

import java.io.File;
import java.nio.file.Files;
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;    

// ...

String zone = "Asia/Tokyo";
File source = new File("/usr/share/zoneinfo/" + zone);
File dest = new File("/etc/localtime");
Files.copy(source.toPath(), dest.toPath(), REPLACE_EXISTING, COPY_ATTRIBUTES);

Note that changing the OS default timezone will not affect current processes. Also note that this is not portable.

EDIT: I second Stephen C's warning about running custom code under elevated privileges.

EDIT: It would probably be better to make a symlink, but either should work.

EDIT: To permanently change a single user's timezone, write export TZ='Asia/Tokyo' into a startup script, like .bashrc. You do not need elevated permissions for that.

Amadan
  • 191,408
  • 23
  • 240
  • 301
1

The JVM maintains its own default time zone, unconnected to the host OS time zone settings.

Most every Java implementation defaults on launch to the host OS’ current default time zone. Optionally, you may pass arguments to the JVM launcher to specify another time zone. Lastly, a call to TimeZone.setDefault immediately changes the current default time zone for all code in all threads of all apps running within that JVM.

I need to change OS timezone from java.

Not possible using the bundled Java classes. No implementation of Java I know of would give that kind of power to a Java app.

You may be able to call some native app or utility from within Java that could alter the host OS time zone settings. But you would have to find such a utility, and set up the bridging call from Java to native code. Or you might be able to execute a shell script to make that OS setting change.

As far as date-time handling within your Java code, you should not rely on the default time zone of either the host OS nor the JVM. I recommend always passing the optional ZoneId (or ZoneOffset) to the various date-time methods. Omitting the argument leads to relying implicitly on the JVM's current default time zone. Better to specify your desired/expected time zone.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

By the way, be aware that the Joda-Time project is now in maintenance-mode. Its creator, Stephen Colebourne, went on to create its successor in the java.time classes defined by JSR 310, now bundled with Java 8 and later.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • OP may want to change the OS timezone for other apps, not necessarily java apps. That's my understanding from *but It seems, they changed just jvm timezone not the actual OS* (= I expected every other program to get the new timezone), so I don't think this question is strictly related to the JVM, maybe I'm wrong though – BackSlash Sep 05 '19 at 06:33
  • @BackSlash I suggest posting that as a request for clarification to the author of the Question. I agree the Question is not clear. – Basil Bourque Sep 05 '19 at 06:35
  • Yes - I want to change OS timezone (off-course that has impact on other app running on that server) not just the java. actually I have a dedicated VM for my app. I don't care about the impact on other application as of now. – Muneeb Nasir Sep 05 '19 at 06:41
  • Timezone is user specific not application specific. different instance of app may have different timezones. – Muneeb Nasir Sep 05 '19 at 06:43
-2

This is posible answer :

Calendar gmtTime = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
System.out.println(gmtTime.getTime());
BackSlash
  • 21,927
  • 22
  • 96
  • 136