目录
一、实体类
二、数据库
三、数据交换
四、关于LocalDateTime类型 (java 8)
4.1 旧版本日期时间问题
4.2 新版日期时间API介绍
4.2.1 LocalDate、LocalTime、LocalDateTime
4.2.2 日期时间的修改与比较
4.2.3 格式化和解析操作
4.2.4 Instant: 时间戳
4.2.5 Duration 与 Period——计算时间差
4.2.6 TemporalAdjuster—— 时间校正器
4.2.7 ZonedDateTime 时区讲解
我们这个实体类中的两个时间类型的数据为LocalDateTime
package com.reggie_take_out.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 员工实体类
*/
@Data
@TableName("Employee")
public class Employee implements Serializable {
// 凡是一个类实现了Serializable接口,建议提供一个固定不变的序列化版本号,这样即使代码修改,java虚拟机也认为是同一个类
private static final long serialVersionUID = 1L;
@TableId("id")
private Long id;
@TableField("username")
private String username;
@TableField("name")
private String name;
@TableField("password")
private String password;
@TableField("phone")
private String phone;
@TableField("sex")
private String sex;
@TableField("id_number")
private String idNumber;
@TableField("status")
private Integer status;
@TableField("create_time")
private LocalDateTime createTime;
@TableField("update_time")
private LocalDateTime updateTime;
@TableField(value = "create_user",fill = FieldFill.INSERT)
private Long createUser;
@TableField(value = "update_user",fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
}
LocalDateTime.now() 获取当前时间,格式为: - 月 - 日 - 时 - 分 - 秒
@Override
public R saveEmployee(HttpServletRequest request,Employee employee) {
// 首先判断是否存在这个username
// 1. 设置初始密码进行加密
employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
// 2. 获取当前操作的用户ID
Long empId = (Long) request.getSession().getAttribute("employee");
// employee.setStatus(1); 入库默认1
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
employee.setCreateUser(empId);
employee.setUpdateUser(empId);
employeeMapper.insert(employee);
return R.success("新增员工成功");
}
与日期类进行对比
JavaSE——java.util.Date日期类演示以及常用方法与操作_我爱布朗熊的博客-CSDN博客
在前后端交互的时候,前端往往向后端传输字符串
旧版本中对日期的设计是非常差的
看下面的红框,Date类在java.util 与 java.sql中都有
java.util.Date同时包含日期和时间的,而java.sql.Date仅仅包含日期。
此外用于格式化和解析的类在java,text包下
@Test
void test01() throws ParseException {
// 时间转换成字符串
Date date = new Date(); //Sun Apr 09 14:03:41 CST 2023
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
String dateTime = sdf.format(date);
System.out.println(dateTime); //2023-04-09
// 字符串转换成时间
Date parse = sdf.parse("2021-05-06");
System.out.println(parse); //Thu May 06 00:00:00 CST 2021
}
所有的日期类都是可变的,这是java日期类最大的问题之一
在多线程的情况下,通过格式化对数据做操作的时候,会存在数据安全问题。
时间格式化和解析操作是线程不安全的
日期类并不提供国际化,没有时区支持
此套API设计合理,是线程安全的。新的日期及时间API位于java.time包中,下面是一些关键类。
// 1. 获取指定日期
LocalDate date = LocalDate.of(2021, 05, 06);
System.out.println(date); // 2021-05-06
// 2. 获取当前日期
LocalDate now = LocalDate.now();
System.out.println(now); //2023-04-09
// 3.根据LocalDate对象获取对应信息
System.out.println("年"+now.getYear()); //2023
System.out.println("月"+now.getMonth()); //APRIL 这是一个枚举类型
System.out.println("日"+now.getDayOfMonth()); //9
System.out.println("星期"+now.getDayOfWeek()); //SUNDAY 这是一个枚举
// 枚举
System.out.println("月"+now.getMonth().getValue()); //4 枚举值
System.out.println("星期"+now.getDayOfWeek().getValue()); //7 枚举值
// 1.得到指定时间
LocalTime time = LocalTime.of(5,23,33,123456);
System.out.println(time); //05:23:33.000123456
// 2.获取当前时间
LocalTime now = LocalTime.now();
System.out.println(now); //分钟:45
System.out.println("小时:"+now.getHour()); //小时:14
System.out.println("分钟:"+now.getMinute()); //分钟:45
System.out.println("秒:"+now.getSecond()); //秒:20
System.out.println("纳秒:"+now.getNano()); //纳秒:698000000
// 1.获取指定的日期时间
LocalDateTime time = LocalDateTime.of(2023, 04, 05, 12, 15, 30);
System.out.println(time);
// 2. 获取当前的日期时间
LocalDateTime now = LocalDateTime.now();
System.out.println("年"+now.getYear()); //2023
System.out.println("月"+now.getMonth()); //APRIL 这是一个枚举类型
System.out.println("日"+now.getDayOfMonth()); //9
System.out.println("星期"+now.getDayOfWeek()); //SUNDAY 这是一个枚举
System.out.println("小时:"+now.getHour()); //小时:49
System.out.println("分钟:"+now.getMinute()); //分钟:45
System.out.println("秒:"+now.getSecond()); //秒:49
System.out.println("纳秒:"+now.getNano()); //纳秒:667000000
日期的修改:
LocalDateTime now = LocalDateTime.now();
System.out.println("now=" + now); //2023-04-09T14:57:07.994
// 1. 修改年份
// 注意!!
// 并不会修改原来的信息,而是创建一个新的对象
LocalDateTime localDateTime = now.withYear(1998);
System.out.println(localDateTime); //1998-04-09T14:57:07.994
// 2. 在当前日期的基础上加上/减去指定的时间
System.out.println(now.plusDays(2)); //两天后 2023-04-11T15:03:39.882
System.out.println(now.plusYears(10));//十年后 2033-04-09T15:03:39.882
System.out.println(now.minusMonths(6)); //半年后 2022-10-09T15:05:19.798
System.out.println(now.minusDays(10)); //十天前 2023-03-30T15:05:19.798
日期的比较:
LocalDate now =LocalDate.now();
LocalDate date = LocalDate.of(2020,1,3);
// 时间比较
System.out.println(now.isAfter(date)); //true
System.out.println(now.isBefore(date)); //false
System.out.println(now.isEqual(date)); //false
LocalDateTime now = LocalDateTime.now();
// 指定格式
// 1.默认格式 DateTimeFormatter.ISO_LOCAL_DATE_TIME
DateTimeFormatter isoLocalDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
// 将日期时间转换为字符串
String format = now.format(isoLocalDateTime);
System.out.println(format); //默认格式 2023-04-09T15:30:56.136
// 2.ofPattern指定格式
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format1 = now.format(dateTimeFormatter);
System.out.println(format1); //2023-04-09 15:33:01
// 3.将字符串解析为日期时间类型
LocalDateTime parse = LocalDateTime.parse("1997-05-06 22:45:16", dateTimeFormatter);
System.out.println(parse); //1997-05-06T22:45:16
在jdk8中给我们新增一个Instant类(时间戳/时间线),内部保存了从1970年1月1日0时0分0秒以来的秒和纳秒(可以精确到纳秒)
Instant now = Instant.now();
System.out.println("now= "+now); //2023-04-09T07:40:59.610Z
System.out.println(now.getNano()); //纳秒数据 610000000
计算时,后面的数据减去前面的数据
LocalTime now = LocalTime.now();
LocalTime time = LocalTime.of(22,48);
// 计算时间差
System.out.println(now); //15:50:08.633
Duration duration = Duration.between(now, time);
// 所差的天数
System.out.println(duration.toDays()); //0
// 所差小时
System.out.println(duration.toHours()); //6
// 所差分钟
System.out.println(duration.toMinutes());//417
// 所差毫秒
System.out.println(duration.toMillis()); //25071367
LocalDate now = LocalDate.now();
LocalDate time = LocalDate.of(1997,12,5);
// 计算时间差
System.out.println(now); //2023-04-09
Period period = Period.between(now, time);
// 所差的年数
System.out.println(period.getYears()); //-25
// 所差月份
System.out.println(period.getMonths()); //-4
// 所差天数
System.out.println(period.getDays());//-4
有时候我们可以需要如下调整: 将日期调整到"下个月的第一天"等操作。当然我们也可以通过with进行修改,但是通过时间校正器更好。
通过源码我们发现TemporalAdjuster是一个函数式接口,而且返回值类型和参数列表都是
Temporal类型
LocalDateTime now = LocalDateTime.now();
// TemporalAdjuster 函数式接口
// 将当前日期调整到下个月一号
TemporalAdjuster adjuster =(temporal -> {
// 这个能强制类型转换是因为LocalDateTime实现了Temporal接口
LocalDateTime dateTIme = (LocalDateTime) temporal;
LocalDateTime nextMonth = dateTIme.plusMonths(1) //下一个月
.withDayOfMonth(1);// 1号
System.out.println("nextMonth="+nextMonth); //nextMonth=2023-05-01T16:14:45.898
return nextMonth;
});
LocalDateTime nextMonth = now.with(adjuster);
System.out.println(nextMonth); //2023-05-01T16:14:45.898
还有更简单的!!! 使用TemporalAdjusters工具类
java8中加入了对时区的支持,localDate、LocalTime、LocalTime是不带时区的,带时区的日期时间类分别为:ZonedDate、ZonedTime、ZonedDateTime
其中,每个时区都对应着ID,ID的格式为"区域/城市",例如:Asia/Shanghai等
ZoneId:该类中包含了所有的时区信息
// 1.获取所有时区ID
Set availableZoneIds = ZoneId.getAvailableZoneIds();
for(String zone :availableZoneIds ){
System.out.println(zone);
}
// 2.获取标准时间 ZonedDateTime.now(Clock.systemUTC());
// 因为我们是东八区,比标准时间(本初子午线所在时区)快八个小时
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime); //2023-04-10T00:05:36.146
ZonedDateTime bz = ZonedDateTime.now(Clock.systemUTC());
System.out.println(bz); //2023-04-09T16:05:36.146Z
// 3.使用计算机默认的时区创建日期时间
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now); // 2023-04-10T00:05:36.146+08:00[Asia/Shanghai]
// 4. 使用指定的时期创建日期时间
ZonedDateTime now1 = ZonedDateTime.now(ZoneId.of("America/Marigot"));
System.out.println(now1);//2023-04-09T12:05:36.147-04:00[America/Marigot]
Java中使用的历法是ISO 8601日历系统,它是世界民用历法,也就是我们所说的公历。平年有365天,闺年是366天。此外Java 8还提供了4套其他历法,分别是:
- ThaiBuddhistDate: 泰国佛教历
- MinguoDate: 中华民国历
- JapaneseDate:日本历
- HiirahDate: 伊斯兰历