• 时间轴-新年倒计时(实操java)


    一、前言

    做一个记录时间小功能,距离今年结束还剩多少天,这个月还剩多少天,这周过去了多少时间,今天还可以努力几个小时。当然可以通过前端代码实现,也可以通过java来实现,下面我会把完整代码贴出来,以供参考。还有如何使用LocalDateTime

    二、前端代码实现

    1、效果图

    年月日倒计时

    年月日

    秒杀1天倒计时

    一天倒计时

    秒杀60秒倒计时

    倒计时60秒

    2、代码实操(微信小程序前端)

    ①在utils文件夹下新建js文件:getperiod.js工具类
    class GetPeriod {
      constructor() {
          this.now = new Date();
          this.nowYear = this.now.getYear(); //当前年 
          this.nowMonth = this.now.getMonth(); //当前月 
          this.nowDay = this.now.getDate(); //当前日 
          this.nowDayOfWeek = this.now.getDay(); //今天是本周的第几天 
          this.nowYear += (this.nowYear < 2000) ? 1900 : 0;
      }
      //格式化数字
      formatNumber(n) {
          n = n.toString()
          return n[1] ? n : '0' + n
      }
      //格式化日期
      formatDate(date) {
          let myyear = date.getFullYear();
          let mymonth = date.getMonth() + 1;
          let myweekday = date.getDate();
          return [myyear, mymonth, myweekday].map(this.formatNumber).join('/');
      }
      //获取某月的天数
      getMonthDays(myMonth) {
          let monthStartDate = new Date(this.nowYear, myMonth, 1);
          let monthEndDate = new Date(this.nowYear, myMonth + 1, 1);
          let days = (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24);
          return days;
      }
      //获取本季度的开始月份
      getQuarterStartMonth() {
          let startMonth = 0;
          if (this.nowMonth < 3) {
              startMonth = 0;
          }
          if (2 < this.nowMonth && this.nowMonth < 6) {
              startMonth = 3;
          }
          if (5 < this.nowMonth && this.nowMonth < 9) {
              startMonth = 6;
          }
          if (this.nowMonth > 8) {
              startMonth = 9;
          }
          return startMonth;
      }
      //获取今天的日期
      getNowDate() {
          return this.formatDate(new Date(this.nowYear, this.nowMonth, this.nowDay));
      }
      //获取本周的开始日期
      getWeekStartDate() {
          return this.formatDate(new Date(this.nowYear, this.nowMonth, this.nowDay - this.nowDayOfWeek + 1));
      }
      //获取本周的结束日期
      getWeekEndDate() {
          return this.formatDate(new Date(this.nowYear, this.nowMonth, this.nowDay + (6 - this.nowDayOfWeek + 1)));
      }
      //获取本月的开始日期
      getMonthStartDate() {
          return this.formatDate(new Date(this.nowYear, this.nowMonth, 1));
      }
      //获取本月的结束日期
      getMonthEndDate() {
          return new Date(this.nowYear, this.nowMonth, this.getMonthDays(this.nowMonth));
      }
      //获取本季度的开始日期
      getQuarterStartDate() {
          return this.formatDate(new Date(this.nowYear, this.getQuarterStartMonth(), 1));
      }
      //获取本季度的结束日期 
      getQuarterEndDate() {
          return this.formatDate(new Date(this.nowYear, this.getQuarterStartMonth() + 2, this.getMonthDays(this.getQuarterStartMonth() + 2)));
      }
      //获取本年的开始日期
      getYearStartDate() {
          return this.formatDate(new Date(this.nowYear, 0, 1));
      }
      //获取本年的结束日期
      getYearEndDate() {
          return new Date(this.nowYear, 11, 31);
      }
      //获取时段方法
      getPeriod(obj) {
          let opts = obj || {}, time = null;
          opts = {
              periodType: opts.periodType || 'now',
              spaceType: opts.spaceType || '~'
          }
          function formatNumber(param1, param2) {
              return [param1, param2].join(opts.spaceType);
          }
          if (opts.periodType == 'week') {
              time = formatNumber(this.getWeekStartDate(), this.getWeekEndDate());
          } else if (opts.periodType == 'month') {
              time = formatNumber(this.getMonthStartDate(), this.getMonthEndDate());
          } else if (opts.periodType == 'quarter') {
              time = formatNumber(this.getQuarterStartDate(), this.getQuarterEndDate());
          } else if (opts.periodType == 'year') {
              time = formatNumber(this.getYearStartDate(), this.getYearEndDate());
          } else {
              time = formatNumber(this.getNowDate(), this.getNowDate());
          }
          return time;
      }
    }
    module.exports = GetPeriod;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    ②引入js,在页面index.js开头引入
    const GetPeriod = require("../../utils/getperiod.js");
    
    • 1

    调用方法

    new GetPeriod().方法   //即可
    
    • 1
    ③完整代码

    index.wxml代码

    <view class="container">
      <view class="title">倒计时 </view>
      <view class="title"> </view>
      <view class="top_tip">
        <view class="countdown-title">
          今年还剩:
          <block>
            <text class="">{{yearDays}}</text>
          </block>
        </view>
        <view class="countdown-title">
          这个月还可以努力:
          <block>
            <text class="">{{monthDays}}</text>
            <text>{{ hours }}小时</text>
          </block>
        </view>
        <view class="countdown-title">
          这周已经过去了:
          <block>
            <text class="">{{dayWeek}}</text>
            <text>{{ weekHours }}</text>
            <text>{{ weekMinutes }}</text>
            <text>{{ weekSeconds }}</text>
          </block>
        </view>
    
        <view class="countdown-title">
          今天剩余时间:
          <block>
            <text>{{ hours }}</text>
            <text>{{ minutes }}</text>
            <text>{{ seconds }}</text>
          </block>
        </view>
      </view>
    </view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    index.js代码

    const GetPeriod = require("../../utils/getperiod.js");
    
    
    Page({
      data: {
        days: '00', //天
        hours: '00', //时
        minutes: '00', //分
        seconds: '00', //秒
        weekHours: '00', //当时
        weekMinutes: '00', //当分
        weekSeconds: '00', //当秒
        dayWeek: '', //周几
        monthDays: '00', //天数
        yearDays: '00' //年数
      },
    
    
      countTime() {
        let days, hours, minutes, seconds, weekDays, weekHours, weekMinutes, weekSeconds, monthDays, yearDays;
        let dayWeek = new Date().getDay();
        let that = this;
        let now = new Date().getTime();
        let yearEndDate = new GetPeriod().getYearEndDate().getTime(); //本年结束日期
        let monthEndDate = new GetPeriod().getMonthEndDate().getTime(); //本月结束日期
        let monthnowDate = new Date(new Date().toLocaleDateString()).getTime(); //当天日期
        let end = new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1
        let leftTime = end - now; //时间差
        let weekLeftTime = now - new Date(new Date().toLocaleDateString()).getTime(); //当天时间
        let leftTimes = monthEndDate - monthnowDate; //本月还剩多少天
        let leftTimeYear = yearEndDate - monthnowDate; //本月还剩多少天
    
        if (leftTime >= 0) {
          days = Math.floor(leftTime / 1000 / 60 / 60 / 24);
          monthDays = Math.floor(leftTimes / 1000 / 60 / 60 / 24);
          monthDays = monthDays < 10 ? "0" + monthDays : monthDays;
          yearDays = Math.floor(leftTimeYear / 1000 / 60 / 60 / 24);
          yearDays = yearDays < 10 ? "0" + yearDays : yearDays;
    
    
          hours = Math.floor(leftTime / 1000 / 60 / 60 % 24);
          weekHours = Math.floor(weekLeftTime / 1000 / 60 / 60 % 24);
          minutes = Math.floor(leftTime / 1000 / 60 % 60);
          weekMinutes = Math.floor(weekLeftTime / 1000 / 60 % 60);
          seconds = Math.floor(leftTime / 1000 % 60);
          seconds = seconds < 10 ? "0" + seconds : seconds;
          weekSeconds = Math.floor(weekLeftTime / 1000 % 60);
          weekSeconds = weekSeconds < 10 ? "0" + weekSeconds : weekSeconds;
          minutes = minutes < 10 ? "0" + minutes : minutes;
          weekMinutes = weekMinutes < 10 ? "0" + weekMinutes : weekMinutes;
          hours = hours < 10 ? "0" + hours : hours;
          weekHours = weekHours < 10 ? "0" + weekHours : weekHours;
    
          if (dayWeek > 6 || dayWeek == 1) {
            dayWeek = dayWeek - 1;
          }
          that.setData({
            dayWeek: dayWeek,
            countdown: days + ":" + hours + ":" + minutes + ":" + seconds,
            days,
            hours,
            minutes,
            seconds,
            weekHours,
            weekMinutes,
            weekSeconds,
            monthDays,
            yearDays
          })
          setTimeout(that.countTime, 1000);
        } else {
          that.setData({
            countdown: '已截止'
          })
        }
      },
    
    
      onLoad: function (options) {
        this.countTime();
      },
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    3、倒计时实现

    ①1天倒计时实现-完整代码

    index.wxml代码

    <button bindtap='countdown'>{{clock}}</button>
    
    • 1

    index.js代码

    // 定义一个总毫秒数,以一天为例
    var total_micro_second = 3600 * 1000*24;//这是一天倒计时
    // var total_micro_second = 60 * 1000; //这是60秒倒计时
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        clock: '1天倒计时效果'
      },
      /* 毫秒级秒杀倒计时 */
      countdown: function () {
        var that = this
        console.log('countdown=');
        // 渲染倒计时时钟
        var clock = this.dateformat(total_micro_second) //格式化时间
        console.log('clock=' + clock)
        that.setData({
          clock: clock
        });
    
        if (total_micro_second <= 0) {
          that.setData({
            clock: "秒杀结束"
          });
          // timeout则跳出递归
          return
        }
        // settimeout实现倒计时效果
        setTimeout(function () {
          // 放在最后--
          total_micro_second -= 10
          that.countdown()
        }, 10) //注意毫秒的步长受限于系统的时间频率,于是我们精确到0.01s即10ms
      },
    
    
      // 时间格式化输出,如天时分秒 。每10ms都会调用一次
      dateformat: function (micro_second) {
        // 总秒数
        var second = Math.floor(micro_second / 1000);
        // 天数
        var day = Math.floor(second / 3600 / 24);
        // 总小时
        var hr = Math.floor(second / 3600);
        // 小时位
        var hr2 = hr % 24;
        // 分钟位
        var min = Math.floor((second - hr * 3600) / 60);
        // 秒位
        var sec = (second - hr * 3600 - min * 60); // equal to => var sec = second % 60;
        // 毫秒位,保留2位
        var micro_sec = Math.floor((micro_second % 1000) / 10);
        // return day + "天" + hr2 + "时" + min + "分" + sec + "秒" + micro_sec;
        return hr2 + "时" + min + "分" + sec + "秒" + micro_sec;
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
    
      },
    
    
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    ②60秒倒计时实现-完整代码

    index.wxml代码

    <button bindtap='countdown'>{{second}}</button>
    
    • 1

    index.js代码

    Page({
     
      /**
       * 页面的初始数据
       */
      data: {
        second: '60'
      },
     
      // 小程序实现简单的倒计时效果
      // 基本实现功能:1,从60到0的倒计时效果2,倒计时完毕后会有提示
      countdown: function () {
        var that = this
        var second = this.data.second
        if (second == 0) {
          that.setData({
            second: '倒计时结束'
          })
          return
        }
        var time = setTimeout(function () {
          that.setData({
            second: second - 1
          })
          that.countdown(that)
        }, 1000)
      },
     
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
     
      },
     
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    三、java代码实现

    先简单聊一下

    为什么建议使用LocalDateTime,而不是Date?

    而又是为什么需要 LocalDate、LocalTime、LocalDateTime等 Java8 新提供的类
    Java 8 中,有一部分代替了以往比较难用的 java.util.Date 类,并且创建了一套新的时间类型,该类为:LocalDateTime ,并且提供了许多方法供我们使用,其中,LocalDate、LocalTime、LocalDateTime是新API里的基础对象,绝大多数操作都是围绕这几个对象来进行的。
    LocalDate : 只含年月日的日期对象,对于LocalDate,只有精度大于或等于日的加减,如年、月、日;
    LocalTime :只含时分秒的时间对象,对于LocalTime,只有精度小于或等于时的加减,如时、分、秒、纳秒;
    LocalDateTime : 同时含有年月日时分秒的日期对象,对于LocalDateTime,则可以进行任意精度的时间相加减;
    差异化
    Date 如果不格式化,打印出的日期可读性差

    Sat Dec 03 10:31:35 CST 2022
    
    • 1

    使用 SimpleDateFormat对时间进行格式化,但 SimpleDateFormat是线程不安全的 SimpleDateFormat的 format;例如:

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date=null;
            try {
                 date = sdf.parse(sdf.format(new Date()));
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println(date);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    而方法最终调用代码:

        // Called from Format after creating a FieldDelegate
        private StringBuffer format(Date date, StringBuffer toAppendTo,
                                    FieldDelegate delegate) {
            // Convert input date to time field list
            calendar.setTime(date);
    
            boolean useDateFormatSymbols = useDateFormatSymbols();
    
            for (int i = 0; i < compiledPattern.length; ) {
                int tag = compiledPattern[i] >>> 8;
                int count = compiledPattern[i++] & 0xff;
                if (count == 255) {
                    count = compiledPattern[i++] << 16;
                    count |= compiledPattern[i++];
                }
    
                switch (tag) {
                case TAG_QUOTE_ASCII_CHAR:
                    toAppendTo.append((char)count);
                    break;
    
                case TAG_QUOTE_CHARS:
                    toAppendTo.append(compiledPattern, i, count);
                    i += count;
                    break;
    
                default:
                    subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
                    break;
                }
            }
            return toAppendTo;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    calendar是共享变量,并且这个共享变量没有做线程安全控制。
    当多个线程同时使用相同的 SimpleDateFormat对象【如用 static修饰的 SimpleDateFormat】调用 format
    方法时。多个线程会同时调用 calendar.setTime方法,可能一个线程刚设置好 time值,另外的一个线程马上把设置的 time值给修改了,导致返回的格式化时间可能是错误的。
    在多线程情况下使用 SimpleDateFormat需格外注意 SimpleDateFormat除了 format是线程不安全以外,parse方法也是线程不安全的。
    parse方法实际调用 alb.establish(calendar).getTime()方法来解析,alb.establish (calendar)方法里主要完成了

    • 重置日期对象 cal的属性值
    • 使用 calb中中属性设置 cal
    • 返回设置好的 cal对象

    但是这三步不是原子操作,多线程并发如何保证线程安全,避免线程之间共享一个 SimpleDateFormat
    对象:

    • 每个线程使用时都创建一次 SimpleDateFormat对象 => 创建和销毁对象的开销大
    • 对使用 format和 parse方法的地方进行加锁 => 线程阻塞性能差
    • 使用 ThreadLocal保证每个线程最多只创建一次 SimpleDateFormat对象 => 较好的方法

    Date 对时间处理比较麻烦,比如想获取某年、某月、某星期,以及 n 天以后的时间。
    Date 类的确有 getYear、getMonth这些方法,获取年月日很 Easy,但都被弃用了啊

    使用java8全新的日期和时间API

    LocalDate
    只获取年月日

    • 创建LocalDate
    //获取当前年月日
    LocalDate localDate = LocalDate.now();
    //构造指定的年月日
    LocalDate localDate1 = LocalDate.of(2022, 12, 03);
    
    • 1
    • 2
    • 3
    • 4
    • 获取年、月、日、星期几
    int year = localDate.getYear();
    int year1 = localDate.get(ChronoField.YEAR);
    Month month = localDate.getMonth();
    int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
    int day = localDate.getDayOfMonth();
    int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
    DayOfWeek dayOfWeek = localDate.getDayOfWeek();
    int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    LocalTime
    只获取几点几分几秒

    • 创建LocalTime
     LocalTime localTime = LocalTime.of(14, 50, 10);
     LocalTime localTime1 = LocalTime.now();
    
    • 1
    • 2
    • 获取时分秒
    //获取小时
    int hour = localTime.getHour();
    int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
    //获取分
    int minute = localTime.getMinute();
    int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
    //获取秒
    int second = localTime.getSecond();
    int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    LocalDateTime
    获取年月日时分秒,等于LocalDate+LocalTime

    • 创建LocalDateTime
    LocalDateTime localDateTime = LocalDateTime.now();
    LocalDateTime localDateTime1 = LocalDateTime.of(2022, Month.SEPTEMBER, 10, 14, 50, 10);
    LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
    LocalDateTime localDateTime3 = localDate.atTime(localTime);
    LocalDateTime localDateTime4 = localTime.atDate(localDate);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 获取LocalDate
     LocalDate localDate2 = localDateTime.toLocalDate();
    
    • 1
    • 获取LocalTime
    LocalTime localTime2 = localDateTime.toLocalTime();
    
    • 1

    Instant
    获取秒数

    • 创建Instant对象
    Instant instant = Instant.now();
    
    • 1
    • 获取秒数
    long currentSecond = instant.getEpochSecond();
    
    • 1
    • 获取毫秒数
    long currentMilli = instant.toEpochMilli();
    
    • 1

    如果只是为了获取秒数或者毫秒数,使用System.currentTimeMillis()来得更为方便

    修改LocalDate、LocalTime、LocalDateTime、Instant
    LocalDate、LocalTime、LocalDateTime、Instant为不可变对象,修改这些对象对象会返回一个副本

    • 增加、减少年数、月数、天数等 以LocalDateTime为例
    LocalDateTime localDateTime = LocalDateTime.of(2022, Month.SEPTEMBER, 10,
                  14, 50, 10);
    //增加一年
    localDateTime = localDateTime.plusYears(1);
    localDateTime = localDateTime.plus(1, ChronoUnit.YEARS);
    //减少一个月
    localDateTime = localDateTime.minusMonths(1);
    localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 通过with修改某些值
    //修改年为2020
    localDateTime = localDateTime.withYear(2020);
    //修改为2023
    localDateTime = localDateTime.with(ChronoField.YEAR, 2023);
    
    • 1
    • 2
    • 3
    • 4

    还可以修改月、日
    时间计算
    比如有些时候想知道这个月的最后一天是几号、下个周末是几号,通过提供的时间和日期API可以很快得到答案

    LocalDate localDate = LocalDate.now();
    LocalDate localDate1 = localDate.with(firstDayOfYear());
    
    • 1
    • 2

    比如通过firstDayOfYear()返回了当前日期的第一天日期,还有很多方法这里不在举例说明
    格式化时间

    LocalDate localDate = LocalDate.of(2022, 12, 10);
    String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
    String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
    //自定义格式化
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    String s3 = localDate.format(dateTimeFormatter);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    DateTimeFormatter默认提供了多种格式化方式,如果默认提供的不能满足要求,可以通过DateTimeFormatter的ofPattern方法创建自定义格式化方式
    解析时间

    LocalDate localDate1 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);
    LocalDate localDate2 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE);
    
    • 1
    • 2

    和SimpleDateFormat相比,DateTimeFormatter是线程安全的。
    简单应用
    SpringBoot中应用LocalDateTime

    • 将LocalDateTime字段以时间戳的方式返回给前端
      添加日期转化类
    public class LocalDateTimeConverter extends JsonSerializer<LocalDateTime> {
    
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeNumber(value.toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    并在LocalDateTime字段上添加@JsonSerialize(using = LocalDateTimeConverter.class)注解,如下:

    @JsonSerialize(using = LocalDateTimeConverter.class)
    protected LocalDateTime gmtModified;
    
    • 1
    • 2
    • 将LocalDateTime字段以指定格式化日期的方式返回给前端
      在LocalDateTime字段上添加@JsonFormat(shape=JsonFormat.Shape.STRING, pattern=“yyyy-MM-dd HH:mm:ss”)注解即可,如下:
    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
    protected LocalDateTime gmtModified;
    
    • 1
    • 2
    • 对前端传入的日期进行格式化

    在LocalDateTime字段上添加@DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)注解即可,如下:

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    protected LocalDateTime gmtModified;
    
    • 1
    • 2
    Java Date和LocalDateTime之间相互转换

    Date转化成LocalDateTime
    一种方法

    package insping;
     
    import java.time.Instant;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.util.Date;
     
    public class Test {
     
        public static void main(String[] args) {
            Date date = new Date();
            Instant instant = date.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
     
            LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
            System.out.println("Date = " + date);
            System.out.println("LocalDateTime = " + localDateTime);
     
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    //输入结果
    Date = Sat Dec 03 12:08:56 CST 2022
    LocalDateTime = 2022-12-03T12:08:56.121
    
    • 1
    • 2
    • 3

    另一种方法:使用LocalDateTime的FactoryInput()方法使用系统的默认时区。

    LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), zoneId);
    
    • 1

    LocalDateTime转化成Date
    步骤方法:

    1.使用atZone()方法将LocalDateTime转换为ZonedDateTime 
    2.ZonedDateTime转换为Instant,并从中获取Date
    
    • 1
    • 2
    package insping;
     
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.util.Date;
     
    public class Test {
     
        public static void main(String[] args) {
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDateTime localDateTime = LocalDateTime.now();
            ZonedDateTime zdt = localDateTime.atZone(zoneId);
     
            Date date = Date.from(zdt.toInstant());
     
            System.out.println("LocalDateTime = " + localDateTime);
            System.out.println("Date = " + date);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    //输出结果
    LocalDateTime = 2022-12-03T12:11:09.398
    Date = Sat Dec 03 12:11:09 CST 2022
    
    • 1
    • 2
    • 3
    简单操作

    获取特殊时间

        public static void main(String[] args) {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
            LocalDateTime yearStart = now.with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN);
            LocalDateTime yearEnd = now.with(TemporalAdjusters.lastDayOfYear()).with(LocalTime.MAX);
    
            LocalDateTime monthStart = now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
            LocalDateTime monthEnd = now.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
    
            int dayOfWeek = now.getDayOfWeek().getValue();
            LocalDateTime weekStart = now.minusDays(dayOfWeek - 1).with(LocalTime.MIN);
            LocalDateTime weekEnd = now.plusDays(7 - dayOfWeek).with(LocalTime.MAX);
    
            LocalDateTime dayStart = now.with(LocalTime.MIN);
            LocalDateTime dayEnd = now.with(LocalTime.MAX);
    
            System.out.println("当前年的开始时间:" + yearStart.format(fmt));
            System.out.println("当前年的结束时间:" + yearEnd.format(fmt));
            System.out.println("当前月的开始时间:" + monthStart.format(fmt));
            System.out.println("当前月的结束时间:" + monthEnd.format(fmt));
            System.out.println("当前周的开始时间:" + weekStart.format(fmt));
            System.out.println("当前周的结束时间:" + weekEnd.format(fmt));
            System.out.println("当天的开始时间:" + dayStart.format(fmt));
            System.out.println("当天的结束时间:" + dayEnd.format(fmt));
    
    
            //获取当前几月几号为 -周几
            Integer week = now.getDayOfWeek().getValue();
            System.out.println("获取当前周:" + week);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    比较日期大小

        public static void main(String[] args) {
            String time1 = "2022-06-26 19:00:00";
            DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime localDateTime = LocalDateTime.parse(time1, dtf2);
            System.out.println(localDateTime.isBefore(LocalDateTime.now()));//你的时间在当前时间之前是true
            System.out.println(localDateTime.isAfter(LocalDateTime.now()));//在当前时间之后是false
    
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    计算两个时间的差

    //使用LocalDateTime计算两个时间的差
    Duration duration = Duration.between(now,end);
    long days = duration.toDays(); //相差的天数
    long hours = duration.toHours();//相差的小时数
    long minutes = duration.toMinutes();//相差的分钟数
    long millis = duration.toMillis();//相差毫秒数
    long nanos = duration.toNanos();//相差的纳秒数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1、效果图

    今年还可以努力:28天
    这个月还可以努力:284小时
    这周已经过去了:119小时327秒
    今天还剩余时间:4小时5626
    • 1
    • 2
    • 3
    • 4

    2、代码实操

    java代码,实现动态,只需加个定时任务(1000毫秒调用一次即可)

    package com.hn.yuan.common;
    
    import java.time.*;
    import java.time.format.DateTimeFormatter;
    import java.time.temporal.TemporalAdjusters;
    
    
    public class test2 {
    
        public static void main(String[] args) {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
            LocalDateTime yearStart = now.with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN);
            LocalDateTime yearEnd = now.with(TemporalAdjusters.lastDayOfYear()).with(LocalTime.MAX);
    
            LocalDateTime monthStart = now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
            LocalDateTime monthEnd = now.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
    
            int dayOfWeek = now.getDayOfWeek().getValue();
            LocalDateTime weekStart = now.minusDays(dayOfWeek - 1).with(LocalTime.MIN);
            LocalDateTime weekEnd = now.plusDays(7 - dayOfWeek).with(LocalTime.MAX);
    
            LocalDateTime dayStart = now.with(LocalTime.MIN);
            LocalDateTime dayEnd = now.with(LocalTime.MAX);
    
            System.out.println("当前年的开始时间:" + yearStart.format(fmt));
            System.out.println("当前年的结束时间:" + yearEnd.format(fmt));
            System.out.println("当前月的开始时间:" + monthStart.format(fmt));
            System.out.println("当前月的结束时间:" + monthEnd.format(fmt));
            System.out.println("当前周的开始时间:" + weekStart.format(fmt));
            System.out.println("当前周的结束时间:" + weekEnd.format(fmt));
            System.out.println("当天的开始时间:" + dayStart.format(fmt));
            System.out.println("当天的结束时间:" + dayEnd.format(fmt));
    
    
            Duration duration = Duration.between(now, yearEnd);
            long yearDays = duration.toDays(); //本年倒计时的天数
            Duration duration2 = Duration.between(now, monthEnd);
            long monthDays = duration2.toDays(); //本月倒计时的天数
            Duration duration3 = Duration.between(now, weekEnd);
            long weekDays = duration3.toDays(); //本周倒计时的天数
    
            Duration duration4 = Duration.between(now, dayEnd);
            long dayHours = duration4.toHours();//倒计时的小时数
            long dayMinutes = duration4.toMinutes() % 60;//相差的分钟数
            long dayMillis = duration4.toMillis() % 60;//相差毫秒数
    
            System.out.println("倒计时");
            System.out.println("今年还可以努力:" + yearDays + "天");
            System.out.println("这个月还可以努力:" + monthDays + "天" + dayHours + "小时");
            System.out.println("这周已经过去了:" + weekDays + "天" + now.getHour() + "小时" + now.getMinute() + "分" + now.getSecond() + "秒");
            System.out.println("今天还剩余时间:" + dayHours + "小时" + dayMinutes + "分" + dayMillis + "秒");
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    定时任务参考

    /**
     *  Timer也可以指定具体时间执行
     *  String time = "2022-12-02 12:00:00"; 
     *  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     *  Date delay = sdf.parse(time);//执行时间
     *  timer.scheduleAtFixedRate(执行任务, delay, 周期);
     */
    public void Ds01()  {
        // 需要定时执行的任务
        TimerTask task = new TimerTask() {
            public void run() {
                System.out.println("-----定时测试-----");
            }
        };
        // Timer定时器工具
        Timer timer = new Timer();
        // 延迟(首次执行的时间)
        long delay = 0;
        // 间隔周期(/毫秒数)
        long intevalPeriod = 5 * 1000;
        // 立即执行,并且每5秒执行一次
        timer.scheduleAtFixedRate(task, delay, intevalPeriod);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    各位看官》创作不易,点个赞!!!
    诸君共勉:万事开头难,只愿肯放弃。

    免责声明:本文章仅用于学习参考

  • 相关阅读:
    ROS机器人编程---------(二)ROS中的核心概念
    7. Spring Boot Profile(多环境配置)
    23款奔驰GLC260L升级小柏林音响 全新15个扬声器
    Spring之更便捷的读取和存储对象
    【JavaEE初阶】网络原理|认识协议|协议分层|TCP/IP模型|封装和分用
    【java开发技术积累篇】之springboot项目优美的文件上传方式
    竞赛选题 基于情感分析的网络舆情热点分析系统
    Java中如何执行多条shell/bat命令 2023年验证通过
    Pytorch构建Transformer实现英文翻译
    封阳台窗户怎么选
  • 原文地址:https://blog.csdn.net/SoulNone/article/details/128165485