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类型的时间转成LocalDateTime:2021-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