How can I set the System Time in Java?

岁酱吖の 提交于 2019-11-26 10:42:59

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:

  1. 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.

  2. If not all code is under your control, install a ClassLoader which returns a different implementation for System. 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 );
    }
    
Jigar Joshi

One way would be using native commands.

for Windows, two commands (date and time) are required:

Runtime.getRuntime().exec("cmd /C date " + strDateToSet); // dd-MM-yy
Runtime.getRuntime().exec("cmd /C time " + strTimeToSet); // hh:mm:ss

for linux, a single command handles both date and time:

Runtime.getRuntime().exec("date -s " + strDateTimeToSet); // MMddhhmm[[yy]yy]

You can only set the system time by running a command line tool as root or Adminstrator. The command are different but you can check the OS first and run the appropriate command for that OS.

You can use JNI for setting the system time. This would work on Windows. You need to know JNI and C.

This is the JNI function, the prototype will be generated by the javah utility

JNIEXPORT void JNICALL Java_TimeSetter_setSystemTime
  (JNIEnv *env, jobject obj, jshort hour, jshort minutes) {

    SYSTEMTIME st;
    GetLocalTime(&st);  
    st.wHour = hour;      
    st.wMinute = minutes;  
    SetLocalTime(&st);   
}

The Java JNI wrapper would be

class TimeSetter {

    public native void setSystemTime( short hour, short minutes);

    static {
        System.loadLibrary("TimeSetter");
    }
}

And finally, to use it

public class JNITimeSetter {

    public static void main(String[] args) {

        short hour = 8;
        short minutes = 30;

        // Set the system at 8h 30m

        TimeSetter ts = new TimeSetter();
        ts.setSystemTime(hour, minutes);
    }
}

There are cases where the process does not run with admin rights, but it still has the permissions to set the system time. It is possible to use Java Native Access to change the system time and have all the required sources in Java (simpler compared with JNI).

package github.jna;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinBase.SYSTEMTIME;
import com.sun.jna.win32.StdCallLibrary;

/**
 * Provides access to the Windows SetSystemTime native API call.
 * This class is based on examples found in
 * <a href="https://github.com/twall/jna/blob/master/www/GettingStarted.md">JNA Getting Started</a>
 */
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);
    }       
}
package myTestProject;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class LocalTimeChangeTest {

    private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args) {
        try {
            String value = "2014-12-12 00:26:14";
            Date date = dateFormat.parse(value);
            value = dateFormat.format(date);
            final Process dateProcess = Runtime.getRuntime().exec("cmd /c date "+value.substring(0, value.lastIndexOf(' ')));
            dateProcess.waitFor();
            dateProcess.exitValue();
            final Process timeProcess = Runtime.getRuntime().exec("cmd /c time "+value.substring(value.lastIndexOf(' ')+1));
            timeProcess.waitFor();
            timeProcess.exitValue();
        } catch (Exception exception) {
            throw new RuntimeException(exception);
        }
    }
}

Run this code under windows administrator model.

SMV
package com.test;

public class Exec {

    public static void main(String[] args) {
        try {
            String[] cmd = {"/bin/bash","-c","echo yourPassword | sudo -S date --set='2017-05-13 21:59:10'"};
            Runtime.getRuntime().exec(cmd);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

You can change the date or add the date in current date using below code. It is working perfectly in windows:

Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
SimpleDateFormat s = new SimpleDateFormat("MM-dd-yyyy");    
String strExpectedDate = s.format(new Date(cal.getTimeInMillis()));
Runtime rt = Runtime.getRuntime();
rt.exec("cmd /C date " + strExpectedDate);

In above code I have added 1 day to current date, You can pass any date for strExpectedDate and this will only work on windows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!