How can I set the System Time in Java?
Java doesn't have an API to do this.
Most system commands to do it require admin rights, so Runtime
can't help unless you run the whole process as administrator/root or you use runas
/sudo
.
Depending on what you need, you can replace System.currentTimeMillis()
. There are two approaches to this:
Replace all calls to
System.currentTimeMillis()
with a call to a static method of your own which you can replace:public class SysTime {
public static SysTime INSTANCE = new SysTime();
public long now() {
return System.currentTimeMillis();
}
}For tests, you can overwrite INSTANCE with something that returns other times. Add more methods to create
Date
and similar objects.If not all code is under your control, install a
ClassLoader
which returns a different implementation forSystem
. This is more simple than you'd think:@Override
public Class<?> loadClass( String name, boolean resolve ) {
if ( "java.lang.System".equals( name ) ) {
return SystemWithDifferentTime.class;
}
return super.loadClass( name, resolve );
}
How to get the current date/time in Java
It depends on what form of date / time you want:
If you want the date / time as a single numeric value, then
System.currentTimeMillis()
gives you that, expressed as the number of milliseconds after the UNIX epoch (as a Javalong
). This value is a delta from a UTC time-point, and is independent of the local time-zone1.If you want the date / time in a form that allows you to access the components (year, month, etc) numerically, you could use one of the following:
new Date()
gives you aDate
object initialized with the current date / time. The problem is that theDate
API methods are mostly flawed ... and deprecated.Calendar.getInstance()
gives you aCalendar
object initialized with the current date / time, using the defaultLocale
andTimeZone
. Other overloads allow you to use a specificLocale
and/orTimeZone
. Calendar works ... but the APIs are still cumbersome.new org.joda.time.DateTime()
gives you a Joda-time object initialized with the current date / time, using the default time zone and chronology. There are lots of other Joda alternatives ... too many to describe here. (But note that some people report that Joda time has performance issues.; e.g. https://stackoverflow.com/questions/6280829.)in Java 8, calling
java.time.LocalDateTime.now()
andjava.time.ZonedDateTime.now()
will give you representations2 for the current date / time.
Prior to Java 8, most people who know about these things recommended Joda-time as having (by far) the best Java APIs for doing things involving time point and duration calculations.
With Java 8 and later, the standard java.time
package is recommended. Joda time is now considered "obsolete", and the Joda maintainers are recommending that people migrate.3.
1 - System.currentTimeMillis()
gives the "system" time. While it is normal practice for the system clock to be set to (nominal) UTC, there will be a difference (a delta) between the local UTC clock and true UTC. The size of the delta depends on how well (and how often) the system's clock is synced with UTC.
2 - Note that LocalDateTime doesn't include a time zone. As the javadoc says: "It cannot represent an instant on the time-line without additional information such as an offset or time-zone."
3 - Note: your Java 8 code won't break if you don't migrate, but the Joda codebase may eventually stop getting bug fixes and other patches. As of 2020-02, an official "end of life" for Joda has not been announced, and the Joda APIs have not been marked as Deprecated.
Programmatically set System Time
As it turns out, the answer did lie in the referenced question found here. However, the command is different for Android 7 (and possibly 6, I have not tested) devices. I do not have the reputation to comment over there, so if someone wishes to paste/reference this answer on that question, go right ahead.
The date code I used was in the format MMddhhmmyy, rather than yyyyMMdd.hhmmss; this works for me on Android 7. I also removed the appended '-s'. The full working code I used to set the system time is below. Again it should be noted that this requires rooting the device so is only useful in certain scenarios like mine.
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
String command = "date 1123104017\n";
// Log.e("command",command);
os.writeBytes(command);
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (InterruptedException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
The date I entered, for clarity, is November 23rd 2017 at 10:40 AM.
Code snippet to change system date and time in java
You look to be missing the -s argument in the date and time commands, so your waitFor() method never returns because it's waiting for user input.
Try changing
final Process dateProcess = Runtime.getRuntime().exec("cmd /c date "+value.substring(0, value.lastIndexOf(' ')));
to
final Process dateProcess = Runtime.getRuntime().exec("cmd /c date -s "+value.substring(0, value.lastIndexOf(' ')));
and the same for your time command. (Assuming this is Windows only).
Setting the system time of JVM
Take a look at this post over on the super user stack exchange. There are 2 different clocks in linux. One is hardware (hwclock) and the other is os/system.
Best way to set date and time on windows machine by java application
I tried to implement the solution with JNA importing kernel32.dll performed the test on Windows 7 machine with timezone UTC+1 (Italy country).
I describe the steps:
1) I imported my maven project the followed dependencies:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.3.0</version>
</dependency>
2) I implemented the followed class:
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinBase.SYSTEMTIME;
import com.sun.jna.win32.StdCallLibrary;
@Component
@Qualifier("windowsSetSystemTime")
public class WindowsSetSystemTime {
/**
* Kernel32 DLL Interface. kernel32.dll uses the __stdcall calling
* convention (check the function declaration for "WINAPI" or "PASCAL"), so
* extend StdCallLibrary Most C libraries will just extend
* com.sun.jna.Library,
*/
public interface Kernel32 extends StdCallLibrary {
boolean SetLocalTime(SYSTEMTIME st);
Kernel32 instance = (Kernel32) Native.loadLibrary("kernel32.dll", Kernel32.class);
}
public boolean SetLocalTime(SYSTEMTIME st) {
return Kernel32.instance.SetLocalTime(st);
}
public boolean SetLocalTime(short wYear, short wMonth, short wDay, short wHour, short wMinute, short wSecond) {
SYSTEMTIME st = new SYSTEMTIME();
st.wYear = wYear;
st.wMonth = wMonth;
st.wDay = wDay;
st.wHour = wHour;
st.wMinute = wMinute;
st.wSecond = wSecond;
return SetLocalTime(st);
}
}
3) By the test class I tried to set the followed date and time
public void setTime(){
System.out.println("START SYNC " + windowsSetSystemTime);
windowsSetSystemTime.SetLocalTime((short)2017, (short)10,(short) 29,(short) 11,(short) 35,(short) 0);
}
TEST RESULT:
As result in this case I obtained the correct date and time because the function considered daylight winter time saving that enter at 29 October 2017 3:00.
Before test, clock was set:
After test clock set:
I found out the logic SetLocalTime method into Kernel32.dll by Windows dev center documentation at link:
SetLocalTime documentation
Windows Dev center REMARKS SetLocalTime:
The system uses UTC internally. Therefore, when you call SetLocalTime, the system uses the current time zone information to perform the conversion, including the daylight saving time setting. Note that the system uses the daylight saving time setting of the current time, not the new time you are setting. Therefore, to ensure the correct result, call SetLocalTime a second time, now that the first call has updated the daylight saving time setting.
How to get system time in Java without creating a new Date
As jzd says, you can use System.currentTimeMillis
. If you need it in a Date
object but don't want to create a new Date
object, you can use Date.setTime
to reuse an existing Date
object. Personally I hate the fact that Date
is mutable, but maybe it's useful to you in this particular case. Similarly, Calendar
has a setTimeInMillis
method.
If possible though, it would probably be better just to keep it as a long
. If you only need a timestamp, effectively, then that would be the best approach.
How to set time zone of a java.util.Date?
Use DateFormat. For example,
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");
Related Topics
Getting Java.Sql.Sqlexception: Operation Not Allowed After Resultset Closed
Add an Background Image to a Panel
How to Watch for Single File Change with Watchservice (Not the Whole Directory)
Masking Password Input from the Console:Java
How to Get a Thread and Heap Dump of a Java Process on Windows That's Not Running in a Console
Break When Exception Is Thrown
How to Select a Dropdown Value in Selenium Webdriver Using Java
Possible Causes of Java Vm Exception_Access_Violation
Spring Boot Rest Service Exception Handling
Does a Finally Block Always Run
How to Re-Attach Detached Objects in Hibernate
How to Get the Name of the Calling Class in Java
Should We @Override an Interface's Method Implementation