如何用Java设置系统时间?
可以用Java更改系统时间吗 它应该在Windows和Linux下运行。我已经在中的如何用Java设置系统时间?,java,systemtime,Java,Systemtime,可以用Java更改系统时间吗 它应该在Windows和Linux下运行。我已经在中的运行时类中尝试过,但权限有问题 这是我的代码: String cmd="date -s \""+datetime.format(ntp_obj.getDest_Time())+"\""; try { Runtime.getRuntime().exec(cmd); } catch (IOException e1) { // TODO Auto-generated catch block e1.print
运行时类中尝试过,但权限有问题
这是我的代码:
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服务器获取时间并将其设置 一种方法是使用本机命令
对于Windows,需要两个命令(日期和时间):
Runtime.getRuntime().exec("cmd /C date " + strDateToSet); // dd-MM-yy
Runtime.getRuntime().exec("cmd /C time " + strTimeToSet); // hh:mm:ss
对于linux,一个命令同时处理日期和时间:
Runtime.getRuntime().exec("date -s " + strDateTimeToSet); // MMddhhmm[[yy]yy]
9年后更新
这不是设置系统时间的好方法,而不是使用java.util.Clock
获取当前时间,并在需要时提供模拟实现来伪造时间。您只能通过以root或administrator身份运行命令行工具来设置系统时间。命令不同,但您可以先检查操作系统,然后为该操作系统运行相应的命令。Java没有API来执行此操作
执行此操作的大多数系统命令都需要管理员权限,因此除非您以管理员/root身份运行整个过程,或者使用runas
/sudo
,否则运行时
将帮不上忙
根据需要,您可以更换System.currentTimeMillis()
。这有两种方法:
将对System.currentTimeMillis()
的所有调用替换为对您自己的静态方法的调用,您可以替换该方法:
public class SysTime {
public static SysTime INSTANCE = new SysTime();
public long now() {
return System.currentTimeMillis();
}
}
对于测试,您可以使用其他时间返回的内容覆盖实例。添加更多方法来创建Date
和类似对象
如果不是所有的代码都在您的控制之下,请安装一个类加载器
,它为系统
返回一个不同的实现。这比你想象的要简单:
@Override
public Class<?> loadClass( String name, boolean resolve ) {
if ( "java.lang.System".equals( name ) ) {
return SystemWithDifferentTime.class;
}
return super.loadClass( name, resolve );
}
@覆盖
公共类loadClass(字符串名称,布尔解析){
if(“java.lang.System”.equals(name)){
返回系统具有不同的time.class;
}
返回super.loadClass(名称、解析);
}
您可以使用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);
}
JavaJNI包装器将是
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);
}
}
在windows管理员模式下运行此代码。在某些情况下,进程不使用管理员权限运行,但仍有权限设置系统时间。可以使用来更改系统时间,并在Java中拥有所有必需的源代码(与JNI相比更简单)
包github.jna;
导入com.sun.jna.Native;
导入com.sun.jna.platform.win32.WinBase.SYSTEMTIME;
导入com.sun.jna.win32.StdCallLibrary;
/**
*提供对Windows SetSystemTime本机API调用的访问。
*该类基于中的示例
*
*/
公共类WindowsSetSystemTime{
/**
*内核32 DLL接口。
*kernel32.dll使用u stdcall调用约定(检查函数
*声明为“WINAPI”或“PASCAL”),因此扩展StdCallLibrary
*大多数C库只会扩展com.sun.jna.Library,
*/
公共接口内核32扩展StdCallLibrary{
布尔SetLocalTime(SYSTEMTIME st);
Kernel32实例=(Kernel32)Native.loadLibrary(“Kernel32.dll”,Kernel32.class);
}
公共布尔值SetLocalTime(SYSTEMTIME st){
返回Kernel32.instance.SetLocalTime(st);
}
公共布尔值SetLocalTime(短wYear、短wMonth、短wDay、短wHour、短wMinute、短wSecond){
SYSTEMTIME st=新的SYSTEMTIME();
圣威耳=威耳;
st.W月=W月;
st.wDay=wDay;
圣呼=呼;
st.wMinute=wMinute;
st.wSecond=wSecond;
返回SetLocalTime(st);
}
}
您可以使用以下代码更改日期或在当前日期中添加日期。它在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);
在上面的代码中,我在当前日期的基础上增加了1天,您可以传递StreExpectedDate的任何日期,这只在windows上起作用为什么您需要设置系统时间?还包括当前相关代码和遇到的错误/问题(例如,权限中的“错误”是什么?)@SSZero,因为系统时间不正确/不准确?您需要在Windows上使用单独的时间命令。Runtime.getRuntime().exec(“cmd/C time”+strTimeToSet);//hh:mm:ss安装带有java.lang.*
名称的类加载器是否总是有效?是的,就类加载而言,java.lang
没有什么神奇之处。就JIT和VM而言,它不应该有什么神奇之处——如果你用其他东西替换String.class
,这应该是可行的,因为类是像其他东西一样加载的。我正在测试第2种方法,得到:java.lang.SecurityException:禁止的包名:java.lang,所以我认为实际上有一些“神奇之处”关于java.lang.@BoneGoat:不,没有。但是你已经安装了SecurityManager
,这样的事情就不可能再发生了。改为使用joda time
。@Pacerier不确定Mac中是否有不同的命令/util,您可以在Mac上试用terminal@JigarJoshi问题是我没有Mac(在Windows上)btw date只更改日期,我们还需要执行命令time来更改系统时间。@msanjay查找命令来设置时间,我想date应该做itAsexec()
为每个调用派生一个新的进程,我建议对两个windows调用进行如下操作:Runtime.getRuntime().exec(“cmd/C date”+strDateToSet+“&time”+strTimeToSet)代码>
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 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();
}
}
}
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);