电脑时间长了发现系统时间不准确,每次手动调整太麻烦,就自己写个程序校正一下
首先linux下设置时间 date -s "2023-01-29 11:12:13",普通执行没问题,放到java里字符串注意转义引号
另外date命令比较高级需要权限,所以直接执行是不行的,java本身是有限权限,折腾了很久发现还是在外面高权限调用java更快捷
java直接运行class,发现文件名不需要.class就可以,有包名的时候注意路径免得报找不到类错误
最后说一下思路,本来校时可以 sudo rdate -s time.nist.gov,但校时服务器不一定在线,就自己随便找个著名服务器curl访问一下,加上-i参数就会返回一个gmt时间,读取返回数据查找到时间行,然后把时间转换为本地时间配合当天日期调用命令date设置一下,注意curl和date调用命令用string和string[],那是因为date命令里有更复杂参数就用数组参数了
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.SequenceInputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// https://blog.csdn.net/lanlangaogao/article/details/120827047
public class ChangeTime {
/**
* 运行外部命令并获得返回结果
*
* @param command 需要运行的外部命令
* @return 合并标准输出和错误输出的返回结果
*/
public static StringBuilder buildProcess(String[] command) {
StringBuilder builder = new StringBuilder();
try {
Process process = Runtime.getRuntime().exec(command);
try (SequenceInputStream input = new SequenceInputStream(process.getInputStream(),
process.getErrorStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(input))) {
String msg;
while ((msg = reader.readLine()) != null) {
builder.append(msg);
builder.append(System.lineSeparator());
System.out.println(msg);
}
process.waitFor();
process.destroy();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return builder;
}
public static String exeProcess(String command) {
String builder = "";
try {
Process process = Runtime.getRuntime().exec(command);
System.out.println(command);
try (SequenceInputStream input = new SequenceInputStream(process.getInputStream(),
process.getErrorStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(input))) {
String msg;
while ((msg = reader.readLine()) != null) {
if (msg.startsWith("Date:")) {
builder = msg;
break;
}
System.out.println(msg);
}
process.waitFor();
process.destroy();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return builder;
}
public static String runProcess(String[] command) {
StringBuilder builder = buildProcess(command);
if (builder.length() == 0) {
return "";
} else {
return builder.substring(0, builder.length() - System.lineSeparator().length());
}
}
public static String Time_Pattern = "HH:mm:ss";
public static String Day_Pattern = "yyyy-MM-dd";
/**
* @param timePattern yyyy-MM-dd HH:mm:ss.SSSXXX
*/
public static String utcToLocal(String utcTime, String timePattern) {
SimpleDateFormat utcFormater = new SimpleDateFormat(timePattern);
utcFormater.setTimeZone(TimeZone.getTimeZone("UTC"));//时区定义并进行时间获取
Date gpsUTCDate = null;
try {
gpsUTCDate = utcFormater.parse(utcTime);
} catch (ParseException e) {
return utcTime;
}
SimpleDateFormat localFormater = new SimpleDateFormat(timePattern);
localFormater.setTimeZone(TimeZone.getDefault());
String localTime = localFormater.format(gpsUTCDate.getTime());
return localTime;
}
private static String[] getCommand(String command) {
String os = System.getProperty("os.name");
String shell = "/bin/bash";
String c = "-c";
if (os.toLowerCase().startsWith("win")) {
shell = "cmd";
c = "/c";
}
String[] cmd = {shell, c, command};
System.out.println(command);
return cmd;
}
public static void main(String[] args) {
String builder = exeProcess("curl -i www.baidu.com");
System.out.println(builder);
for (String str : builder.split(" ")) {
if (str.indexOf(":") > 0 && str.indexOf(":") < 3) {
String str2 = utcToLocal(str, Time_Pattern);
SimpleDateFormat localFormater = new SimpleDateFormat(Day_Pattern);
Date now = new Date();
String newDate = localFormater.format(now) + " " + str2;
System.out.println(newDate);
StringBuilder cmdBuilder = new StringBuilder();
cmdBuilder.append("date -s \"");
cmdBuilder.append(newDate+"\"");
String runProc = runProcess(getCommand(cmdBuilder.toString()));
System.out.println(runProc);
break;
}
}
}
}
就校时这一块常用的ntp服务,试了几次都没成功 服务器列表 - 全球可用的NTP服务器列表与解析服务 - ntp.org.cn & ntpdate.net
后来网上看到deepin系统自带校时服务,更新/etc/systemd/timesyncd.conf ntp服务地址
比如
cn.pool.ntp.org
然后service systemd-timesyncd start,就启动了系统自己的校时,然后可以看这个服务状态
service systemd-timesyncd status