今天在改一个开源SpringBoot项目,要拿到Android中使用,所以要去除掉SpringBoot相关的东西,看到项目中使用了SpringBoot的@Scheduled(cron = "0 0 * * * ?")来添加定时器,非常简洁,就这么一个注解就实现了整点执行,每一个小时的整点执行,我要改到Android中去用,Android中不知道怎么使用Spring的注解,所以我就不用Spring,改成普通的Java代码实现。

一个整时执行一次,这样等待的时间太长了,所以我先实现一整秒执行一次,方便测试。使用Timer即可轻松实现,如下:

timer.scheduleAtFixedRate(task, firstTime, period);

如果是整点,假如现在是10:23分,则需要在11:00执行定时器,所以关键点在于拿到下一个小时,如果是整秒,则是拿到下一秒,代码如下:

static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");public static Date getNextHour() {Calendar calendar = Calendar.getInstance();System.out.println("当前时间 = " + dateFormat.format(calendar.getTime()));    calendar.set(Calendar.MILLISECOND, 0);   // 清空毫秒calendar.add(Calendar.SECOND, 1);        // 添加一秒Date nextHour = calendar.getTime();System.out.println("开始时间 = " + dateFormat.format(nextHour));return nextHour;
}

运行getNextHour()函数,打印结果如下:

当前时间 = 2022-07-11 16:01:50.294
开始时间 = 2022-07-11 16:01:51.000

OK,成功的获取到了下一个整秒,然后就是使用定时器,从下一整秒开始,每隔一秒执行一次:

public static void main(String[] args) {Timer timer = new Timer();TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println(dateFormat.format(new Date()));}};Date firstTime = getNextHour();             // 设置定时器第1次执行的开始时间long period = TimeUnit.SECONDS.toMillis(1); // 设置每隔1秒执行1次timer.scheduleAtFixedRate(task, firstTime, period);
}

执行效果如下:

当前时间 = 2022-07-11 16:07:15.570
开始时间 = 2022-07-11 16:07:16.000
2022-07-11 16:07:16.010
2022-07-11 16:07:17.011
2022-07-11 16:07:18.010
2022-07-11 16:07:19.010
2022-07-11 16:07:20.005
2022-07-11 16:07:21.005

可以看到定时器并不是百分百准时的,我们设置的是在16:07:16.000执行,但却是在16:07:16.010执行,有10毫秒的偏差,往后是每隔一秒执行一次,也是有毫秒级的偏差的,像航天航空这种高精度要求的,肯定用不了这种定时器,而对于我们的普通应用,这点影响一般是无关紧要的。

另外,在开始解这个问题的时候,开始时间弄错了,导致发现一个定时器的Bug,比如当前时间已经是15秒了,你却设置为12秒的时候执行,慢了3秒,则一运行代码就会立马执行4次run()函数(为什么不是3次?我也不知道,反正慢4秒就执行5次,慢5秒就执行6次,就这个规律),示例如下:

把设置秒的地方设置为负3秒,如下:

calendar.add(Calendar.SECOND, -3);

运行效果如下:

当前时间 = 2022-07-11 16:14:26.325
开始时间 = 2022-07-11 16:14:23.000
2022-07-11 16:14:26.340
2022-07-11 16:14:26.340
2022-07-11 16:14:26.340
2022-07-11 16:14:26.340
2022-07-11 16:14:27.012
2022-07-11 16:14:28.012

所以,定时器的开始时间不能弄错,不能设置的比当前时间早,设置的早了就会出现这样的问题。

实现了整秒的定时器,再实现整点的定时器就很简单了,代码如下:

static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");public static void main(String[] args) {Timer timer = new Timer();TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println(dateFormat.format(new Date()));}};Date firstTime = getNextHour();             // 设置定时器第1次执行的开始时间long period = TimeUnit.HOURS.toMillis(1);    // 设置每隔1小时执行1次      timer.scheduleAtFixedRate(task, firstTime, period);
}/** 获取当前时间的下一个小时的整点时间 */
public static Date getNextHour() {Calendar calendar = Calendar.getInstance();System.out.println("当前时间 = " + dateFormat.format(calendar.getTime()));calendar.set(Calendar.MINUTE, 0);       // 清空分calendar.set(Calendar.SECOND, 0);       // 清空秒calendar.set(Calendar.MILLISECOND, 0);  // 清空毫秒calendar.add(Calendar.HOUR, 1);      // 添加1小时Date nextHour = calendar.getTime();System.out.println("开始时间 = " + dateFormat.format(nextHour));return nextHour;
}

执行效果如下:

当前时间 = 2022-07-11 16:24:56.510
开始时间 = 2022-07-11 17:00:00.000
2022-07-11 17:00:00.013
2022-07-11 18:00:00.006
2022-07-11 19:00:00.009
2022-07-11 20:00:00.011
2022-07-11 21:00:00.001
2022-07-11 22:00:00.005
2022-07-11 23:00:00.009
2022-07-12 00:00:00.014
2022-07-12 01:00:00.018
2022-07-12 02:00:00.004
2022-07-12 03:00:01.233
2022-07-12 04:00:00.000
2022-07-12 05:00:00.010
2022-07-12 06:00:00.002
2022-07-12 07:00:00.005
2022-07-12 08:00:00.004

从结果可以看到,没有24点,只有23点,23:59之后就是00:00,这是新的一天了,所以00:00是新的一天的开始,如果用24:00会让人以为还没到新的一天!在凌晨3点的时候误差有1秒多,后面又自动究正了!

Java整点报时定时器相关推荐

  1. java 定时器(整点报时)

    java 多线程定时器(整点报时) 实现整点报时的详细步骤 第一 构建时间类 1.构建一个时间类 作为锁 和判断 public class Time { public boolean flag; // ...

  2. java定时器整点报时_单片机 整点报时 定时小闹钟程序

    #include #include #include #define uchar unsigned char #define uint unsigned int uchar code segtbl[] ...

  3. java定时器整点报时_整点报时功能

    让计算机在整点自动给你报时是不是感觉不错,那我们搞起来 (其实上一期的espeak命令也可以实现,但是我没能学会) 一.首先,我们下一个叫做"mplayer"的软件 二.然后去一个 ...

  4. Java报时用什么制作_简单实现一个整点报时的软件

    突然又个小需求.电脑整点报时.不想下载网络那些不明的软件,而且这个功能不难.自己实现吧. 首先是播放,wav声音就用华为自带的闹钟声音 Alarm_Beep.wav .  就是以前闹钟的滴滴滴声. # ...

  5. 51单片机 Proteus仿真 时钟 串口 发送时钟 整点报时

    #include "reg52.h" #include <intrins.h> #include <string.h> #include <stdio ...

  6. python报时功能_Python(PyS60)实现简单语音整点报时

    本文实例为大家分享了python语音整点报时的具体代码,供大家参考,具体内容如下 主要的技术特殊点在于PyS60的定时器最多只能定2147秒.在手机上直接写的. import e32 import a ...

  7. c语言时钟程序整点报时,单片机开发的(带整点报时、音乐闹钟)电子时钟(一)...

    整个电路由一台单片机和一些外围电路组成.它的计时采用单片机内部的定时器,其晶振频率为11.0592MHz.其主要功能都是通过C语言编程来实现的.其显示部分用四位数码管来显示,能同时显示小时和分钟.它主 ...

  8. 时钟加闹钟c语言程序,51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)...

    <51单片机c语言电子钟(已加入调时.闹铃.整点报时功能)>由会员分享,可在线阅读,更多相关<51单片机c语言电子钟(已加入调时.闹铃.整点报时功能)(13页珍藏版)>请在技术 ...

  9. 单片机c语言怎样设置闹钟,51单片机c语言电子钟(已加入调时、闹铃、整点报时功能).doc...

    #include#define uchar unsigned char #define uint unsigned int /*七段共阴管显示定义*/ //此表为 LED 的字模, 共阴数码管 0-9 ...

最新文章

  1. linux 源码包编译,源码包编译安装
  2. 卡尔曼滤波 -- 从推导到应用(二)
  3. html元素按压高亮效果
  4. 向iGoogle中添加Google日历及其他小工具
  5. 字符串专题 【2008】四1 C++版
  6. 【CyberSecurityLearning 66】提权
  7. Tomcat(二)环境变量配置
  8. EPOLL使用的简单总结4——epoll+线程池解决c10k问题
  9. Marlin固件运动控制代码分析
  10. 罗永浩当年求职新东方一万多字的求职信
  11. 超宽屏幕比例_Hello!宽时代 21:9超宽屏显示器选购
  12. matlab gui修改图标,Matlab的GUI中左上角修改为自己想要的图标
  13. 如何摆脱CRUD等打杂状态,从事更高价值工作
  14. 网络游戏网络同步方案的选择
  15. 60.ElasticSearch
  16. 2019.06.17
  17. 多卡聚合路由器和企业路由器的区别
  18. oracle 增加tns,Oracle11gr2的tnsnam.ora新增TRANSPORT_CONNECT_TIMEOUT参
  19. 开源的 Flash 项目
  20. 数据推荐 | 手势识别训练数据集

热门文章

  1. ufs 固态硬盘_何必羡慕SSD?UFS3.0闪存让手机比PC还快!
  2. JVM学习笔记之四 四种引用和垃圾回收的两次标记
  3. 狙击精英4服务器文件,狙击精英4联机补丁
  4. 公司注册资本越高越好吗?公司注册资本为什么不能随便填?
  5. 多用途的web电商项目网页模板源码下载
  6. 美国9·11事件永远不能忘记的22张照片(内附高清大图)
  7. Flutter,Android,java现在又来了个国产鸿蒙,字节跳动Android面试
  8. 精心推荐-自动化软件
  9. 调制与解调(一)——模拟调制系统调制解调方法
  10. 【Python异常】 NPM创建Vue项目遇到ERROR command failed: npm install --loglevel error