我怎样才能在Java中设置系统时间?
是否有可能改变Java的系统时间?
它应该在Windows和Linux下运行。 我已经尝试过Runtime
类,但有一个权限问题。
[编辑]
你好,谢谢,
这里是我尝试的代码:
String cmd="date -s \""+datetime.format(ntp_obj.getDest_Time())+"\""; try { Runtime.getRuntime().exec(cmd); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println(cmd);
cmd的输出是: date -s“06/01/2011 17:59:01”但是系统时间和以前一样。
我会设置时间,因为我正在写一个NTP客户端,并从那里得到一个NTP服务器的时间,并将其设置。
Java没有一个API来做到这一点。
大部分系统命令都需要pipe理员权限,所以除非以pipe理员/ root身份运行整个进程,或者使用runas
/ sudo
否则Runtime
将无法提供帮助。
根据你所需要的,你可以replaceSystem.currentTimeMillis()
。 有两种方法:
-
将所有调用replace为您可以replace的静态方法
System.currentTimeMillis()
:public class SysTime { public static SysTime INSTANCE = new SysTime(); public long now() { return System.currentTimeMillis(); } }
对于testing,您可以用其他时间返回的东西覆盖INSTANCE。 添加更多的方法来创build
Date
和类似的对象。 -
如果不是所有的代码都在你的控制之下,那么安装一个
ClassLoader
,它将为System
返回一个不同的实现。 这比你想象的更简单:@Override public Class<?> loadClass( String name, boolean resolve ) { if ( "java.lang.System".equals( name ) ) { return SystemWithDifferentTime.class; } return super.loadClass( name, resolve ); }
一种方法是使用本机命令。
对于Windows,需要两个命令(date和时间):
Runtime.getRuntime().exec("cmd /C date " + strDateToSet); // dd-MM-yy Runtime.getRuntime().exec("cmd /C time " + strTimeToSet); // hh:mm:ss
对于linux,一个命令处理date和时间:
Runtime.getRuntime().exec("date -s " + strDateTimeToSet); // MMddhhmm[[yy]yy]
您只能通过以root或Adminstrator身份运行命令行工具来设置系统时间。 该命令是不同的,但您可以先检查操作系统,并运行适当的命令该操作系统。
您可以使用JNI
来设置系统时间。 这将在Windows上工作。 你需要知道JNI
和C
这是JNI函数,原型将由javah
实用程序生成
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); }
Java的JNI包装将是
class TimeSetter { public native void setSystemTime( short hour, short minutes); static { System.loadLibrary("TimeSetter"); } }
最后,使用它
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); } }
在某些情况下,进程不会以pipe理员权限运行,但仍具有设置系统时间的权限。 可以使用Java Native Access来改变系统时间并在Java中具有所有必需的源代码(与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); } } }
在Windowspipe理员模式下运行此代码。
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(); } } }