起航学习网

- 让每个人都能学到最前沿新知识、新技能!
起航学习网
当前位置: 起航学习网 > 短期培训 > 编程语言 > 如何使按秒输出当前时间的程序不跳秒

如何使按秒输出当前时间的程序不跳秒

时间:2021-07-29 15:15:05来源:Java开发培训网 作者:Java开发教程网 已有: 名学员访问该课程

前言:学习线程的时候,IT培训网Java开发培训的传奇老师带我们做了一个按秒显示当前时间的小程序。这个程序不难, 但传

学习线程的时候,IT培训网Java开发培训的传奇老师带我们做了一个按秒显示当前时间的小程序。这个程序不难,
但传奇老师课上提到这个小程序有缺陷,就是你仔细盯着输出结果看,有时候会发现显示
的时间突然跳了一秒,比如从19:56:42 跳到19:56:44。
我对这个现象产生的原因很感兴趣,于是研究了一下它是如何产生的以及研究了一下解决办法。
原程序如下:

import Java.text.SimpleDateFormat;
import Java.util.Calendar;
import Java.util.Date;

public class ThreadDemo8 {

/**
* @param args
*/
public static void main(String[] args) {
/*
* 实现电子表功能
* 每秒钟输出依次当前系统时间
* HH:mm:ss
*/
Thread t=new Thread(){
public void run(){
Calendar calendar;
Date date;
String str;
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
for(;;){
calendar=Calendar.getInstance();
calendar.add(calendar.HOUR_OF_DAY, 16);
calendar.add(calendar.MINUTE, 4);
date=calendar.getTime();
str=sdf.format(date);
System.out.println(str+" ");//输出当前时间
try{
Thread.sleep(1000);
}catch(InterruptedException e){
}
}
}
};
t.start();
}
}

为了使时间显示的更精确,我将用于输出当前时间的 System.out.println(str+" ");
这句改为了 System.out.println(str+" "+System.currentTimeMillis()%1000);
输出结果如下:
20:09:43 998
20:09:44 998
20:09:45 998
20:09:46 999
20:09:47 999
20:09:48 999
20:09:49 999
20:09:50 999
20:09:52 0
20:09:53 0
20:09:54 0
20:09:55 0
20:09:56 1
20:09:57 1
20:09:58 1
20:09:59 1
20:10:00 2
20:10:01 2
20:10:02 2

可以发现,在20:09:50到20:09:52发生了跳跃,把20:09:51隔过去了。还能发现大约每数4.4次,
毫秒数会+1,也就是每4.4*1000=4400次即73分钟会跳一次秒。这是不是很像每天比实际地球自转
时间多算约4分钟,所以每4年要多1天来抵消这个误差?这个计时程序的误差来自
Thread.sleep(1000); 这里没有把计算机运行一次for循环所用的时间考虑进去。所以,它应
该sleep更少的时间才对,大约少sleep 1/4.4毫秒。
于是,我就像用增加润年的方法把
Thread.sleep(1000); 改为:
Thread.sleep(1000-i%5/4+i%40/39); //每5毫秒减少1毫秒,每40毫秒增加1毫秒
它的输出结果变成这样了
20:25:36 393
20:25:37 393
20:25:38 394
20:25:39 394
20:25:40 394
20:25:41 393
20:25:42 393
20:25:43 394
20:25:44 394
20:25:45 394
20:25:46 393
20:25:47 394
20:25:48 394
误差小了很多,但是还是不够精确。就像我们现实的时间虽有润年调整,还是无法和地球自转时间对照,
因此前几年有2天都出现了如19:59:60这样时间,增加1秒以对地球的计时做校正。
但是,在这个程序中我们可以抛弃这种永远无法真正校准时间的方法。我想起了原来我学过的一门课程
《自动控制原理》,里面有个概念叫做负反馈,根据结果来校正下一次的结果可以做到真正的精准。
用在这里具体就是:输出的时间超了1毫秒就在下次减1毫秒,超2毫秒就减2毫秒。反正它能自动调整为
准确时间
于是有了如下方法:
Thread.sleep(1000); 改为:
Thread.sleep(1000-System.currentTimeMillis()%1000);
输出结果如下:
20:32:32 0
20:32:33 0
20:32:34 0
20:32:35 0
20:32:36 0
20:32:37 0
20:32:38 0
可以发现,这次的输出时间都是和系统几乎同步的!做到了真正的精准。最终版本的程序如下:


import Java.text.SimpleDateFormat;
import Java.util.Calendar;
import Java.util.Date;

public class ThreadDemo8 {

/**
* @param args
*/
public static void main(String[] args) {
/*
* 实现电子表功能
* 每秒钟输出依次当前系统时间
* HH:mm:ss
*/
Thread t=new Thread(){
public void run(){
Calendar calendar;
Date date;
String str;
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
for(int i=0;;i++){
calendar=Calendar.getInstance();
calendar.add(calendar.HOUR_OF_DAY, 16);
calendar.add(calendar.MINUTE, 4);
date=calendar.getTime();
str=sdf.format(date);
if(i>0){
System.out.println(str+" "+System.currentTimeMillis()%1000);
}
try{
Thread.sleep(1000-System.currentTimeMillis()%1000);
}catch(InterruptedException e){
}
}
}
};
t.start();
}

}

文章出自:http://qh.itpxw.cn/peixun/software/202190806.html

文章标题:如何使按秒输出当前时间的程序不跳秒



免责声明:本站文章均由入驻起航学习网的会员所发或者网络转载,所述观点仅代表作者本人,不代表起航学习网立场。如有侵权或者其他问题,请联系举报,必删。侵权投诉

(责任编辑:深圳学历教育网)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
培训学校
IT培训网 访问该机构站点 报名留言 加为好友 用户等级:注册会员 用户级别:10 机构名称:IT培训网 联 系 人:罗老师 联系电话:13783581536 联系手机:13783581536 在线客服:起航学习网客服 在 线 QQ:起航学习网客服 电子邮件: 网站域名:http://www.itpxw.cn 注册时间:2016-07-18 11:07 最后登录:2024-02-20 13:02
推荐内容