java中的时间类型

GMT+08:00:GMT(Greenwich Mean Time)是格林尼治标准时间,+08:00 指标准时间加8小时,也就是北京时间。

时间类型

Java 8中表示日期和时间的类有多个,主要的有:

  • Instant:表示时刻,不直接对应年月日信息,需要通过时区转换
  • LocalDateTime: 表示与时区无关的日期和时间信息,不直接对应时刻,需要通过时区转换
  • LocalDate:表示与时区无关的日期,与LocalDateTime相比,只有日期信息,没有时间信息
  • LocalTime:表示与时区无关的时间,与LocalDateTime相比,只有时间信息,没有日期信息
  • ZonedDateTime: 表示特定时区的日期和时间
  • ZoneId/ZoneOffset:表示时区

LocalDateTime与字符串互转

简单粗暴

  DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	LocalDateTime time = LocalDateTime.now();
	String localTime = df.format(time);
	LocalDateTime ldt = LocalDateTime.parse(localTime,df);
	System.out.println("LocalDateTime转成String类型的时间:"+localTime);
	System.out.println("String类型的时间转成LocalDateTime:"+ldt);
===============
运行结果
LocalDateTime转成String类型的时间:2021-11-22 10:30:43
String类型的时间转成LocalDateTime2021-11-22T10:30:43

LocalDateTime 与Date互转

  • ZoneId/ZoneOffset:表示时区
  • ZonedDateTime: 表示特定时区的日期和时间
  • Instant:表示时刻,不直接对应年月日信息,需要通过时区转换
//DATE---->LOCALDATETIME
Date date = new Date();
Instant instant = date.toInstant();
System.out.println(instant);
ZoneId zone = ZoneId.systemDefault();
System.out.println(zone);
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
System.out.println(localDateTime);
===============
运行结果
2021-11-22T02:35:42.900Z
Asia/Shanghai
2021-11-22T10:35:42.900
LocalDateTime localDateTime = LocalDateTime.now();
ZoneId zone = ZoneId.systemDefault();
Instant instant = localDateTime.atZone(zone).toInstant();
Date date = Date.from(instant);
===============
运行结果
Mon Nov 22 10:38:52 CST 2021

LocalDateTime 与 LocalDate互转

LocalDateTime 转 LocalDate

直接调用 toLocalDate() 方法

LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = localDateTime.toLocalDate();

LocalDate 转 LocalDateTime

一般调用 atTime() 方法进行赋值

LocalDate localDate = LocalDate.now();
LocalDateTime localDateTime1 = localDate.atStartOfDay();
LocalDateTime localDateTime2 = localDate.atTime(8,20,33);
LocalDateTime localDateTime3 = localDate.atTime(LocalTime.now());

LocalDate与Date互转

Date date = new Date();
ZoneId zoneId = ZoneId.systemDefault();
LocalDate localDate = date.toInstant().atZone(zoneId).toLocalDate();

LocalDate 转 Date

先调用 atStartOfDay() 方法转 LocalDateTime 再转 Date

LocalDate localDate = LocalDate.now();
ZoneId zone = ZoneId.systemDefault();
Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
Date date = Date.from(instant);
System.out.println(date);
===============
运行结果
Mon Nov 22 00:00:00 CST 2021

时间比较

LocalDateTime now = LocalDateTime.now();
Long epochMilli = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

然后比较long就可以了,默认时区是ZoneId.systemDefault()

//北京时区
ZoneId bjZone = ZoneId.of("GMT+08:00")

间隔计算

使用Duration进行 day,hour,minute,second等的计算

使用Period进行Year,Month的计算,不能计算天

public static void main(String[] args) {
      LocalDateTime localDateTime = LocalDateTime.now();
      LocalDateTime localDateTime4 = localDateTime.plusDays(100);
      Duration duration = Duration.between(localDateTime,localDateTime4);
      long l = duration.toDays();
      long l1 = duration.toHours();
      long l2 = duration.toMinutes();
      System.out.println(l);
      System.out.println(l1);
      System.out.println(l2);
  //LocalDate
      Period period2 = Period.between(localDateTime.toLocalDate(),localDateTime4.toLocalDate());
      int years = period2.getYears();
      int months = period2.getMonths();
      int days = period2.getDays();
      long l3 = period2.toTotalMonths();
      System.out.println(years);
      System.out.println(months);
      System.out.println(days);
      System.out.println(l3);
}
===============
运行结果
100
2400
144000
0
3
8//不能计算天
3s

ChronoUnit定义了用于测量时间的单位。当你想要在一个单位的时间内测量一段时间,比如几天或几秒时, ChronoUnit.between 可以做到。between 方法与所有基于时间的对象一起工作,但是它只返回单个单元的数量。 下面的代码以毫秒为间隔计算两个时间戳之间的差距:

Instant current = Instant.now();
// 10秒前
Instant previous = current.minus(10, ChronoUnit.SECONDS);
if (previous != null) {
    // MILLIS,计算两个时间之前间隔多少毫秒
    long between = ChronoUnit.MILLIS.between(previous, current);
    System.out.println(between); // 10000
}

而 Duration 类则可以转换为更多的时间单位;

LocalDate today = LocalDate.now();
// 1960.06.01
LocalDate birthday = LocalDate.of(1992, Month.OCTOBER, 5);

Period p = Period.between(birthday, today);
long p2 = ChronoUnit.DAYS.between(birthday, today);
// 生活了58年,4个月,8天,总共21313天
System.out.println("You are " + p.getYears() + " years, " + p.getMonths() +
" months, and " + p.getDays() +
                   //8天不准,用Duration来计算
" days old. (" + p2 + " days total)");
===============
运行结果
You are 29 years, 1 months, and 17 days old. (10640 days total)

判断是否是今天或昨天

String time = "2021-11-22 11:20:45";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
System.out.println(dtf);
LocalDateTime localTime = LocalDateTime.parse(time, dtf);
System.out.println(localTime);
LocalDateTime startTime = LocalDate.now().atTime(0, 0, 0);
System.out.println(startTime);
LocalDateTime endTime = LocalDate.now().atTime(23, 59, 59);
System.out.println(endTime);
LocalDateTime startYesterday = LocalDate.now().plusDays(-1).atTime(0, 0, 0);
System.out.println(startYesterday);
LocalDateTime endYesterday = LocalDate.now().plusDays(-1).atTime(23, 59, 59);
System.out.println(endYesterday);


//如果小于昨天的开始日期
if (localTime.isBefore(startYesterday)) {
    System.out.println("时间是过去");
}
//时间是昨天
if (localTime.isAfter(startYesterday) && localTime.isBefore(endYesterday)) {
    System.out.println("时间是昨天");
}
//如果大于今天的开始日期,小于今天的结束日期
if (localTime.isAfter(startTime) && localTime.isBefore(endTime)) {
    System.out.println("时间是今天");
}
//如果大于今天的结束日期
if (localTime.isAfter(endTime)) {
    System.out.println("时间是未来");
}




// 自定义开始时间
 LocalDateTime startTime = LocalDateTime.of(2021, 10, 22, 10, 10, 10);
// 自定义结束时间
 LocalDateTime endTime = LocalDateTime.of(2021, 10, 22, 11, 11, 11);

前后端LocalDateTime日期格式转换问题

场景:

后台通过实体接收参数,使用POST,前端通过Json的形式进行交互。

前端传 “2020-10-18 11:20:23” 这种格式的时间时,后端无法接收,报解析异常。

解决:
@JsonFormat
后端的 LocalDataTime 只能解析类似【 2020-01-01T10:00:00】 这样的格式。

只要在后端的实体类,相应的属性上加如下注解,即可解决。

@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”)
缺点:每个用到的属性都要加,略麻烦

亦可采用其他格式接收,使用再转LocalDataTime的方式来避免。

LocalDateTime转为yyyy-MM-dd HH:mm:ss

LocalDateTime转为yyyy-MM-dd HH:mm:ss
LocalDateTime time1 = LocalDateTime.now();
String = time1.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
  
  // yyyyMM格式转为yyyy-MM格式
		String date = "201402";
        Date parse = null;
        String dateString = "";
        try {
            parse = new SimpleDateFormat("yyyyMM").parse(date);
            dateString = new SimpleDateFormat("yyyy-MM").format(parse);
        } catch (Exception e) {
            dateString=null;
            log.error("日期格式转换出错,{}",date);
        }
        System.out.println(dateString); // 2014-02
// yyyyMMdd格式转为yyyy-MM-dd格式
		String date = "20140204";
        Date parse = null;
        String dateString = "";
        try {
            parse = new SimpleDateFormat("yyyyMMdd").parse(date);
            dateString = new SimpleDateFormat("yyyy-MM-dd").format(parse);
        } catch (Exception e) {
            dateString=null;
            log.error("日期格式转换出错,{}",date);
        }
        System.out.println(dateString); // 2014-02-04

计算

Date日期增加一天

Calendar

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = sdf.parse("2020-11-11");
Date endDate = null;
try {
    Calendar c = Calendar.getInstance();// 日历
    c.setTime(startDate);// 设置时间
    c.add(Calendar.DATE, 1);// 增加一天
    endDate = c.getTime();// 获取日期
}catch (Exception e){
    //log.error("转换日期格式出错",e);
}
System.out.println(sdf.format(startDate)); // 输出2020-11-11
System.out.println(sdf.format(endDate)); // 输出2020-11-12

调整时间

LocalDateTime now = LocalDateTime.now();
//明天
LocalDateTime plusDays = now.plusDays(1);
//昨天
LocalDateTime plusDays2 = now.plusDays(-1);
//还有时分等同理
System.out.println(plusDays);
System.out.println(plusDays2);

time = time.plusMinutes(5);//获取当前时间并加5分钟
time = time.minusMinutes(5);//获取当前时间并减去5分钟

time = time.plusHours(5);//获取当前时间并加5小时
time = time.minusHours(5);//获取当前时间并减去5小时

===============
运行结果
2021-11-23T10:48:54.389
2021-11-21T10:48:54.389
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值