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

news2024/11/15 14:36:54

文章目录

    • 一、前言
    • 二、前端代码实现
      • 1、效果图
        • 年月日倒计时
        • 秒杀1天倒计时
        • 秒杀60秒倒计时
      • 2、代码实操(微信小程序前端)
        • ①在utils文件夹下新建js文件:getperiod.js工具类
        • ②引入js,在页面index.js开头引入
        • ③完整代码
      • 3、倒计时实现
        • ①1天倒计时实现-完整代码
        • ②60秒倒计时实现-完整代码
    • 三、java代码实现
      • 先简单聊一下
        • 为什么建议使用LocalDateTime,而不是Date?
        • 使用java8全新的日期和时间API
        • Java Date和LocalDateTime之间相互转换
        • 简单操作
      • 1、效果图
      • 2、代码实操

一、前言

做一个记录时间小功能,距离今年结束还剩多少天,这个月还剩多少天,这周过去了多少时间,今天还可以努力几个小时。当然可以通过前端代码实现,也可以通过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;

②引入js,在页面index.js开头引入

const GetPeriod = require("../../utils/getperiod.js");

调用方法

new GetPeriod().方法   //即可

③完整代码

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>

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();
  },
});

3、倒计时实现

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

index.wxml代码

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

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) {

  },


})

②60秒倒计时实现-完整代码

index.wxml代码

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

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) {
 
  },
 
})

三、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

使用 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);

而方法最终调用代码:

    // 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;
    }

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);
  • 获取年、月、日、星期几
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);

LocalTime
只获取几点几分几秒

  • 创建LocalTime
 LocalTime localTime = LocalTime.of(14, 50, 10);
 LocalTime localTime1 = LocalTime.now();
  • 获取时分秒
//获取小时
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);

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);
  • 获取LocalDate
 LocalDate localDate2 = localDateTime.toLocalDate();
  • 获取LocalTime
LocalTime localTime2 = localDateTime.toLocalTime();

Instant
获取秒数

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

如果只是为了获取秒数或者毫秒数,使用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);  
  • 通过with修改某些值
//修改年为2020
localDateTime = localDateTime.withYear(2020);
//修改为2023
localDateTime = localDateTime.with(ChronoField.YEAR, 2023);

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

LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.with(firstDayOfYear());

比如通过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);

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

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

和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());
    }
}

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

@JsonSerialize(using = LocalDateTimeConverter.class)
protected LocalDateTime gmtModified;
  • 将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;
  • 对前端传入的日期进行格式化

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

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
protected LocalDateTime gmtModified;

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);
 
    }
}
//输入结果
Date = Sat Dec 03 12:08:56 CST 2022
LocalDateTime = 2022-12-03T12:08:56.121

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

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

LocalDateTime转化成Date
步骤方法:

1.使用atZone()方法将LocalDateTime转换为ZonedDateTime 
2.ZonedDateTime转换为Instant,并从中获取Date
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);
    }
}
//输出结果
LocalDateTime = 2022-12-03T12:11:09.398
Date = Sat Dec 03 12:11:09 CST 2022

简单操作

获取特殊时间

    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);
    }

比较日期大小

    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

    }

计算两个时间的差

//使用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、效果图

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

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 + "秒");
    }


}

定时任务参考

/**
 *  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);
}

在这里插入图片描述

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/61260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习python第一天(数据类型)

关于Python的数据类型 Python数据类型包括&#xff1a; 数字类型&#xff0c;字符类型&#xff0c;布尔类型&#xff0c;空类型&#xff0c;列表类型&#xff0c;元组类型&#xff0c;字典类型 1、数字类型 包括&#xff1a;整型int 浮点型float(有小数位的都是是浮点型) 注…

自己写Spring组件-01手写Bean注册器

简介 在进行web开发的时候&#xff0c;我们经常使用Component、Services、Controller等注解去声明Bean&#xff0c;然后Spring就会帮我们注册。 如果我们想要自己写一个组件&#xff08;方便后期使用&#xff09;&#xff0c;进行无感引入的时候&#xff0c;就需要自己去注册B…

【计算机网络】计算机网络复习总结 ----- 链路层

计算机网络 内容管理数据链路层 Data Link Layer相关概念术语link 链路data link 数据链路帧 frameMTU maximum transfer Unit 最大传送单元PPP point to point Protcol 点对点协议MAC 地址 media access control网桥 bridge交换机 switch成帧 规则成帧定界字符计数法字符填充分…

QT:文件介绍

UI&#xff1a;QT程序中使用的ui界面就保存在该文件中 组件 设置当前组件的属性 点谁显示谁的属性 调整最终页面的布局&#xff0c;使组件控件在水平或对齐 调整因页面放大缩小时&#xff0c;控件与控件之间的水平和垂直间距 各种各样的按钮 图像显示有关的视图 列表框 各…

Gradle学习笔记之Groovy简单使用

简介 groovy可以当成java的脚本化改良版&#xff0c;同样运行于JVM之上&#xff0c;可以很好地和java代码及相关库进行交互&#xff0c;既可以面向对象编程&#xff0c;也可以用作纯粹的脚本语言。Groovy支持动态类型转换、闭包、元编程、函数式编程、默认作用域为public&…

ArcGIS基础:使用线段分割面数据操作

本操作主要是实现线要素对面要素的分割。 先看一下原始数据&#xff0c;如下所示&#xff0c;2个面&#xff0c;1条线&#xff0c;面被线贯穿过去。 首先进行【面转线】操作&#xff0c;以提取面要素的边界线&#xff0c;如下所示 提取结果如下所示&#xff1a; 然后进行【…

java认证与证书

本文内容主要来自《Java加密与解密的艺术》 目前主要有JKS和PEM两种编码格式文件。 JKS&#xff08;Java Key Store&#xff09;&#xff0c;Java原生的密钥库/信任库文件。**PEM&#xff08;Privacy Enbanced Mail&#xff0c;隐私增强邮件&#xff09;**是使用多种加密方法提…

2022-12-04一周学习

这周基本上还是在对前端学习的更多一点&#xff0c;主要是之前没有重视vue3的学习,现在在补上来&#xff0c;学习了vue3的一些知识&#xff0c;前端的权限管理&#xff0c;设置路由守卫&#xff0c;pinia&#xff0c;还学习了redis的一些基本操作&#xff0c;之前只是照搬了别人…

Linux的线程创建

对于任何一个进程来讲&#xff0c;即便我们没有主动去创建线程&#xff0c;进程也是默认有一个主线程的。线程是负责执行二进制指令的&#xff0c;它会根据项目执行计划书&#xff0c;一行一行执行下去。进程要比线程管的宽多了&#xff0c;除了执行指令之外&#xff0c;内存、…

二、演练领域驱动的设计过程

一、业务分析&#xff1a;统一语言与事件风暴 1、统一语言&#xff1a; 客户明白自己的领域知识也就是业务&#xff0c;以及自己需要解决的问题&#xff0c;也叫做痛点&#xff0c;但是不知道技术。技术人员知道技术&#xff0c;但是不了解客户的业务。所以两者交流起来往往会…

[附源码]计算机毕业设计物品捎带系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

finereport公式帮助

1 if(inarray($$$,ds1.select(销售员))<$TOPN,$$$,"其他")&#xff0c;将第 N 个销售员之后的所有销售员合并为其他&#xff0c; 2 "["((roundup($$$/$num)-1)*$num1)"~"(roundup($$$/$num)*$num)"]" 3 SQL语句用if语句&#xff0c…

HTML网页设计作业:文化网站设计——基于HTML古典中国风工艺美术网页设计(9页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

SpringBoot @InitBinder注解绑定请求参数

参考资料 springMVC之InitBinder 和 ValidatorspringMVC之InitBinder的用法1springMVC之InitBinder的用法2 目录一. 作用二. 前期准备三. Get请求 URL传值处理3.1 前台-test16.html3.2 Controller层3.3 效果四. Post请求 表单传值 自定义日期属性绑定器4.1 前台-test16.htm…

华为机试 - 任务最优调度

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 给定一个正整数数组表示待系统执行的任务列表&#xff0c;数组的每一个元素代表一个任务&#xff0c;元素的值表示该任务的类型。 请计算执行完所有任务所需的最短时间。 任务执行规则如下: 任务可…

Springboot RabbitMq源码解析之RabbitListener注解 (四)

文章目录1.RabbitListener注解介绍2.EnableRabbit和RabbitBootstrapConfiguration3.RabbitListenerAnnotationBeanPostProcessor4.对RabbitListener注解的解析5.RabbitListenerEndpointRegistrar1.RabbitListener注解介绍 RabbitListener是Springboot RabbitMq中经常用到的一个…

D-023 DVI硬件电路设计

DVI硬件电路设计1 简介1.1 连接器1.2 接口信号定义1.3 DVI的分类1.4 DVI规格2 硬件设计实战3 硬件设计要点3.1 注意事项3.2 补充说明3.3 VGA 和 DVI 优缺点1 简介 DVI(Digital Visual Interface)是一种数字视频接口&#xff0c;它是基于TMDS (Transition Minimized Differenti…

MFC列表控件的用法(基于对话框的编程)

目录 一、List Control列表控件属性 1.List Control 2.View属性 二、OnInitDialog初始化列表 1.创建List Control的变量 2.找OnInitDialog ​3. InsertColumn插入表头 4. InsertColumn设置对齐方式和列宽 5. 设置List的正文内容 ​6.循环结构创建列表 7.设置列表整行…

Windows内核--子系统(3.5)

到底什么是子系统? 子系统是用户层概念。在Windows内核之上&#xff0c;如果想要执行类UNIX应用程序&#xff0c;就是POSIX子系统&#xff0c;如果要类似OS/2环境&#xff0c;就是OS/2子系统。 如何能模拟出不同子系统呢? 一般需要子系统用户态应用程序和相关DLL支援。 对于W…

腾讯云服务器mysql安装

1.选择mysql版本 2.安装mysql源 sudo wget https://repo.mysql.com//mysql80-community-release-el7-1.noarch.rpm 3.下载mysql.rpm源 wget https://repo.mysql.com//mysql80-community-release-el7-1.noarch.rpm 4.安装下载好的rpm包 sudo rpm -ivh mysql80-community-rele…