2025年3月25日 星期二 甲辰(龙)年 月廿四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 编程箴言

计算两个时间之间的持续时间

时间:02-07来源:作者:点击数:49

需求是这样的,公司一个项目出了问题,是一个即时通讯App,为了保持在线状态,App会每15秒向服务器发送心跳包,服务器上,过期时间为30秒,即30秒内如果没收到心跳包,即会把该用户设置为离线状态。问题是有时候发现视频通话还在,但是在线状态已经是离线状态了,这时就打印了App收和发的所有消息,就发现有时发完心跳包之后,半个多小时没有发的消息,也没有收的消息。有时候日志太多了,就希望快速定位到这种突然隔了很久没有收发消息的日志,因为在发送消息和收消息的日志中,都会以时间开头写到日志中,所以就可以通过写程序读取这个日志文件,读取每一行的时间,然后比较两个时间之间的间隔是不是隔了很久,这样一下就能找出所有这种间隔大的时间日志了。

使用Java8的Date类来实现,先说一下重点的类:

  • LocalDate 表示一个日期,不带时间的,如:2021-09-07
  • LocalTime 表示一个时间,不带日期的,如:14:30:25
  • LocalDateTime 表示日期和时间,如:2021-09-07 14:30:25
  • Duration 表示一段持续的时间:如:比如计算13点45分 到 13点50分之间经过了5分钟,这个5分钟就是一个Duration。

具体类的使用可参考:https://www.cdsy.xyz/computer/programme/java/230207/cd40308.html

实现计算两个时间之间Duration的代码如下:

  • String pattern = "yyyy-MM-dd HH:mm:ss:SSS";
  • DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
  • String date1 = "2021-09-06 00:00:00:000";
  • String date2 = "2021-09-07 23:30:30:100";
  • LocalDateTime start = LocalDateTime.parse(date1, formatter);
  • LocalDateTime end = LocalDateTime.parse(date2, formatter);
  • Duration duration = Duration.between(start, end);
  • System.out.println(duration.toDaysPart());
  • System.out.println(duration.toHours());
  • System.out.println(duration.toSeconds());
  • System.out.println(duration.toMillis());

Duration.between(start, end) 这个函数需要注意,最好把小的时间放在第一个参数,大的时间放在第二个参数。

输出结果如下:

  • 1
  • 47
  • 171030
  • 171030100

如上代码中的两个时间,差半个小时就两天了,从输出结果看,它是不算小数的,直接取整数,丢掉小数,比如间隔转换为天数,按道理大概是1.9天吧,但是输出是1。换成小时,大概是47.5小时,但是输出是47小时。查看这几个函数的原代码发现,其实duration中有一个senconds属性,用秒的方式保存了两个时间之间的持续时间,如果要换成天,就拿这个senconds除以1天对应的秒数,要换成小时就除以1小时对应的秒除,要换成分,就除以1分对应的秒数(即60),最后结果都是直接取整,丢掉小数。

下面就捧上实现我公司需求的代码,先上一小段日志,如下:

  • 2021-09-06 09:07:42:717 timer 3 fires
  • 2021-09-06 09:07:42:891 RECV:SIP/2.0 200 OK
  • v:SIP/2.0/TCP 172.18.118.245:52639;branch=z9hG4bK-1153217720;rport=52639
  • f:<sip:150205@10.238.113.71>;tag=2125390592
  • t:<sip:150205@10.238.113.71>;tag=48mD9Dp42eX1j

可以发现,并不是每一行都以时间开头的,所以可以使用正则表达式来获取每一行开头的时间,还要考虑开头没有时间的情况,实现代码如下,这里会打印时间间隔大于10分钟的两个时间,如下:

  • public class Main {
  • public static void main(String[] args) throws IOException {
  • String path = "C:\\Users\\Even\\Desktop\\doubango.log";
  • printLongTimeInterval(path);
  • }
  • /** 打印长时间间隔 */
  • private static void printLongTimeInterval(String path) throws IOException {
  • BufferedReader reader = new BufferedReader(new FileReader(path));
  • String line;
  • String pattern = "yyyy-MM-dd HH:mm:ss:SSS";
  • DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
  • LocalDateTime start = null;
  • while ((line = reader.readLine()) != null) {
  • String time = getTime(line);
  • if (time != null) {
  • LocalDateTime end = LocalDateTime.parse(time, formatter);
  • if (start != null) {
  • Duration duration = Duration.between(start, end);
  • long minutes = duration.toMinutes();
  • if (minutes > 10) {
  • System.out.println("----------------------------------------");
  • System.out.println(start.format(formatter));
  • System.out.println(end.format(formatter));
  • System.out.println("时间间隔:" + minutes + "分钟");
  • }
  • }
  • start = end;
  • }
  • }
  • }
  • /** 通过正则获取字符串开头的日期,例如:2021-09-02 07:56:50:969 RECV:SIP/2.0 200 OK,获取的日期为:2021-09-02 07:56:50:969*/
  • private static String getTime(String string) {
  • String regex = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}:\\d{3}";
  • Pattern pattern = Pattern.compile(regex);
  • Matcher matcher = pattern.matcher(string);
  • boolean find = matcher.find();
  • if (find) {
  • return matcher.group();
  • }
  • return null;
  • }
  • }

输出结果如下:

  • ----------------------------------------
  • 2021-09-02 15:57:45:992
  • 2021-09-02 16:26:03:659
  • 时间间隔:28分钟
  • ----------------------------------------
  • 2021-09-02 18:04:44:239
  • 2021-09-02 18:33:33:942
  • 时间间隔:28分钟
  • ----------------------------------------
  • 2021-09-03 11:12:24:067
  • 2021-09-03 11:40:32:856
  • 时间间隔:28分钟
  • ----------------------------------------
  • 2021-09-03 11:41:55:067
  • 2021-09-03 12:10:46:368
  • 时间间隔:28分钟

如上日志,在两天的日志中,有4个地方是时间间隔很大的,如果要用肉眼去找出这样的日志,恐怕要疯啊!所以编程是个好东西!

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门