我用快捷方式做到了。快捷方式cmd
与命令链接,更改时间或与服务器时间同步时间。由于更改系统设置快捷方式应以管理员权限调用,因此有一种方法自动设置快捷方式标志Run as administrator
。为了确保同步成功,有一种方法safeSynchronize
将时间更改为假时间,然后才询问服务器时间。对我来说,它完美无缺。
package system;
import mslinks.ShellLink;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.time.DateUtils;
import java.io.*;
import java.nio.file.Files;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
public class TimeSynchronizer {
Random random = new Random();
private int WAIT_LAG = 1000;
private DateFormat dateFormat = new SimpleDateFormat("dd-MM-yy");
private DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
public void synchronize() throws IOException, InterruptedException {
File file = getFile();
makeShortcut(file, "/c net start w32time");
callShortcut(file);
makeShortcut(file, "/c w32tm /resync");
callShortcut(file);
if (file.exists()) file.delete();
}
public void safeSynchronize() throws IOException, InterruptedException {
Calendar rightNow = Calendar.getInstance();
int minute = rightNow.get(Calendar.MINUTE);
boolean isForward = minute < 30;
Date date = DateUtils.addMinutes(Date.from(Instant.now()), 10 * (isForward ? 1 : -1));
setTime(date);
synchronize();
}
public void setTime(Date date) throws IOException, InterruptedException {
setTime(date, false);
}
public void setTime(Date date, boolean withDate) throws IOException, InterruptedException {
File file = getFile();
if (withDate) {
makeShortcut(file, "/c date " + dateFormat.format(date));
callShortcut(file);
}
makeShortcut(file, "/c time " + timeFormat.format(date));
callShortcut(file);
if (file.exists()) file.delete();
}
private void callShortcut(File file) throws IOException, InterruptedException {
Process process = Runtime.getRuntime().exec(
getSystem32Path() + "\\cmd.exe /c start /wait \"\" \"" + file.getAbsolutePath() + "\""
);
process.waitFor();
process.exitValue();
}
private String getSystem32Path() {
return System.getenv("SystemRoot") + "\\system32";
}
private File getFile() {
return new File(random.nextInt() + "shortcut.lnk");
}
private void makeShortcut(File file, String command) throws IOException, InterruptedException {
String system32Path = getSystem32Path();
ShellLink s = new ShellLink();
s.setTarget(system32Path + "\\cmd.exe");
s.setCMDArgs(command);
s.saveTo(file.getAbsolutePath());
Thread.sleep(WAIT_LAG);
setRunAsAdmin(file);
}
private void setRunAsAdmin(File file) throws IOException {
byte[] fileContent = Files.readAllBytes(file.toPath());
fileContent[21] = (char)32;
FileUtils.writeByteArrayToFile(file, fileContent);
}
}