java调用命令行校对系统时间

电脑时间长了发现系统时间不准确,每次手动调整太麻烦,就自己写个程序校正一下

首先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
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值