时间轴-新年倒计时(实操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;
②引入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);
}

在这里插入图片描述

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

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

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中可以使用JavaFX库来实现时间轴动画。JavaFX中的时间轴动画是通过一个时间轴对象(Timeline)来实现的,时间轴对象会在一段时间内以指定的速度重复执行一个动画。 以下是一个简单的例子,实现了一个小球从左边移动到右边的动画: ```java import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.stage.Stage; import javafx.util.Duration; public class TimeLineAnimationExample extends Application { @Override public void start(Stage primaryStage) throws Exception { Group root = new Group(); Scene scene = new Scene(root, 500, 500, Color.WHITE); Circle ball = new Circle(20, Color.RED); ball.relocate(0, 250); root.getChildren().add(ball); Timeline timeline = new Timeline( new KeyFrame(Duration.ZERO, e -> { ball.setTranslateX(ball.getTranslateX() + 5); }), new KeyFrame(Duration.seconds(2)) ); timeline.setCycleCount(Animation.INDEFINITE); timeline.play(); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } ``` 在这个例子中,我们创建了一个小球,并将其添加到场景中。然后创建了一个时间轴对象,并设置了两个关键帧(KeyFrame),第一个关键帧表示每隔一段时间更新小球的位置,第二个关键帧表示动画的持续时间。最后设置了时间轴对象的重复次数和播放动画。 你可以根据需要调整关键帧的时间和小球的移动距离来实现不同的动画效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值