我的编程空间,编程开发者的网络收藏夹
学习永远不晚

日常编程中和日期相关的代码和bug

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

日常编程中和日期相关的代码和bug

本文主要是Java中和日期时间相隔的几个常用代码函数代码,做了总结,希望在日常编码中,可以帮到大家。

1.计算闰年

记住一个短语,“四年一润,百年不闰,四百再润”,不管换啥语言,相信大家不会写错这块的实现代码。
怎么理解呢?转换为我们程序语言就是“

  • 是4的倍数并且不是100的倍数,那么是普通闰年
  • 是400的倍数,那么是世纪闰年
        public static boolean isLeapYear(int y) {        if (y % 4 == 0 && y % 100 != 0 || y % 200 == 0) {            return true;        } else {            return false;        }    }

2.SimpleDateFormat线程不安全问题

SimpleDateFormat是Java 时间处理上,经常使用到的一个函数,经常用于C-S直接,时间戳处理为当前的格式化的时间。但是大家需要知道,SimpleDateFormat、Date等函数,仅仅是系统的一个功能函数而已,并没有线程同步的功能,所以不可以在多线程环境下,共用一个SimpleDateFormat,不然就会出现相同的时间戳,解析出来的时间不一样的问题。
我们可以看一下SimpleDateFormat的format源码,的确是没有加同步相关的处理逻辑的。

   public abstract StringBuffer format(Date date, StringBuffer toAppendTo,            FieldPosition fieldPosition);        public final String format(Date date)    {        return format(date, new StringBuffer(),                      DontCareFieldPosition.INSTANCE).toString();    }

3.定时器的调用

3.1 CountDownTimer

Java中经常会使用到定时器,经常使用的无疑是CountDownTimer

 CountDownTimer countDownTimer = new CountDownTimer(6000, 1000) {            @Override            public void onTick(long millisUntilFinished) {                //每隔1s回调            }            @Override            public void onFinish() {                //6s倒计时完成回调            }        };

当然了,如果在android中的,可选择的API框架更多了,例如:Handler、Rxjava等等
Handler延迟执行

 new Handler().postDelayed(new Runnable() {            @Override            public void run() {                // 6s后执行的代码            }        }, 6000);

但是这里需要注意,大家如果在android中使用CountDownTimer实现倒计时相关需求时,会存在跳秒的问题。
究其原因,是因为handler postDealy会有消息处理第一次的跳变问题(如果使用handler.postDealyed(……, 1000)方式来进行每秒的计时,是不准确的,是的,有很大误差,误差的原因在于在你收到消息,到你重新发出handler.postDealyed的时间,并不是瞬间完成的,这里面有很多逻辑处理的时间,即使没有逻辑处理的时间,handler本身也是耗损性能的,所以消息并不可能按照理想的1000延迟来进行发送,这就导致了误差的累积,怎么解决?

  • 一方面可以通过自己封装CountDownTimer来规避这个错误
  • 一方面可以借助其他第三方框架来实现,例如Rxjava
package com.itbird.design.builder.dialog;import android.os.Handler;import android.os.Message;import android.os.SystemClock;public abstract class CustomCountDownTimer {    private static final int MSG = 1;        private final long mMillisInFuture;        private final long mCountdownInterval;        private long mStopTimeInFuture;        private long mPauseTimeInFuture;        private boolean isStop = false;    private boolean isPause = false;        public CustomCountDownTimer(long millisInFuture, long countDownInterval) {        // 解决秒数有时会一开始就减去了2秒问题(如10秒总数的,刚开始就8999,然后没有不会显示9秒,直接到8秒)        if (countDownInterval > 1000) {            millisInFuture += 15;        }        mMillisInFuture = millisInFuture;        mCountdownInterval = countDownInterval;    }    private synchronized CustomCountDownTimer start(long millisInFuture) {        isStop = false;        if (millisInFuture <= 0) {            onFinish();            return this;        }        mStopTimeInFuture = SystemClock.elapsedRealtime() + millisInFuture;        mHandler.sendMessage(mHandler.obtainMessage(MSG));        return this;    }        public synchronized final void start() {        start(mMillisInFuture);    }        public synchronized final void stop() {        isStop = true;        mHandler.removeMessages(MSG);    }        public synchronized final void pause() {        if (isStop) return;        isPause = true;        mPauseTimeInFuture = mStopTimeInFuture - SystemClock.elapsedRealtime();        mHandler.removeMessages(MSG);    }        public synchronized final void restart() {        if (isStop || !isPause) return;        isPause = false;        start(mPauseTimeInFuture);    }        public abstract void onTick(long millisUntilFinished);        public abstract void onFinish();    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            synchronized (CustomCountDownTimer.this) {                if (isStop || isPause) {                    return;                }                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();                if (millisLeft <= 0) {                    onFinish();                } else if (millisLeft < mCountdownInterval) {                    // no tick, just delay until done                    sendMessageDelayed(obtainMessage(MSG), millisLeft);                } else {                    long lastTickStart = SystemClock.elapsedRealtime();                    onTick(millisLeft);                    // take into account user's onTick taking time to execute                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();                    // special case: user's onTick took more than interval to                    // complete, skip to next interval                    while (delay < 0) delay += mCountdownInterval;                    sendMessageDelayed(obtainMessage(MSG), delay);                }            }        }    };}

3.2 Rxjava.interval

Rxjava.interval

  //每隔10s,触发一下acceptObservable.interval(10, TimeUnit.SECONDS)        .subscribe(new Consumer<Long>() {            @Override            public void accept(Long aLong) throws Exception {                Log.d(TAG + "interval", String.valueOf(aLong));//从0开始输出            }        });

这个相当于定时器,用它可以取代CountDownTimer。它会按照设定的间隔时间,每次发送一个事件,发送的事件序列:默认从0开始,无限递增的整数序列 。
那么Rxjava.interval的实现原理是什么呢?这块源码其实,我们之前RxJava系列文章讲解过,这里不再赘述,有兴趣的小伙伴,可以移步查阅。
简言之,就是使用了线程池的ScheduledExecutorService ,定时周期执行任务。

在这里插入图片描述

来源地址:https://blog.csdn.net/baobei0921/article/details/129204144

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

日常编程中和日期相关的代码和bug

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

日常编程中和日期相关的代码和bug

本文主要是Java中和日期时间相隔的几个常用代码函数代码,做了总结,希望在日常编码中,可以帮到大家。 1.计算闰年 记住一个短语,“四年一润,百年不闰,四百再润”,不管换啥语言,相信大家不会写错这块的实现代码。 怎么理解呢?转换为我们程序语
2023-08-18

C#开发中如何处理日期和时间相关的问题

C#开发中如何处理日期和时间相关的问题,需要具体代码示例在C#开发中,处理日期和时间是非常常见的任务,无论是计算日期差、日期格式化还是日期的比较,都需要掌握一些常用的日期和时间处理方法。本文将介绍C#中常用的日期和时间处理方法,并提供具体的
2023-10-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录